bolt Valebyte VPS from $4/mo — NVMe, 60s deploy.

Get a VPS arrow_forward

Medusa on VPS: installation, configuration, and maintenance

calendar_month June 18, 2026 schedule 17 min read visibility 24 views
person
Valebyte Team
Medusa on VPS: installation, configuration, and maintenance

Installing Medusa on a VPS is an effective way to deploy a powerful and flexible e-commerce platform, providing full control over the infrastructure, data, and scalability of your online store.

What is Medusa and why do you need Medusa on a VPS?

Medusa is a modern, open-source, headless e-commerce platform built for developers. It offers a powerful API-first approach, allowing you to create fully customized storefronts using any frontend framework (React, Next.js, Vue.js, etc.), integrate various third-party services and payment gateways, and scale functionality to meet any business requirements. Unlike monolithic solutions, Medusa separates the backend (API), admin panel, and storefront, providing maximum flexibility and performance.

Using Medusa on a VPS gives you several significant advantages. Firstly, it provides full control over the deployment environment. You are not limited by the constraints of SaaS platforms; you can install any necessary dependencies, configure the server to your needs, and ensure maximum security. Secondly, Medusa self-hosted on your own server allows you to avoid subscription fees for hosting, which often increase with your business's turnover on commercial platforms. You only pay for VPS resources, which can be significantly more cost-effective in the long run, especially with high sales volumes.

Deploying Medusa on a Virtual Private Server (VPS) from Valebyte.com provides a reliable and high-performance foundation for your online store. Our plans include NVMe SSDs, which are critically important for fast database operations and content loading, as well as stable communication channels, ensuring instant response times for your customers.

To simplify the deployment and management process, we will use Medusa Docker. Dockerization allows you to isolate the application with all its dependencies, simplifies scaling, updating, and migrating Medusa to other servers. This is an ideal approach for modern development and operations.

System Requirements for Medusa on a Server: What You Need to Know?

Before proceeding with Medusa installation, it's important to ensure that your VPS meets the minimum requirements. Medusa consists of several components: backend (Node.js), database (PostgreSQL), cache (Redis), and optionally a frontend (Storefront) and admin panel. All these components consume system resources.

Minimum and Recommended Configurations for Medusa VPS

For a small store with limited traffic and assortment (up to 1000 products, up to 100 concurrent users), the following minimum requirements are suitable:

  • Processor (CPU): 2 vCPU. Medusa Backend on Node.js uses multi-core processing quite efficiently.
  • Random Access Memory (RAM): 4 GB. This will be sufficient for all Docker container components (PostgreSQL, Redis, Medusa Backend, Storefront, Admin) to run.
  • Disk Space: 50 GB NVMe SSD. NVMe drives are critically important for PostgreSQL database performance and file loading speed.
  • Network Channel: 100 Mbps.
  • Operating System: Ubuntu 22.04 LTS (recommended) or Debian 11/12.

For medium and large projects (thousands of products, hundreds of concurrent users, active use of plugins and integrations), it is recommended:

  • Processor (CPU): 4 vCPU or more.
  • Random Access Memory (RAM): 8 GB or more. PostgreSQL and Redis can consume significant amounts of memory with large data volumes.
  • Disk Space: 100 GB NVMe SSD or more.
  • Network Channel: 1 Gbps.
  • Operating System: Ubuntu 22.04 LTS.

Always choose NVMe SSD. The difference in speed compared to regular SSDs or HDDs is enormous and directly impacts your store's performance, especially when processing database queries.

Choosing an Operating System for Medusa on a Server

The most popular and well-supported Linux distributions for deploying Docker containers are Ubuntu Server LTS (Long Term Support) and Debian Stable. We recommend Ubuntu 22.04 LTS due to its broad community support, up-to-date packages, and stability. All commands in this guide will be oriented towards Ubuntu.

Looking for a reliable server for your projects?

VPS from $10/month and dedicated servers from $9/month with NVMe, DDoS protection, and 24/7 support.

View Offers →

Preparing Your VPS for Medusa Docker Installation

Before proceeding with Medusa installation, you need to prepare your VPS. This includes updating the system, installing Docker and Docker Compose, and basic security configuration.

System Update and Installation of Necessary Packages

Connect to your VPS via SSH as the root user or a user with sudo privileges. First, update the package list and the system itself:

sudo apt update
sudo apt upgrade -y

Install necessary utilities such as git (for cloning the Medusa repository) and curl (often used for downloading scripts):

sudo apt install git curl -y

Configure the basic UFW (Uncomplicated Firewall) to allow only necessary ports. To start, we'll allow SSH (port 22), HTTP (port 80), and HTTPS (port 443):

sudo ufw allow OpenSSH
sudo ufw allow http
sudo ufw allow https
sudo ufw enable
sudo ufw status

Confirm firewall activation by entering y.

Installing Docker and Docker Compose for Medusa on a VPS

Medusa Docker is the simplest and recommended deployment method. We will install Docker Engine and Docker Compose. The official Docker installation script will do this for you:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

Add the current user to the docker group to avoid using sudo with every Docker command:

sudo usermod -aG docker $USER
newgrp docker

Check Docker installation:

docker --version
docker compose version

If you see the Docker and Docker Compose versions, the installation was successful. Your VPS is now ready for Medusa deployment.

rocket_launch Quick pick

Need a dedicated server?

Compare prices from top providers. Configure and order in minutes.

Browse dedicated servers arrow_forward

Step-by-Step Medusa Installation on a VPS with Docker Compose

Now that the VPS is ready, we can proceed with Medusa installation using Docker Compose. This approach allows you to manage all Medusa components as a single service.

Cloning the Repository and Configuring the Environment for Medusa Docker

Medusa provides ready-made templates for Docker Compose, which significantly simplifies the process. Navigate to your user's home directory or create a separate directory for your project:

cd ~
mkdir medusa-store
cd medusa-store

Clone the official Medusa repository with the Docker Compose configuration:

git clone https://github.com/medusajs/medusa-starter-ecommerce.git .

Copy the example environment variables file and edit it. This file will contain important settings such as API keys, database URL, etc.

cp .env.template .env
nano .env

In the .env file, you will need to configure the following variables:

  • DATABASE_URL: URL for connecting to PostgreSQL. By default in Docker Compose, this will be postgres://medusa:password@medusa-db:5432/medusa. Change password to a more secure one.
  • REDIS_URL: URL for connecting to Redis. By default redis://medusa-redis:6379.
  • JWT_SECRET: Secret key for JSON Web Tokens. Generate a long random string.
  • COOKIE_SECRET: Secret key for session cookies. Also generate a long random string.
  • ADMIN_CORS: URL of your admin panel (e.g., http://localhost:7000,http://admin.yourdomain.com).
  • STORE_CORS: URL of your storefront (e.g., http://localhost:8000,http://yourdomain.com).

Example .env content (replace your_secure_password, your_jwt_secret, your_cookie_secret, and domains):

# Database
DATABASE_URL=postgres://medusa:your_secure_password@medusa-db:5432/medusa
REDIS_URL=redis://medusa-redis:6379

# Medusa Backend
PORT=9000
MEDUSA_URL=http://localhost:9000 # Inside the Docker network, a reverse proxy will be used for external access
ADMIN_CORS=http://localhost:7000,https://admin.yourdomain.com
STORE_CORS=http://localhost:8000,https://www.yourdomain.com
JWT_SECRET=your_jwt_secret_here_at_least_32_chars
COOKIE_SECRET=your_cookie_secret_here_at_least_32_chars

Save changes (Ctrl+O, Enter, Ctrl+X).

Now copy the `docker-compose.yml` file. Depending on the repository, it might be named `docker-compose.yml.template` or simply be in the root. Ensure you have a `docker-compose.yml` file that includes services for PostgreSQL, Redis, Medusa Backend, as well as Storefront and Admin (if using official starters).

Example `docker-compose.yml` structure you will find in the starter repository:

version: "3.8"

services:
  medusa-db:
    image: postgres:13-alpine
    restart: always
    environment:
      POSTGRES_USER: medusa
      POSTGRES_PASSWORD: ${DB_PASSWORD} # Will be taken from .env (DATABASE_URL)
      POSTGRES_DB: medusa
    volumes:
      - db_data:/var/lib/postgresql/data
    ports:
      - "5432:5432" # For debugging only, better not to expose in production

  medusa-redis:
    image: redis:6-alpine
    restart: always
    volumes:
      - redis_data:/data
    ports:
      - "6379:6379" # For debugging only, better not to expose in production

  medusa-backend:
    build:
      context: .
      dockerfile: Dockerfile
    restart: always
    environment:
      DATABASE_URL: ${DATABASE_URL}
      REDIS_URL: ${REDIS_URL}
      JWT_SECRET: ${JWT_SECRET}
      COOKIE_SECRET: ${COOKIE_SECRET}
      ADMIN_CORS: ${ADMIN_CORS}
      STORE_CORS: ${STORE_CORS}
      # Additional variables for plugins and services
    ports:
      - "9000:9000"
    depends_on:
      - medusa-db
      - medusa-redis

  medusa-admin:
    build:
      context: .
      dockerfile: Dockerfile.admin
    restart: always
    environment:
      MEDUSA_BACKEND_URL: http://medusa-backend:9000 # Inside the Docker network
    ports:
      - "7000:7000"
    depends_on:
      - medusa-backend

  medusa-storefront:
    build:
      context: .
      dockerfile: Dockerfile.storefront
    restart: always
    environment:
      NEXT_PUBLIC_MEDUSA_BACKEND_URL: http://medusa-backend:9000 # Inside the Docker network
    ports:
      - "8000:8000"
    depends_on:
      - medusa-backend

volumes:
  db_data:
  redis_data:

Pay attention to the ports in `docker-compose.yml`. In a production environment, it's better not to expose ports for `medusa-db` and `medusa-redis` externally (remove the `ports` section), as they will only be accessible from within the Docker network for other containers.

Now create the necessary Dockerfiles for the backend, admin panel, and storefront, if they are not already in the root. They are usually provided in the starter repository. For example, the `Dockerfile` for the backend might look like this:

FROM node:18-alpine

WORKDIR /app

COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

COPY . .

RUN yarn build

CMD ["yarn", "start"]

Similarly for `Dockerfile.admin` and `Dockerfile.storefront`, using the appropriate build and run commands for Next.js or another framework.

Starting Medusa Backend, Storefront, and Admin

After configuring `.env` and verifying `docker-compose.yml`, you can start all services. First, initialize the Medusa database:

docker compose run medusa-backend medusa seed
docker compose run medusa-backend medusa migrations run

The `medusa seed` command (if it exists in your starter project) can load demo data, which is useful for testing. `medusa migrations run` applies all necessary database migrations.

Now, start all services in the background:

docker compose up -d --build

The `--build` option ensures that images are rebuilt, which is useful for the first run or when Dockerfiles are changed. The `-d` option runs containers in detached mode.

Check the status of running containers:

docker compose ps

You should see all services (`medusa-db`, `medusa-redis`, `medusa-backend`, `medusa-admin`, `medusa-storefront`) in `Up` status.

After startup, you need to create the first administrator user to access the Medusa admin panel:

docker compose exec medusa-backend medusa user --email [email protected] --password your_admin_password

Replace `[email protected]` and `your_admin_password` with your desired credentials. Ensure the password is strong enough. After this, you will be able to log in to the admin panel.

Configuring Reverse Proxy and HTTPS for Medusa

To ensure secure and convenient access to your **Medusa on server** store, as well as to work with domain names, you need to configure a Reverse Proxy with HTTPS support. This will allow you to direct traffic from your domain to the corresponding Docker container ports and encrypt the connection.

Why are Reverse Proxy and HTTPS needed?

  • Reverse Proxy: Allows you to direct requests from a single domain name (e.g., www.yourdomain.com or admin.yourdomain.com) to different internal services running on different ports. It can also cache content, balance load, and provide an additional layer of security.
  • HTTPS (SSL/TLS): Encrypts all traffic between the user's browser and your server. This is critically important for protecting sensitive data (passwords, payment information) and is a mandatory requirement for SEO, modern browsers, and payment systems. Let's Encrypt provides free SSL certificates.

We will look at configuring Nginx and Caddy — two popular and efficient Reverse Proxies.

Configuring Nginx as a Reverse Proxy for Medusa

Install Nginx on your VPS:

sudo apt install nginx -y

Create a configuration file for your domain. For example, for www.yourdomain.com and admin.yourdomain.com:

sudo nano /etc/nginx/sites-available/medusa.conf

Example Nginx configuration (replace yourdomain.com with your actual domain):

server {
    listen 80;
    listen [::]:80;
    server_name www.yourdomain.com yourdomain.com; # Main domain for the storefront

    location / {
        return 301 https://$host$request_uri; # Redirect to HTTPS
    }
}

server {
    listen 80;
    listen [::]:80;
    server_name admin.yourdomain.com; # Domain for the admin panel

    location / {
        return 301 https://$host$request_uri; # Redirect to HTTPS
    }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name www.yourdomain.com yourdomain.com; # Main domain for the storefront

    ssl_certificate /etc/letsencrypt/live/www.yourdomain.com/fullchain.pem; # Path to Let's Encrypt certificate
    ssl_certificate_key /etc/letsencrypt/live/www.yourdomain.com/privkey.pem; # Path to Let's Encrypt key
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://localhost:8000; # Medusa Storefront Port (Next.js)
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }

    # If the backend is accessible via API on the main domain, use a prefix
    # location /api/ {
    #     proxy_pass http://localhost:9000; # Medusa Backend Port
    #     proxy_set_header Host $host;
    #     proxy_set_header X-Real-IP $remote_addr;
    #     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    #     proxy_set_header X-Forwarded-Proto $scheme;
    #     proxy_redirect off;
    # }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name admin.yourdomain.com; # Domain for the admin panel

    ssl_certificate /etc/letsencrypt/live/admin.yourdomain.com/fullchain.pem; # Path to Let's Encrypt certificate
    ssl_certificate_key /etc/letsencrypt/live/admin.yourdomain.com/privkey.pem; # Path to Let's Encrypt key
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://localhost:7000; # Medusa Admin Port (Next.js)
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }

    location /admin/api/ { # API for the admin panel
        proxy_pass http://localhost:9000/admin/api/; # Medusa Backend Port
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name api.yourdomain.com; # Domain for the backend API

    ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://localhost:9000; # Medusa Backend Port
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
}

Create a symbolic link to the configuration file:

sudo ln -s /etc/nginx/sites-available/medusa.conf /etc/nginx/sites-enabled/

Remove the default Nginx configuration, if it exists:

sudo rm /etc/nginx/sites-enabled/default

Check Nginx syntax:

sudo nginx -t

Reload Nginx:

sudo systemctl restart nginx

Now install Certbot to obtain Let's Encrypt SSL certificates:

sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com -d admin.yourdomain.com -d api.yourdomain.com

Follow Certbot's instructions. It will automatically configure Nginx for HTTPS. After that, check Nginx syntax again and restart it. Your Medusa store is now accessible via HTTPS through domain names.

Configuring Caddy as a Reverse Proxy (alternative)

Caddy is a modern web server that automatically generates and renews Let's Encrypt SSL certificates. This makes it very convenient for quick HTTPS setup.

Install Caddy:

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy -y

Create or edit the `/etc/caddy/Caddyfile`:

sudo nano /etc/caddy/Caddyfile

Example Caddy configuration (replace yourdomain.com with your actual domain):

www.yourdomain.com, yourdomain.com {
    reverse_proxy localhost:8000 # Medusa Storefront Port
}

admin.yourdomain.com {
    reverse_proxy localhost:7000 # Medusa Admin Port
}

api.yourdomain.com {
    reverse_proxy localhost:9000 # Medusa Backend Port
}

Save the file and restart Caddy:

sudo systemctl restart caddy
sudo systemctl enable caddy

Caddy will automatically obtain and configure SSL certificates for your domains. This is significantly simpler than manual Nginx and Certbot configuration, but Nginx offers more options for fine-tuning.

Initial Setup and Maintenance of Medusa

After successful Medusa installation on a VPS and Reverse Proxy configuration, you need to perform a series of initial settings and plan a maintenance strategy.

Accessing the Admin Panel and Basic Steps

Open your admin panel URL in a browser (e.g., https://admin.yourdomain.com) and log in using the credentials created earlier (`[email protected]` and `your_admin_password`). In the admin panel, you can:

  • Configure regions and currencies: Define which countries you will sell to and which currencies to support.
  • Add products: Upload products, their descriptions, images, variants, and prices.
  • Create collections: Group products for easy navigation.
  • Set up shipping methods: Integrate shipping services and define rates.
  • Integrate payment gateways: Connect Stripe, PayPal, or other payment systems.
  • Configure plugins: Medusa supports many plugins to extend functionality (file storage, notifications, analytics).

Remember that Medusa is an API-first platform. All store logic operates through the backend. The frontend (storefront) merely consumes data from the API. Ensure your frontend project is correctly configured to interact with the Medusa API.

Regular Backups of Medusa Data on the Server

Backup is a critically important aspect of maintaining any online service. Data loss can lead to catastrophic consequences for your business. For Medusa on server, you need to regularly back up the following components:

  1. PostgreSQL Database: Contains all your store's data (products, orders, customers, settings).
  2. Medusa Configuration Files: The `.env` file and any custom plugins or code changes.
  3. File Storage: If you use local file storage for product images, rather than cloud storage (S3, MinIO), these files also need to be backed up.

For PostgreSQL, you can use `pg_dump`:

docker compose exec medusa-db pg_dump -U medusa -d medusa > /path/to/backups/medusa_db_$(date +%Y%m%d%H%M%S).sql

It is recommended to store backups not only on the same VPS but also on remote storage (e.g., S3-compatible storage or another server). For automation and backup management, you can use tools like Restic, which allows you to create encrypted and deduplicated backups.

Set up Cron jobs to automatically perform backups, for example, daily or weekly, depending on the volume of changes in your store.

Updating Medusa and Docker Components

Regularly updating Medusa and its components (Node.js, PostgreSQL, Redis) is important for security, stability, and receiving new features. Since we are using Medusa Docker, the update process is simplified:

  1. Updating Docker images:
    cd ~/medusa-store
            docker compose pull # Will download new image versions
            docker compose down # Will stop current containers
            docker compose up -d --build # Will start new containers, rebuilding Medusa Backend, Storefront, Admin
            

    The `--build` option is important as it rebuilds your custom Dockerfiles using updated base images.

  2. Updating Medusa Backend: If you have made changes to the Medusa code or are using custom plugins, you may also need to update Node.js dependencies and rebuild the backend. Check the official Medusa documentation for specific version update instructions. This usually involves updating `package.json` and running `yarn install`.
  3. Updating the operating system: Periodically update your OS:
    sudo apt update && sudo apt upgrade -y
            

Always perform a full backup before any major update!

It is also useful to have a tool for managing files on the server, such as Filebrowser, which provides a web interface for working with configuration files and backups.

rocket_launch Quick pick

Need a dedicated server?

Compare prices from top providers. Configure and order in minutes.

Browse dedicated servers arrow_forward

Choosing the Optimal VPS for Medusa Under Real Load

Choosing the right VPS configuration for Medusa on VPS is a key factor for the performance and stability of your online store. A server that is too weak will lead to slow operation and loss of customers, while one that is too powerful will result in unjustified expenses.

Factors Affecting Medusa Performance

  • Number of products: The more products, the more data in PostgreSQL, which requires more disk space and RAM for the database.
  • Number of orders: A high frequency of orders increases the load on the database and Medusa backend.
  • Number of concurrent users: Each active user consumes backend and frontend resources.
  • Use of plugins and integrations: Additional plugins can increase RAM and CPU consumption.
  • Scale of media content: If you store many images or videos locally, this increases disk space and I/O requirements.
  • Frequency of data updates: Regular imports/exports or batch operations can temporarily increase load.

VPS Configuration Recommendations for Medusa

Valebyte.com offers various VPS plans that are ideally suited for deploying Medusa. Here are general recommendations for choosing a configuration:

Usage Scenario vCPU RAM (GB) Disk (NVMe SSD) Approx. Cost/month Notes
Small Store / Testing
(up to 500 products, up to 50 orders/day, up to 20 concurrent users)
2 4 50 GB from $10-$15 Ideal for startup, MVP, and development. Ensure NVMe drives.
Medium Store
(up to 5000 products, up to 200 orders/day, up to 100 concurrent users)
4 8 100 GB from $20-$35 Good balance of performance and cost. Recommended for growing projects.
Large Store / High Load
(over 5000 products, over 200 orders/day, hundreds of concurrent users)
6-8+ 16+ 200 GB+ from $40-$70+ Requires Medusa optimization and potentially horizontal scaling (separate VPS for database, backend).

It is important to note that these figures are approximate. Actual load can vary significantly. Always start with a configuration that slightly exceeds the minimum requirements and scale it as your project grows. Resource monitoring (CPU, RAM, disk I/O) will help you determine when it's time to upgrade to a more powerful plan. For example, for projects like Home Assistant or NocoDB, which actively work with databases, disk and RAM requirements can be comparable.

By choosing a VPS from Valebyte.com, you get access to high-performance NVMe SSDs, stable communication channels, and flexible pricing plans that can be easily scaled as your business grows. This provides an ideal environment for your **Medusa on server**.

Conclusion

Deploying Medusa on a VPS via Docker Compose is a powerful and flexible solution for creating a modern online store, giving you full control over your e-commerce platform. By following this step-by-step guide, you can successfully install, configure, and maintain Medusa, ensuring high performance and security. Choose a reliable VPS from Valebyte.com with NVMe SSD for optimal operation of your Medusa.

Ready to choose a server?

VPS and dedicated servers in 72+ countries with instant activation and full root access.

Get Started Now →
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.