Analytics cookies only (Google Analytics, PostHog). No ad networks, no cross-site tracking. See our privacy policy.
Self-host Medusa
updated Oct 2026deployed by usprices checked · Jul 2026Install verified on Ubuntu 26.04 · Oct 2026 · how we test
We earn commissions when you shop through the links below. Full disclosure →
A headless commerce platform and framework for Node.js and TypeScript: products, carts, orders, payments, promotions and regions as modules behind a REST API, with a React Admin dashboard served from the same process. You extend it in code with your own modules, workflows and subscribers, and bring your own storefront (a Next.js starter is optional). It runs on PostgreSQL, with Redis for production. The repository is MIT apart from its Enterprise Edition materials (role-based access control and SSO), which are proprietary.
Key facts
CategoryE-commerce
LicenseMIT core with proprietary enterprise modules
Runs on a VPS from $12/mo (Kamatera 4GB, 4 GB RAM) · prices checked Sep 2026
Our recommendation
Pick Medusa when your team writes TypeScript and wants a commerce backend it can extend in code rather than configure around: products, carts, orders, payments, promotions and regions as modules, a REST API, and an Admin dashboard served from the same Node.js process. The installer is `create-medusa-app`, which sets up the project, runs migrations and seeds demo products; the storefront is yours to build, with an optional Next.js starter. The repository is MIT apart from the Enterprise Edition files for role-based access control and SSO. If you would rather run a ready-made Docker stack with a GraphQL API, Saleor is the catalog's other headless option.
What you need
Any VPS with at least 2048 MB of RAM
A domain you control — most self-hosted setups need HTTPS in front of them
About an afternoon — budget time for troubleshooting
Paid link — we earn a commission if you shop through it.
Install
Run these commands on your server:
# Medusa — create-medusa-app (the official installer from the docs) pinned to 2.21.2, then the production build and start steps from Medusa's deployment guide. Node.js 20.19+ or 22.12+, Git and PostgreSQL are required. Replace SERVER_IP with your server's address and choose your own passwords.sudo apt-get update && sudo apt-get install -y nodejs npm git postgresqlsudo -u postgres psql -c "CREATE USER medusa WITH PASSWORD 'choose-a-db-password'" -c "CREATE DATABASE medusa OWNER medusa"# the installer asks whether to add the Next.js storefront; the n answers that prompt. It runs migrations and seeds a few demo products.printf 'n\n' | npx --yes create-medusa-app@2.21.2 my-medusa-store --version 2.21.2 --db-url "postgres://medusa:choose-a-db-password@localhost:5432/medusa" --no-browser --use-npmcd my-medusa-store/apps/backend# the generated .env ships JWT_SECRET and COOKIE_SECRET as "supersecret" and localhost CORS origins; production start needs real secretssed -i -e "s|^JWT_SECRET=.*|JWT_SECRET=$(openssl rand -hex 32)|" -e "s|^COOKIE_SECRET=.*|COOKIE_SECRET=$(openssl rand -hex 32)|" -e "s|^ADMIN_CORS=.*|ADMIN_CORS=http://SERVER_IP:9000|" -e "s|^AUTH_CORS=.*|AUTH_CORS=http://SERVER_IP:9000|" .envnpm run buildcd .medusa/server && npm installset -a; . ../../.env; set +anpx medusa user -e admin@example.com -p choose-an-admin-passwordNODE_ENV=production nohup npm run start > ~/medusa.log 2>&1 &# the Admin is at http://SERVER_IP:9000/app and the store API on the same port; put it under a systemd unit and add Redis before real traffic
Medusa is a framework you deploy, not a packaged appliance, and its own deployment guide sets the production bar:
non-negotiableRole-based access control and SSO are Medusa Enterprise Edition features: ENTERPRISE-LICENSE.md lists the RBAC and SSO paths as proprietary software that needs a commercial agreement with MedusaJS, Inc., and the rest of the repository is MIT.
non-negotiableThere is no official Docker Compose file or image in the repository, so you build and run the Node.js app yourself. The installer lays out a monorepo, the backend builds into .medusa/server, and that folder needs its own npm install before medusa start. Our snippet runs it with nohup; use a systemd unit or a container in practice.
non-negotiableThe generated .env ships JWT_SECRET and COOKIE_SECRET as supersecret and localhost CORS origins. Replace the secrets, and set ADMIN_CORS and AUTH_CORS to the URL the Admin is served from, or the dashboard cannot sign in. Production start refuses missing secrets.
non-negotiableThe deployment guide asks for PostgreSQL and Redis, two instances of the app (server mode for requests and the Admin, worker mode for background jobs) and at least 2 GB of RAM. Without a REDIS_URL module config Medusa logs that a fake in-memory Redis is used and will not scale past a single process, which is fine for one server and not for more.
non-negotiableMedusa collects anonymous usage analytics by default; turn it off with medusa telemetry --disable. Upgrades are yours too: pin the Medusa version in package.json and run medusa db:migrate (the guide's predeploy step) before starting a new build.