Skip to content

EmbeddedEra production store (live since 2026-10-30)

The production WooCommerce store, compose project embeddedera-store-prod, on 127.0.0.1:8510, public at store.embeddedera.com since 2026-10-30 (owner ran release): live Stripe card payments (express checkouts off), Stripe Tax live, Cricket product 25 purchasable with backorders on; the store key needs Accounts Read (without it cart pages took 25-30 s); LiPo cells EE-C-0184 $5.95 and EE-C-0197 $6.95 listed "Coming soon", not purchasable (owner ran launch-cricket.sh batteries 2026-11-01); shipping USPS Ground Advantage 7.95 + 1.00 * ([qty] - 1) since 2026-11-01. Source: projects/store-production-launch-plan Log 2026-10-30. Text below about dark/not-public is the 2026-10-06 history. Not the sandbox: that is embeddedera-store-sandbox (project embeddedera-store, port 8500, untouched). Plan and phase status: projects/store-production-launch-plan.

Why this shape

A separate project, volumes, secrets and mu-plugin set so a sandbox command or sandbox value can never reach production. Tier is explicit: EE_STORE_TIER=production plus WP_ENVIRONMENT_TYPE=production; the mu-plugins fail closed (503) if they disagree.

Shape

  • Deployed from a pinned worktree ~/embeddedera-store-prod/src (detached at a commit of branch production; development worktree ~/embeddedera-store-prod/work). Run compose only through scripts/prod/pcompose (supplies the env file, refuses the dev checkout).
  • Services: stripe-proxy (Squid, exact hosts api.stripe.com + challenges.cloudflare.com, the only egress with mail-relay), db (MariaDB 11.4, 384 MiB), redis (96 MiB), wordpress (512 MiB), ingress (Caddy, 64 MiB, 127.0.0.1:8510, sends X-Robots-Tag: noindex until go-live), scheduler (profile workers, 256 MiB, WP-Cron every 60 s), wpcli (profile tools, bootstrap), mail-relay (profile mail, postfix boky/postfix pinned digest, defined and NOT started or credentialed). Images pinned by digest in dependencies.lock.json.
  • Volumes embeddedera-store-prod_wp_data and embeddedera-store-prod_db_data. Secrets: ~/.config/embeddedera-store-prod/env (0700 dir, 0600 file, never in git): DB passwords, salts, the one admin adiaz (password only there until the owner moves it to Vaultwarden). Live Stripe keys will live in ~/.config/stripe/live-store.env and reach WordPress only through scripts/prod/stripe-live-gateway on stdin.
  • mu-plugins mounted: shared ee-store-tier, catalog-navigation, customer-order-status, store-performance, quantity-pricing-preview; production-only production-guards (HTTP allowlist, mail blocked until option ee_store_mail_enabled=yes, no file mods/auto-updates, XML-RPC off, only Stripe gateways, max-per-order meta) and stripe-live-guard (live keys only; gateway cannot enable without valid pk_live, rk/sk_live and whsec). No sandbox mu-plugin is mounted.
  • Seeded by scripts/prod/bootstrap-prod.sh: USD, 1001 Ridge Dr Clayton NC 27520, guest checkout, zone Contiguous US (48 states + DC) with flat USPS Ground Advantage $8.95 taxable, Stripe gateway present but disabled, Stripe Tax installed not keyed, empty Woo tax table, blog_public=0, production policy pages, one product: Cricket EE-A-0003-A as a hidden draft ($24.99, 2+ $22.49, max 4, stock 0, release pending). Cart Abandonment Recovery is deliberately not installed.
  • Backup set store in erp-backup (see schedules): DB dump + uploads, age-encrypted, /mnt/storage/EmbeddedEra/backups/store/<stamp>/ 30 days, R2 store/<stamp>/. Restore drill: erp-backup store-verify (also run by erp-backup verify) into a throwaway --network none MariaDB.
  • Health: user timer ee-store-prod-health.timer every 5 min runs scripts/prod/health-check.sh (origin 200, scheduler healthy, no failed scheduled actions, newest store dump < 26 h); failure pages through the job-failure hook. Also public checks via https://store.embeddedera.com (home 200, /wp-login.php 302 to Access, ?wc-api=wc_stripe not 5xx and not Access). Cloudflare cache rules 2 (bypass) and 3 (30-day static assets) include the store host; Rule 1 (HTML) does not, so HTML is DYNAMIC.

  • Order notifications (verified 2026-11-01): WooCommerce new_order, cancelled_order, and failed_order are enabled with explicit recipient orders@embeddedera.com (two-member Google Group). From is also orders@, independently of the recipient. Previously unset recipient settings defaulted to admin adiaz@, so order #37 bypassed the group. No historical email was resent.

Connected to

  • owns: the two named volumes, the env file, the store backup set, the health timer.
  • owned-by: repo ~/embeddedera-store, branch production (no remote yet).
  • joins: embeddedera-store-sandbox only by sharing images and source; torrentvpn-stack not at all.
  • looks-like-but-is-not: the sandbox stack (different project, port, secrets, guards).

If you change this

  • Hits: deploy/prod/ in the repo, then re-pin ~/embeddedera-store-prod/src (git checkout --detach production) and pcompose up -d; store backup and health check read the container names embeddedera-store-prod-{db,wordpress,scheduler}-1; jobs-index catalogue.
  • Does not hit: the sandbox stack, the production ERP (read-only for the store project until plan P7), DNS/Cloudflare (not configured).
  • Gotcha (2026-11-01): pcompose run wpcli <anything> ignores the command and runs the full bootstrap-prod.sh (entrypoint), which resets home/siteurl to 127.0.0.1:8510 and blog_public 0 on the live store. Never use it for reads.

Surfaces

Surface Role
scripts/prod/pcompose, bootstrap-prod.sh, stripe-live-gateway operate
erp-backup store / store-verify backup, restore drill
ee-store-prod-health.timer monitor

See

  • Source: /home/angel/embeddedera-store-prod/src/deploy/prod/ (README there); plan projects/store-production-launch-plan