Medusa is an open-source headless commerce platform — a Node.js/TypeScript backend that exposes admin and store APIs, paired with a separate frontend storefront you control. Medusa v2 restructured the project, so this guide targets v2 and the realistic production topology: a backend service, a worker, a managed Postgres, a managed Redis, and a Next.js storefront.
The pieces and how they relate
| Service | What it is | Public? |
|---|---|---|
| Medusa backend (server mode) | Admin + Store REST APIs, admin dashboard | yes |
| Medusa worker (worker mode) | Background jobs, scheduled tasks, subscribers | no |
| PostgreSQL | Orders, products, customers | no |
| Redis | Event bus, workflow engine, cache | no |
| Storefront (Next.js) | Customer-facing shop, calls the Store API | yes |
Medusa v2 runs the same backend codebase in two runtime modes: server (handles HTTP) and worker (handles background work). In production you run both so a slow background job never blocks API requests.
Backend configuration
Medusa is configured in medusa-config.ts and via environment variables. The essentials:
DATABASE_URL=postgres://...
REDIS_URL=redis://...
JWT_SECRET=long-random-secret
COOKIE_SECRET=long-random-secret
STORE_CORS=https://shop.yourdomain.com
ADMIN_CORS=https://admin.yourdomain.com
AUTH_CORS=https://shop.yourdomain.com,https://admin.yourdomain.comThe CORS variables trip people up constantly: if STORE_CORS doesn't include your storefront's origin, the shop can't call the API and you'll see opaque browser CORS errors. Set them to your real domains.
On PandaStack, attach a managed PostgreSQL and managed Redis to the backend; the injected DATABASE_URL is used directly, and you supply REDIS_URL from the attached Redis. Run migrations as a release step before serving traffic:
npx medusa db:migrateRunning server and worker modes
Deploy the same backend image twice with different mode settings:
# server service
MEDUSA_WORKER_MODE=server
# worker service (no public port needed)
MEDUSA_WORKER_MODE=workerBoth point at the same Postgres and Redis. The Redis-backed event bus is what lets the server enqueue work that the worker consumes — without Redis, Medusa falls back to an in-memory bus that doesn't span processes, so the worker would never see events. Redis is effectively required for this split.
The admin dashboard
Medusa v2 serves its admin dashboard from the backend itself at /app. There's no separate admin deployment in the default setup — once the backend is live, the admin is at https://admin.yourdomain.com/app. Make sure ADMIN_CORS and the backend URL config are correct so the dashboard's API calls resolve.
The storefront
The storefront is a separate Next.js app (Medusa provides a starter). It talks to the backend's Store API using a publishable API key. Configure it with:
NEXT_PUBLIC_MEDUSA_BACKEND_URL=https://api.yourdomain.com
NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=pk_...You can deploy the storefront as its own container service (for SSR) or, if you export a static build, as a static site. Most production storefronts use SSR/ISR for fresh inventory and pricing, so a container service is the typical choice. Create the publishable key in the Medusa admin first, then inject it into the storefront.
Putting it together: deploy order
- 1Provision managed PostgreSQL + managed Redis.
- 2Deploy the backend (server mode); run
medusa db:migrate; create an admin user. - 3Deploy the worker (worker mode) sharing the same DB/Redis.
- 4In admin, create a publishable API key + sales channel.
- 5Deploy the storefront pointing at the backend with that key.
- 6Set CORS and custom domains; SSL is automatic.
Production notes
- File storage: configure an S3 module for product images; local disk is ephemeral.
- Secrets:
JWT_SECRETandCOOKIE_SECRETmust be stable and shared across server and worker. - Scaling: scale server replicas for traffic, worker replicas for background throughput, independently.
References
- [Medusa deployment overview](https://docs.medusajs.com/learn/deployment)
- [Medusa worker mode](https://docs.medusajs.com/learn/production/worker-mode)
- [Medusa configuration](https://docs.medusajs.com/learn/configurations/medusa-config)
- [Medusa Next.js storefront](https://docs.medusajs.com/resources/nextjs-starter)
A full Medusa stack — backend, worker, storefront — fits PandaStack's model: deploy each as a service, attach managed Postgres and Redis once, and let custom domains get automatic SSL. Start your store on the free tier at [dashboard.pandastack.io](https://dashboard.pandastack.io).