Blog/Deploy Medusa JS to Railway

Deploy Medusa JS to Railway: A Complete Step-by-Step Guide

[Published On May 18, 2025]

Medusa Js deployment guide
Share

When it comes to deploying your Medusa backend, you’ve got plenty of options. The main requirement is that your hosting provider supports Node.js, since that’s what Medusa runs on. For this example, we’ll be using Railway, but the same general steps apply if you’re deploying to platforms like DigitalOcean, AWS, Heroku, or others.

What You’ll Need to Deploy

Once you're ready to take your Medusa project live, there are a few key pieces you'll need to deploy:

  • PostgreSQL Database
  • Redis Database
  • Medusa Application (in Server and Worker mode)
Medusa JS deployment infrastructure

Medusa Admin and Application Configurations

You’ll need to deploy two instances of your Medusa application: one in server mode, and the other in worker mode.

  • The "Server" instance is responsible for handling all incoming requests like API calls from your storefront, admin dashboard, or any integrations.
  • The "Worker" instance runs in the background, managing tasks like scheduled jobs, event subscribers, and other long-running processes.

To get your Medusa app ready for deployment, update your medusa config (medusa-config.ts) file to support both server mode and worker mode, and to optionally disable the admin dashboard.

Here’s what you're going to add:

1module.exports = defineConfig({ 2 projectConfig: { 3 // other config options... 4 workerMode: process.env.MEDUSA_WORKER_MODE as "shared" | "worker" | "server", 5 }, 6 admin: { 7 disable: process.env.DISABLE_MEDUSA_ADMIN === "true", 8 backendUrl: process.env.MEDUSA_BACKEND_URL, 9 }, 10}) 11

You’ll set different values for MEDUSA_WORKER_MODE and DISABLE_MEDUSA_ADMIN based on which Medusa instance you’re deploying. MEDUSA_BACKEND_URL defines the backend URL your admin dashboard will connect to. We’ll generate this when we deploy to Railway.

Add the variables (MEDUSA_WORKER_MODE, DISABLE_MEDUSA_ADMIN, & MEDUSA_BACKEND_URL) to your .env file so you can easily copy and paste the values when setting up each instance.

Configure Redis URL

We’ll use the REDIS_URL environment variable to connect Medusa to Redis. We’ll set up Redis on Railway a bit later.

In your medusa-config.ts file, add the following line inside projectConfig:

1module.exports = defineConfig({ 2 projectConfig: { 3 // other config options... 4 redisUrl : process.env.REDIS_URL 5 }, 6}) 7

Then, in your .env file, add a placeholder for the Redis connection string REDIS_URL=

We’ll come back and fill this in once Redis is deployed.

Add a Predeploy Script

To make sure your Medusa app always runs migrations and syncs links before deployment, add the following predeploy script to your package.json:

1{ 2 // ...other configurations 3 "scripts": { 4 // ...other scripts 5 "predeploy": "medusa db:migrate" 6 } 7}

Configure Production Modules and Providers

For production environments, it’s highly recommended to use the Redis-based modules for caching, the event bus, and the workflow engine, rather than relying on the default in-memory versions.

In a production environment, you’ll also want to set up the S3 File Module Provider for file storage. But to keep things simple, we’ll leave it as-is for this tutorial.

Add the following Redis modules to your medusa-config.ts file:

1module.exports = defineConfig({ 2 // other configurations.... 3 modules: [ 4 { 5 resolve: "@medusajs/medusa/cache-redis", 6 options: { 7 redisUrl: process.env.REDIS_URL, 8 }, 9 }, 10 { 11 resolve: "@medusajs/medusa/event-bus-redis", 12 options: { 13 redisUrl: process.env.REDIS_URL, 14 }, 15 }, 16 { 17 resolve: "@medusajs/medusa/workflow-engine-redis", 18 options: { 19 redis: { 20 url: process.env.REDIS_URL, 21 }, 22 }, 23 }, 24 ], 25});

Create a GitHub Repository

Create a GitHub repository for your Medusa application — this will make things much easier when we deploy to Railway. Plus, it will also allow you to automatically deploy when changes are made to your repo. New to Github? Follow this guide.

Create a Railway Account

If you’ve made it this far, nice work! You’re now ready to deploy your Medusa app to Railway.

Go to https://railway.com/new, and create an account if you haven’t already. Make sure to connect your GitHub to your Railway account.

Create a new Railway project for your Medusa application.

Deploy PostgreSQL and Redis on Railway

In your Railway dashboard, click the “Create” button and deploy both services:

  • Search for "PostgreSQL" and deploy it to set up your Medusa DB
  • Search for "Redis" and deploy it as well

Make sure both are added to the same project — this allows you to use Railway's template syntax and dynamic environment variables for easy service connections.

Deploy Medusa Application in Server Mode

In your Railway project, click “Create” and select the GitHub Repo option. Choose the repository you just created for your Medusa app. Name this service “Server”, this helps keep things clear when you deploy the "Worker" instance later on.

Make sure you’re deploying this to the same Railway project where your Redis and PostgreSQL services are running — this allows you to use dynamic environment variables to connect the services.

Head back to your local Medusa project, open your .env file, and copy the relevant environment variables.

In your "Server" instance, go to the "Variables" tab and use the "Raw Editor" to paste them. Before updating, make the following additions:

1DISABLE_MEDUSA_ADMIN="false" 2MEDUSA_WORKER_MODE="server" 3PORT="9000" 4MEDUSA_BACKEND_URL=https://<your-generated-url> 5DATABASE_URL="${{ Postgres.DATABASE_PUBLIC_URL }}" 6REDIS_URL="${{ Redis.REDIS_PUBLIC_URL }}"

In your "Server" instance, go to the Settings tab, and under "Networking", click the "Generate Domain" button for your Medusa backend URL. Add this url as MEDUSA_BACKEND_URL in your variables.

1DISABLE_MEDUSA_ADMIN="false" 2MEDUSA_WORKER_MODE="server" 3PORT="9000" 4MEDUSA_BACKEND_URL=https://<your-generated-url> 5DATABASE_URL="${{ Postgres.DATABASE_PUBLIC_URL }}" 6REDIS_URL="${{ Redis.REDIS_PUBLIC_URL }}"

Also in the "Settings" tab, add the following configuration for "Custom Start Command":

cd .medusa/server && npm install && npm run predeploy && npm run start

Deploy Medusa Application in Worker Mode

Repeat the steps in "Deploy Medusa Application in Server Mode", with a couple key differences.

In your "Worker" instance on Railway, go to the Settings tab, scroll down to the "Custom Start Command" field, and add:

cd .medusa/server && npm install && npm run start

Go back to your local Medusa application, open the .env file, and copy the relevant environment variables.

Then, in your "Worker" instance, go to the "Variables" tab, click on "Raw Editor", and paste the variables. Before updating, make the following adjustments:

1DISABLE_MEDUSA_ADMIN="true" 2MEDUSA_WORKER_MODE="worker" 3PORT="9000" 4MEDUSA_BACKEND_URL=https://<your-generated-url> 5DATABASE_URL="${{ Postgres.DATABASE_PUBLIC_URL }}" 6REDIS_URL="${{ Redis.REDIS_PUBLIC_URL }}"

Connect to Railway CLI from Terminal

Once your deployment is live, you can connect to your project using the Railway CLI. It lets you run scripts, execute migrations, and manage your Medusa app directly from your terminal.

First, install the Railway CLI tool. In my case, I’ll use Homebrew to do this. (CLI installation instructions: https://docs.railway.com/guides/cli)

1brew install railway

After installing the CLI, log in to Railway:

1railway login

Once you're logged in, link your local Medusa project to your Railway project:

1railway link

When prompted to choose a project during linking, select the server instance.

To create an admin user, run the following command from your project’s root directory.

1railway run npx medusa user -e admin-medusa@test.com -p supersecret

Be sure to replace admin-medusa@test.com and supersecret with the email and password you'd like to use for your admin account.

If you’d like to seed your project with auto-generated store, products, inventory, and more, run the following command.

1railway run npx medusa exec ./src/scripts/seed.ts

Medusa js deployment services

Need help getting live?

Work 1-on-1 with a deployment expert and launch with confidence.

Mon, May 26, 2025, 08:57 PM

© 2025 306 Technologies Ltd. All Rights Reserved.

[Technology Partners]
Shopify Partner | 306 TechnologiesVercel Partner | 306 TechnologiesBooqable Partner | 306 Technologies