---
title: "Deploy MedusaJS 2 Full Stack Production Ready"
description: "Server + worker, Next.js storefront, search, persistent media, no setup"
category: "Starters"
url: https://railway.com/deploy/medusajs-2-full-stack-production-ready
---

# Deploy MedusaJS 2 Full Stack Production Ready

Server + worker, Next.js storefront, search, persistent media, no setup

**[Deploy MedusaJS 2 Full Stack Production Ready on Railway](https://railway.com/template/medusajs-2-full-stack-production-ready)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/medusajs-2-full-stack-production-ready/manifest.json

- **Creator:** Aceweb
- **Category:** Starters

## Template content

### storefront https://user-images.githubusercontent.com/59018053/229103275-b5e482bb-4601-46e6-8142-244f531cebdb.svg

- **Source:** https://github.com/acewebs/medusa-js-railway
- **Health check:** /
- **Public domain:** Yes

### postgres https://devicons.railway.app/i/postgresql.svg

- **Image:** ghcr.io/railwayapp-templates/postgres-ssl:18

### medusa-backend https://user-images.githubusercontent.com/59018053/229103275-b5e482bb-4601-46e6-8142-244f531cebdb.svg

- **Source:** https://github.com/acewebs/medusa-js-railway
- **Health check:** /health
- **Public domain:** Yes

### media-proxy https://user-images.githubusercontent.com/59018053/229103275-b5e482bb-4601-46e6-8142-244f531cebdb.svg

- **Source:** https://github.com/acewebs/medusa-js-railway
- **Health check:** /_health
- **Public domain:** Yes

### medusa-worker https://user-images.githubusercontent.com/59018053/229103275-b5e482bb-4601-46e6-8142-244f531cebdb.svg

- **Source:** https://github.com/acewebs/medusa-js-railway

### redis https://devicons.railway.app/redis

- **Image:** redis:8.2
- **Start command:** `/bin/sh -c "rm -rf $RAILWAY_VOLUME_MOUNT_PATH/lost+found/ && exec docker-entrypoint.sh redis-server --requirepass $REDIS_PASSWORD --save 60 1 --dir $RAILWAY_VOLUME_MOUNT_PATH"`

## Buckets

- **bucket**

## Documentation

# Deploy and Host MedusaJS 2 Full Stack Production Ready on Railway

MedusaJS 2 Full Stack Production Ready is a complete commerce stack deployed the way Medusa's own guide specifies: the API with its admin dashboard, a separate worker for background jobs, a Next.js storefront, PostgreSQL, Redis, and persistent object storage behind a read-only proxy. Seven resources, wired to each other, with nothing to fill in on the deploy form.

## About Hosting MedusaJS 2 Full Stack Production Ready

Medusa's deployment guide asks for two instances of the application, one serving the API in server mode and one running jobs and subscribers in worker mode, with Redis behind the event bus, workflow engine, locking and cache. Most one-click Medusa templates run a single process and skip some of those modules, which works until a long workflow starts competing with checkout requests. This template deploys the documented topology instead. Migrations, the first admin account, regions, a sales channel, the storefront's publishable key and a demo catalogue are all created on the first deploy, so what finishes building is a working store rather than an empty one waiting to be configured.

## Common Use Cases

- **A production store on your own infrastructure**, with no per-sale fee and no platform lock-in
- **A commerce backend for a storefront you are building yourself**, on Railway or anywhere else
- **A B2B or marketplace build** that starts from a correct deployment instead of a single-process demo
- **Migrating off a hosted platform** onto a stack you can read, change and move

## Dependencies for MedusaJS 2 Full Stack Production Ready Hosting

- **PostgreSQL**, provisioned automatically, connected over Railway's private network rather than the TCP proxy
- **Redis**, provisioned automatically, backing the event bus, workflow engine, locking and cache
- **Railway Storage Bucket**, provisioned automatically, for uploads that survive every redeploy

All three are created and wired with Railway variable references, and every secret is generated at deploy time. Stripe and SendGrid are optional: set a key and the provider is configured, leave it unset and it is absent rather than half configured.

### Deployment Dependencies

- [Source repository](https://github.com/acewebs/medusa-js-railway)
- [Medusa documentation](https://docs.medusajs.com)
- [Medusa's production deployment guide](https://docs.medusajs.com/learn/deployment)

### Implementation Details

#### The server owns migrations, the worker waits for it

```sh
wait_for "$DATABASE_URL"
wait_for "$REDIS_URL"
medusa db:migrate            # server only
medusa exec ./src/scripts/bootstrap.js
wait_for "$MEDUSA_WAIT_FOR"  # worker only
exec medusa start
```

Both Medusa services run the same image and differ only in `MEDUSA_WORKER_MODE`. The API instance's port opens only after migrations and bootstrap succeed, which makes a reachable port the schema's readiness signal for the worker, so the worker never races a database that is still being migrated. A failed migration exits before anything serves traffic: the healthcheck never passes and Railway keeps the previous version live.

Setup lives in the container entrypoint rather than a deploy-time hook, because a published Railway template does not carry pre-deploy commands and anything put there would never run on the deploy that needs it. Bootstrap is idempotent, so a boot interrupted halfway through is repaired by the next one instead of leaving a store with no admin account.

#### A publishable key the storefront can be built with

Next.js inlines its publishable API key into the browser bundle while the image is built, and Railway builds every service in parallel, before the backend has run once. A key the backend generated would therefore never reach the storefront. Here the key is one value both services share, and bootstrap writes it onto the publishable key in the database.

#### Persistent media without a public bucket

Railway Storage Buckets are private and have no public URL, and a presigned URL expires while the URL Medusa stores on a product image has to keep working. A small read-only proxy serves objects from the bucket with cache headers. It can only read: it cannot list, write or delete, so the bucket credentials never leave the server side.

#### Search without another service

Search is Medusa's own index on PostgreSQL. There is no separate search service to pay for, scale or keep in sync.

#### Verified end to end, not just started

```bash
MEDUSA_URL=https://… STOREFRONT_URL=https://… node scripts/smoke-test.mjs
```

The repository ships the smoke test used to check it: admin login, a file upload read back through the proxy, product search, then a real order placed through the store API. 17 checks, because a deploy where every service reads "Online" can still fail most of them.

#### Three things to do before you go live

`MEDUSA_ADMIN_PASSWORD` is generated for you and used only on the first boot. Changing it afterwards does not reset the account, and recovering a lost one needs either `SENDGRID_API_KEY` configured for the admin's own reset email or a manual change in the database. Copy it out of the variables before the store is in use.

`S3_FILE_URL` is written onto every product image as it is uploaded. Changing it later does not rewrite rows that already exist, so if you plan to serve media from a custom domain or a CDN, set that address before building the catalogue.

`SEED_DEMO_DATA` is true by default so the storefront has something to render. Set it to false for an empty store. Deleting the demo products later works too, and they do not come back on redeploy.

#### If you do not need the storefront

A second listing, MedusaJS 2 Production Ready, deploys the backend half only: server, worker, PostgreSQL and Redis, with no storefront, media proxy or bucket. Same repository and same entrypoint, for anyone pointing their own front end at the API.

## Why Deploy MedusaJS 2 Full Stack Production Ready on Railway?

Medusa wants long-lived processes, a database, Redis and object storage in one place, which is exactly what Railway provisions in a single project on a single bill.

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 MedusaJS 2 Full Stack Production Ready 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.

## Similar templates

- [Openfront Gym](https://railway.com/deploy/openfront-gym) — Opensource Mindbody alternative based on Next.js and Keystone.js
- [open-excalidraw](https://railway.com/deploy/open-excalidraw) — Self-hostable collaborative drawing built on Excalidraw
- [Next.js + Prisma + PostgreSQL Starter](https://railway.com/deploy/nextjs-prisma-postgres) — Deploy a Next.js app with Prisma ORM and PostgreSQL in one click.

Open this page in a browser: https://railway.com/deploy/medusajs-2-full-stack-production-ready
