Blog/Deploy Medusa JS on Coolify

How to Deploy Medusa JS on Coolify (Step-by-Step Tutorial)

[Published On September 18, 2025]

Medusa Js and Coolify deployment guide
Share

In this blog post, I’ll take you through step-by-step on how to deploy your Medusa JS application to Coolify. We’ll cover everything from setting up your VPS to installing Coolify and getting your Medusa app live.

Setting Up Your VPS

To deploy our application on Coolify, we’ll need a VPS (Virtual Private Server). Think of it as a powerful computer sitting in a data center, where you rent a slice of it and use it just like your own machine.

We’ll be renting our VPS through a platform called Hostinger. Head over to hostinger.com and create your account. Once you’re logged in, head to the VPS tab in the dashboard and sign up for a KVM VPS.

On the “Choose an Operating System” screen, select the Ubuntu option. Next, you’ll be prompted to create a root password. Be sure to save it somewhere safe, you’ll need it later.

Hostinger offers several hardware options for their VPS plans. Since Coolify requires at least 2 CPU cores, 2 GB of RAM, and 30 GB of storage, the KVM 2 plan is the best fit for our needs.

Hostinger VPS plans

Once the VPS setup is complete, you’ll be taken to a dashboard with all the details about your virtual machine.

Copy the ROOT ACCESS string, it should look something like this ssh root@69.96.420.024 We’ll need this for our next step!

Hostinger VPS dashboard

Setting Up Coolify on Your VPS

Open the CLI (Command Line Interface) on your computer. For example, I’m on macOS, so I’ll be using Terminal.

Paste the Root Access string you copied earlier into the terminal and press Enter. You’ll then be prompted to enter your password; this is the same root password you created earlier when setting up the VPS.

Now it’s time to install Coolify on your virtual machine. Run the following command from inside your virtual machine.

1curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash

Once successful, the script will display your Coolify URL. It should look something like this: http://203.0.113.1:8000. Visit the URL and you'll be redirected to a registration page to create your first admin account.

Once you’ve created an account, you’re ready to spin up your first project.

Setting up PostgreSQL

Create a new project in Coolify and add a PostgreSQL resource to it. Make sure to select the latest version of PostgreSQL; it should be the default option.


Before you deploy and start your PostgreSQL instance, make sure to enable SSL under the SSL configuration and hit save.

Setting up Redis

In the same project you created in the last step, add a new resource for a Redis instance, and deploy.

Medusa Application Configurations

Now, let’s open up our Medusa application and make a few configurations before deploying.


The main thing to understand, and where a lot of people get stuck, is that your Medusa app needs to be deployed twice.

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


You’ll need to deploy both for your application to run smoothly.

Medusa JS deployment Infrastructure

Thankfully, you don’t need separate projects for the server and worker. You can simply specify the worker mode in the medusa-config file.

Update your Medusa config (medusa-config.ts) file to support both server mode and worker mode, and to optionally disable the admin dashboard.

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})

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.

Redis Configurations

We’ll use the REDIS_URL environment variable to connect Medusa to Redis. 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})

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.

So add the following Redis modules to your Medusa config.

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}); 26

Create a GitHub Repository

Create a new GitHub repository for your Medusa application, then commit your project files to it.

This will make things much easier when we deploy to Coolify. Plus, it will also allow you to automatically deploy when changes are made to your GitHub project.

New to Github? Follow this guide.

Deploy the Medusa Application in Server Mode

Back in Coolify, we’ll add a new resource for your Medusa application in server mode, apply the necessary configurations, and deploy it.

Create A New Resource

Add a new resource to the project we created earlier, and choose the “Private Repository (with GitHub App)” option. If it’s your first time, you’ll need to go through a few extra steps to connect your GitHub account.


Once connected, select your Medusa application’s GitHub repository. On the configuration settings screen, make sure to select the correct branch, change the port from 3000 to 9000, and click continue.

Start Command & Application Name

After your application is set up, you’ll be taken to the configuration screen. First, rename your application to “server.” This helps avoid confusion later since we’ll be deploying the same application twice.


We’ll also add a custom start command to make sure our Medusa server runs with the proper setup. Copy the command below and paste it into the “Start Command” input.

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

Be sure to click Save each time you make changes. The button is located at the top, next to “General.”

Add Environment Variables

In the Environment Variables tab of your Medusa server application, add the following variables. Be sure to replace <medusa-server-domain-name> with your actual domain name from the previous step.

1 2STORE_CORS=<medusa-server-domain-name> 3ADMIN_CORS=<medusa-server-domain-name> 4AUTH_CORS=<medusa-server-domain-name> 5JWT_SECRET=supersecret 6COOKIE_SECRET=supersecret 7DATABASE_URL= 8MEDUSA_BACKEND_URL=<medusa-server-domain-name> 9DISABLE_MEDUSA_ADMIN=false 10MEDUSA_WORKER_MODE=server 11PORT=9000 12REDIS_URL=

You’ll notice the values for DATABASE_URL and REDIS_URL are still empty. We’ll retrieve these from the PostgreSQL and Redis resources we deployed earlier.

Go to your PostgreSQL resource and copy the “Postgres URL (internal)”. Make sure SSL is enabled, and remove any parameters like ?sslmode=require or ?sslmode=disable from the end of your PostgreSQL database URL.

Paste the Postgres URL into the DATABASE_URL field in your environment variables.

1STORE_CORS=<medusa-server-domain-name> 2ADMIN_CORS=<medusa-server-domain-name> 3AUTH_CORS=<medusa-server-domain-name> 4JWT_SECRET=supersecret 5COOKIE_SECRET=supersecret 6DATABASE_URL=<postgres-url-internal> 7MEDUSA_BACKEND_URL=<medusa-server-domain-name> 8DISABLE_MEDUSA_ADMIN=false 9MEDUSA_WORKER_MODE=server 10PORT=9000 11REDIS_URL=


Go to your Redis resource and copy the “Redis URL (internal).” Paste this into the REDIS_URL field in your environment variables.

1STORE_CORS=<medusa-server-domain-name> 2ADMIN_CORS=<medusa-server-domain-name> 3AUTH_CORS=<medusa-server-domain-name> 4JWT_SECRET=supersecret 5COOKIE_SECRET=supersecret 6DATABASE_URL=<postgres-url-internal> 7MEDUSA_BACKEND_URL=<medusa-server-domain-name> 8DISABLE_MEDUSA_ADMIN=false 9MEDUSA_WORKER_MODE=server 10PORT=9000 11REDIS_URL=<redis-url-internal>

Be sure to click “Save All Environment Variables” at the bottom to save all changes.

Deploy Changes

Now you’re ready to deploy your Medusa server, just click the Deploy button in the top-right corner of the screen.

Deploy the Medusa Application in Worker Mode

Next, we’ll deploy our Medusa application in worker mode. We’ll use the same GitHub repository as before, but update a few environment variables to make it work.

Create A New Resource

Add a new resource, and choose the “Private Repository (with GitHub App)” option.

Select your Medusa application’s GitHub repository. Just like with the server application, go to the configuration settings screen, choose the correct branch, change the port from 3000 to 9000, and then click Continue.

Start Command & Application Name

After your application is set up, you’ll be taken to the configuration screen. First, rename your application to “worker” to differentiate it from the “server” application.


We’ll also add a custom start command. Copy the command below and paste it into the “Start Command” input, and click save.

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

Add Environment Variables

To keep things simple, copy the environment variables from your Medusa server application and paste them into the environment variables of your Medusa worker application.

Most of these variables will stay the same, with just a couple of exceptions. Set the MEDUSA_WORKER_MODE to worker and DISABLE_MEDUSA_ADMIN to true. Everything else can remain the same.

1STORE_CORS=<medusa-server-domain-name> 2ADMIN_CORS=<medusa-server-domain-name> 3AUTH_CORS=<medusa-server-domain-name> 4JWT_SECRET=supersecret 5COOKIE_SECRET=supersecret 6DATABASE_URL=<postgres-url-internal> 7MEDUSA_BACKEND_URL=<medusa-server-domain-name> 8DISABLE_MEDUSA_ADMIN=true 9MEDUSA_WORKER_MODE=worker 10PORT=9000 11REDIS_URL=<redis-url-internal>

Deploy Changes

Your Medusa worker is now ready to deploy! When you’re set, click the Deploy button.

Test Deployed Application

Once your deployment is successful, go to <medusa-server-domain-name>/health, If the deployment was successful, you’ll see the OK response. The Medusa admin can be accessed at <medusa-server-domain-name>/app.


If you’re unable to access your Medusa server domain URL, here are some common gotchas to check:

  • DNS Propagation / Cache. Clear your DNS cache from your CLI.
  • Firewall / Port blocking. Your home router or ISP might be blocking certain ports.
  • If you’ve forced HTTPS but your SSL certificate isn’t valid, the URL won’t resolve.
  • Make sure you’re using the Medusa server domain, not the worker domain. The server domain is where your admin dashboard lives.


If you’re on a non-HTTPS domain, you won’t be able to log in because cookies can’t be set securely over a non-HTTP connection.


In the next step, we’ll add a custom domain to our Medusa server application.

Add a Custom Domain

Log in to your domain registrar and open the DNS settings for your domain. Remove any old A records.


Add your VPS IP address as an A record. You can find this IP address in your Hostinger dashboard.

how to find Hostinger VPS IP address

Back in your Medusa server application on Coolify, add your domain name in the Domains field. Be sure to include both the www and non-www version of your domain.

Below the Domains field, you’ll find an option to set the redirection for your domain. Choose to redirect to the non-www version, so your domain always points to: https://your-domain-name.com.

Custom domain names in Coolify

Next, update the MEDUSA_BACKEND_URL with your custom domain URL. Also, add the same custom domain URL to ADMIN_CORS, AUTH_CORS, and STORE_CORS.

Do this for both the Medusa server application and the Medusa worker application.


Redeploy both the Medusa server and the worker, and you should be all set. Just keep in mind that DNS propagation can take a few hours, so a little patience may be required.

1STORE_CORS=<medusa-server-domain-name> 2ADMIN_CORS=<medusa-server-domain-name> 3AUTH_CORS=<medusa-server-domain-name> 4JWT_SECRET=supersecret 5COOKIE_SECRET=supersecret 6DATABASE_URL=<postgres-url-internal> 7MEDUSA_BACKEND_URL=<medusa-server-domain-name> 8DISABLE_MEDUSA_ADMIN=true/false 9MEDUSA_WORKER_MODE=worker/server 10PORT=9000 11REDIS_URL=<redis-url-internal>

Create Admin User

You can easily create an admin user, using the your Medusa server terminal in Coolify. Go to your Medusa server application, and then the “Terminal” tab.

Run the following command to create an admin user. Be sure to replace admin-medusa@test.com and supersecret with your own values.

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

Seeding Your Medusa Project

If you want to seed your Medusa project with demo products, run the following command from your Medusa server terminal.

1npm run seed

Troubleshooting

Raj Mahil Twitter/X account

Have questions or need help troubleshooting? Reach out to me on X (Twitter) @RajFrom306. I’m happy to help.


If you need a more advanced deployment setup or help with Medusa JS development, feel free to reach out through our contact form.

Fri, Oct 17, 2025, 03:32 AM

© 2025 306 Technologies Ltd. All Rights Reserved.

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