Railway

Deploy Medusa v2 (Worker Mode)

Medusa v2 with a dedicated background-job worker, search and storefront.

Deploy Medusa v2 (Worker Mode)

Just deployed

/data

Just deployed

/var/lib/postgresql/data

Just deployed

/meili_data

Bucket

Bucket

Just deployed

Deploy and Host Medusa on Railway

Medusa is an open-source commerce platform: a headless Node.js backend with a full Admin dashboard, plus a Next.js storefront. This template runs it the way Medusa documents for production — API traffic and background jobs split into two independently scalable services instead of one process doing both.

About Hosting Medusa

Deploying provisions seven services: a Medusa Backend in server mode, a Worker in worker mode, Postgres, Redis, Meilisearch, a Next.js Storefront, and a read-only media proxy in front of a Railway Storage Bucket. Backend and Worker build the same repository, so the first deploy takes roughly 10–15 minutes. On a cold project the Backend runs migrations and seeds demo catalog data on first boot, while the Worker restarts a few times until that schema exists — this is expected and self-healing, not a failure. Only Backend, Storefront, Meilisearch, and the media proxy get public domains; the Worker deliberately has none.

Common Use Cases

  • Running a production storefront where checkout, emails, and webhooks must not compete with API request handling for CPU
  • Catalogs large enough that Meilisearch indexing and scheduled jobs need their own compute budget
  • A customizable Shopify alternative you fully own, with the Admin, Store API, and storefront on one platform

Dependencies for Medusa Hosting

  • No external accounts are required. Postgres, Redis, Meilisearch, and object storage are all provisioned by the template.
  • Change MEDUSA_ADMIN_EMAIL on the Backend before deploying — it becomes your Admin login. The matching password is generated for you; read it from the Backend service's MEDUSA_ADMIN_PASSWORD variable after deploy.
  • Optional: STRIPE_API_KEY + STRIPE_WEBHOOK_SECRET for card payments, and RESEND_API_KEY + RESEND_FROM_EMAIL (or the SendGrid pair) for transactional email. Each feature turns on only when its full pair is set.

Deployment Dependencies

Implementation Details

Worker mode. The two Medusa services run identical code and differ only in two variables:

BackendWorker
MEDUSA_WORKER_MODEserverworker
MEDUSA_DISABLE_ADMINfalsetrue
Public domainyesno
Healthcheck/healthnone

They share the same Postgres and Redis, which is how jobs are handed over — Medusa's Redis event bus and workflow engine are the queue. Scheduled jobs and subscribers execute only on the Worker.

First boot ordering. Railway has no equivalent of compose's condition: service_completed_successfully. The Backend owns migrations and seeding; the upstream launcher already skips seeding when MEDUSA_WORKER_MODE=worker, so the two never race to migrate. The Worker is given restartPolicyType: ALWAYS and no healthcheck, so it retries harmlessly until the schema is in place rather than failing the deploy.

Ports are pinned. PORT is set explicitly on Backend (9000), Storefront (3000), Meilisearch (7700), and the media proxy (8080). Railway's healthcheck probes the canonical PORT, so leaving it implicit is the most common cause of a deploy that serves traffic fine but never goes healthy.

Media proxy. Railway Storage Buckets have no public URL, but product images must be browser-readable. A small Bun function serves objects read-only — GET/HEAD only, everything else gets 405 — and the bucket credentials never leave the private network. S3_FILE_URL points at this proxy's domain.

Meilisearch traffic is split. The Backend indexes over the private network (http://${{MeiliSearch.RAILWAY_PRIVATE_DOMAIN}}:7700); only the Storefront uses the public origin, because browsers query the index directly.

Scaling the Worker. The upstream config does not enable @medusajs/locking-redis, so distributed locks are per-instance. That is safe here because scheduled jobs run on a single Worker — but add the Redis locking module before scaling the Worker past one replica, or two replicas can run the same scheduled job concurrently. The Backend scales horizontally without this caveat.

If Admin login fails. The upstream first-boot check treats "the user table exists" as "already seeded". If a first boot is interrupted after migrations but before the admin user is created (for example by editing a variable mid-deploy), seeding is skipped forever and no admin exists. Recreate it from the Backend service shell:

railway ssh --service Backend -- sh -lc \
  "cd /app/.medusa/server && npx medusa user -e you@example.com -p 'your-password'"

Why Deploy Medusa on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying Medusa on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.


Template Content

More templates in this category

View Template
Rocky Linux
[Jul'26] Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀

codestorm
37
View Template
Foundry Virtual Tabletop
A Self-Hosted & Modern Roleplaying Platform

Lucas
71
View Template
Letta Code Remote
Run a Letta Code agent 24/7. No inbound ports, just deploy.

Letta
51