Medusa setup example
This page walks through a full Medusa installation on TurboStack, step by step: the Medusa backend (which includes the admin dashboard) and the optional Next.js storefront. It is a worked example that complements Deploy Medusa on TurboStack - read that page first for the host configuration and the reasoning behind the reverse-proxy pattern.
If you only want the backend, you can skip the storefront steps. Medusa exposes an Application Programming Interface (API) so you can connect your own storefront later.
Before you start
Configure the host as described in Deploy Medusa on TurboStack. The example below
assumes two websites (vhosts) under one system user, each with proxy_enabled: true so Nginx
proxies public traffic to the Node process:
- a storefront on port
8000(for exampleshop.example.com) - the Medusa backend and admin on port
9000(for exampledashboard.example.com)
webserver: nginx
postgresql_version: "18"
system_users:
- username: prod
vhosts:
- server_name: shop.example.com www.shop.example.com
app_name: frontend
nodejs_version: "24"
cert_type: letsencrypt
proxy_enabled: true
proxy_upstream_port: "8000"
- server_name: dashboard.example.com
app_name: dashboard
nodejs_version: "24"
cert_type: letsencrypt
proxy_enabled: true
proxy_upstream_port: "9000"
Publish the host so the two websites and PostgreSQL exist, then open an SSH session as the system user for the steps below.
Note
If you only want the backend, remove the storefront vhost.
Step 1: Create the Medusa project
Create a directory for the project in your home directory and change into it:
mkdir project
cd project
Warning
Do not place the project inside public_html. That directory is served publicly and would expose
source and configuration files.
Run the Medusa installer:
npx create-medusa-app@latest <shopname>
Follow the interactive prompts. When asked, provide your PostgreSQL credentials:
? Would you like to install the Next.js Starter Storefront? Yes
? Enter your Postgres username prod
? Enter your Postgres password [hidden]
? Enter your Postgres user's database name prod
You find the PostgreSQL credentials in the TurboStack interface under the host's Credentials, or
on the server in the ~/.pgpass file:
cat ~/.pgpass
The installer is finished when it prints:
Server is ready on port: 9000
Stop the test server with Ctrl + C. You will start it as a persistent service later.
Note
If you only want the backend, answer No to the storefront prompt.
Step 2: Create an admin user
You need an admin account to sign in to the dashboard. Change the values to your own:
npx medusa user -e user@example.com -p <StrongPassword>
Step 3: Allow your dashboard domain
Medusa's admin runs on a development server that only accepts requests for hosts it knows. Add your
dashboard domain to the allowedHosts list in medusa-config.ts, found at
~/project/<shopname>/medusa-config.ts. Add the admin block:
import { loadEnv, defineConfig } from '@medusajs/framework/utils'
loadEnv(process.env.NODE_ENV || 'development', process.cwd())
module.exports = defineConfig({
projectConfig: {
databaseUrl: process.env.DATABASE_URL,
http: {
storeCors: process.env.STORE_CORS,
adminCors: process.env.ADMIN_CORS,
authCors: process.env.AUTH_CORS,
jwtSecret: process.env.JWT_SECRET || "supersecret",
cookieSecret: process.env.COOKIE_SECRET || "supersecret",
},
},
admin: {
// Allow the host (and its subdomains) that serve the admin dashboard
vite: (config) => {
return {
...config,
server: {
allowedHosts: [".example.com"],
},
}
},
},
})
Step 4: Build and run the backend for production
The development server is not suitable for production. From the project directory
~/project/<shopname>/, build the backend:
npx medusa build
The build writes a production bundle to .medusa/server. Change into it and install its
dependencies:
cd .medusa/server
npm install
Copy the environment file from the project root into the build directory:
cp ../../.env .env
Start the server once to confirm it works:
npx medusa start
Open https://dashboard.example.com in your browser and sign in with the admin account you created.
When the backend loads correctly, stop it with Ctrl + C and start it as a persistent process so it
survives your logout and restarts on boot. A Node process manager such as PM2 does this:
pm2 start "npx medusa start" --name medusa-backend
Step 5: Build and run the storefront (optional)
Change into the storefront directory and install its dependencies:
cd ~/project/<shopname>-storefront
npm install
Build and start it once to confirm it listens on port 8000:
npm run build
npm start
When it works, stop it with Ctrl + C and start it as a persistent process:
pm2 start "npm start" --name storefront
The storefront is now reachable at https://shop.example.com, proxied by Nginx to port 8000.
Tip: Non-interactive install
To script the installation, pass the database connection string and the storefront flag directly, so
create-medusa-app does not prompt:
npx create-medusa-app@latest <shopname> \
--db-url "postgres://<username>:<password>@localhost:5432/<dbname>" \
--with-nextjs-starter
Read the credentials from ~/.pgpass rather than copying them from the interface. If you only need
the backend, delete the generated storefront directory afterward.
Related
- Deploy Medusa on TurboStack - the host YAML and the reverse-proxy pattern.
- Medusa best practices - performance and stability.
- Troubleshooting Medusa - logs and common fixes.
- What is SSH?
- Applications overview