Young's Mind
01 Research

Medusa v2 as our hosted commerce + POS product (2026-10-13)

Companion to medusa-nextjs-commerce-study (stack choice: Medusa won, MIT end-to-end). Young's brief added the product shape: two features — sell services online + POS — delivered as e-commerce website hosting with POS functions, multi-hosting environments on Docker. This note covers the deployment/tenancy half, verified against the live docs (.md agent endpoints, fetched 2026-10-13).

Medusa v2 as our hosted commerce + POS product (2026-10-13)

Companion to medusa-nextjs-commerce-study (stack choice: Medusa won, MIT end-to-end). Young's brief added the product shape: two features — sell services online + POS — delivered as e-commerce website hosting with POS functions, multi-hosting environments on Docker. This note covers the deployment/tenancy half, verified against the live docs (.md agent endpoints, fetched 2026-10-13).

Summary

  • Medusa's official Docker path is a 4-service compose stack (Postgres 15 + Redis 7 + medusa backend + Next.js storefront) built on the dtc-starter pnpm monorepo — one Dockerfile serves backend and storefront. Verified publishable topology; MIT licence means we can repackage it as our hosting template without restriction.
  • Production is not the dev compose: docs mandate a server + worker split (MEDUSA_WORKER_MODE=server|worker, admin disabled on the worker) against shared Postgres + Redis, plus production infrastructure modules (Redis event-bus/caching/locking/workflow-engine, S3 file, SendGrid notification). ≥2GB RAM per host recommended.
  • Tenancy for a hosting product: per-tenant stack (compose project per client: own DB, own Redis, own containers) is the clean fit — blast-radius isolation, per-tenant secrets, per-tenant Admin, straightforward backup/restore. Shared cluster multi-tenancy (medusa start --cluster / --servers --workers, v2.11+) is for scaling one tenant bigger, not for isolating many tenants.

Verified deployment facts

  • Base image: node:20-alpine; Medusa requires Node ≥ 20.19.0. Backend ports 9000 (API/Admin), 5173 (admin HMR dev); storefront 8000.
  • Dev compose (docker-install doc): postgres:15-alpine, redis:7-alpine, medusa (build .), storefront (build . + start-storefront.sh entrypoint). pnpm-workspace gotcha documented: anonymous volumes over node_modules dirs are required or bind-mounts clobber installed deps. Names/ports/volumes must be re-suffixed per project — the docs' own multi-project guidance maps 1:1 onto per-tenant stacks.
  • Production build: medusa build outputs to .medusa/server; start command per docs: cd .medusa/server && npm install && npm run predeploy && npm run start, where predeploy = medusa db:migrate (runs migrations + syncs links on every update — the tenant-update pipeline hook).
  • Env parity server/worker: shared DATABASE_URL, REDIS_URL, COOKIE_SECRET, JWT_SECRET (docs require generated secrets in production), STORE_CORS/ADMIN_CORS/AUTH_CORS; DISABLE_MEDUSA_ADMIN=false on server, true on worker.
  • Cluster mode (v2.11+): npx medusa start --cluster 4 --servers 25% --workers 75% — splits processes across cores of ONE tenant's host.
  • Health/lifecycle: <APP_URL>/health → OK; Admin at <APP_URL>/app; admin user seeded via npx medusa user -e … -p ….
  • Storefront deployment is separate (any Node host); docs warn Vercel's free plan is personal/non-commercial only — for our hosting product the storefront ships in our own Docker env anyway.
  • Services-selling: native in the data model — products/variants without stock + price lists; bookings/subscriptions layered as a custom module (the framework layer is exactly for this). POS: fork Agilo POS (MIT, Admin REST over HTTPS); its roadmap gaps remain: no payments integration yet (manual payment plugin path exists), no offline mode.

Proposed hosting product (our Docker offer)

Per-tenant stack, one template, fleet-managed:

LayerPer tenantShared (our infra)
Postgres 15own container + volumebackup cron → offsite
Redis 7own container—
Medusa serverown container, WORKER_MODE=serverreverse proxy + TLS (nginx, per-tenant domain)
Medusa workerown container, WORKER_MODE=worker, admin off—
Storefront (Next.js)own container or static exportsame proxy
Agilo POS (client's tablets)SaaS-style client to their own backend—
  • Onboarding = one script: generate compose project + secrets (openssl rand), set domain in proxy, predeploy, create admin user, health-check /health. Mirrors our probe-pattern: no stack is "live" until /health returns OK and the admin loads.
  • Updates: git-tagged tenant template; update = pull new tag → predeploy (auto-migrate) → container restart → health re-check. Checkout-before-cutover: keep old volumes; rollback = prior tag.
  • Sizing: docs floor 2GB RAM/tenant (server+worker+storefront+PG+Redis comfortably in 4GB); small tenants can bin-pack 2–4 compose stacks per VPS node, isolated at compose-project level. Start conservative: 1 tenant per 4GB until measured.
  • Multi-env: staging + production per client = two compose projects, same image tag, separate DBs/Redis — cheap to offer and matches the docs' "multiple testing environments" pitch (which Medusa Cloud sells — our version is the self-hosted equivalent).

Capacity on prod Oracle ARM (measured 2026-10-13, Young confirmed specs)

Node: Oracle Ampere A1, aarch64 (Neoverse-N1) × 4 OCPUs, 23Gi RAM, 200GB disk (180G free) — verified live via lscpu/free/df. Current residents: OS (1.4Gi baseline) + solos-docs + pulse-site.

  • All official Medusa base images (node:20-alpine, postgres:15-alpine, redis:7-alpine) are multi-arch — the whole stack runs unmodified on ARM64.
  • Conservative capacity (read + measured, using docs floor + breathing room):
    • ~4 full tenant stacks (4.8 GB steady each: server 2 + worker 1 + storefront 1 + PG 0.7 + Redis 0.1), or
    • ~6 small tuned stacks (3 GB each: server 1.2 + worker 0.6 + storefront 0.7 + PG 0.4 + Redis 0.1).
  • CPU: 4 vCPU shared with the two Nuxt sites — thin tenants (~0.3–0.5 vCPU steady) fine; count builds, not just runtime: medusa build/Next.js builds spike hard, so image builds happen once per template release, shared image for all tenants — rebuilding per-tenant would saturate the 4 vCPUs trivially.
  • Disk: 180G free ≫ shared image layers (~2G) + per-tenant PG/Redis volumes (small); backup/storage budget, not RAM, is the ceiling long-term on this node.
  • Scaling path: node 1 = pilot (2–3 tenants max, colocated with solos-docs/pulse) → dedicated node 2 for tenants when pilot stabilises (same ARM profile, more RAM). Per-tenant stacks make node-to-node evacuation = compose project move.

Implications / next steps

  1. Build the tenant template repo (Ace lane): dtc-starter fork + prod-optimised multi-stage Dockerfile (docs' Dockerfile is dev-oriented: bind-mounts, dev server) + docker-compose.prod.yml (server/worker split) + onboarding script + /health-gated cutover script.
  2. Per-tenant secrets register follows fleet hygiene: 0600, never in compose files.
  3. Services catalogue module (custom module) is the differentiator for "sell services online"; scope it after first tenant ships with physical/simple goods.
  4. POS pilot caveat: Agilo POS works today for cart/draft-order flow on client tablets; payments-in-POS is the known gap — in-store payments can start via the manual-payment path while the payment-terminal roadmap lands.
  5. Medusa Cloud is the competitor bench-mark, not a dependency: their pitch (push-to-deploy, preview envs, storefront hosting) is our feature list for the self-hosted product.

Sources

  • docs.medusajs.com learn/installation/docker (.md agent endpoint) — full compose/Dockerfile/start scripts, multi-project port/volume suffixing guidance.
  • learn/deployment + learn/deployment/general — server/worker split, production modules, env matrix, predeploy, health check, admin Bootstrap.
  • learn/production/worker-mode — workerMode config, admin-disable pattern, cluster mode --servers/--workers (v2.11+).
  • GitHub API + READMEs (2026-10-13): medusajs/medusa v2.21.2 MIT; medusajs/dtc-starter MIT, active; Agilo/medusa-pos-starter MIT, FAQ payment/offline gaps.
  • Prior study medusa-nextjs-commerce-study for stack comparison + licence matrix.
Copyright © 2026