Deployment
MERN Production Setup Guide: Node.js, MongoDB, PM2, and Nginx
A step-by-step MERN production setup guide with Ubuntu, Node.js, MongoDB, PM2, Nginx, environment variables, and deployment commands.
Advertisement
What a Good MERN Production Setup Actually Includes
A real MERN production setup is not just “run npm start on a server.” In production, the stack needs clear separation between frontend, backend, database, and web server responsibilities. That usually means the React frontend is built and served efficiently, the Express API runs as a managed background process, MongoDB is secured properly, and Nginx handles the public traffic.
For most teams hosting on Ubuntu, a strong baseline setup is: React frontend build, Node.js and Express API behind PM2, MongoDB running locally or through a managed service, and Nginx as the reverse proxy. This keeps the stack understandable and maintainable while still being production-safe.
This guide is written around that model so you can deploy a MERN application in a way that is actually usable after launch, not just technically online.
Recommended Server Structure
Before touching packages, decide how the app will be organized on the server. A clean convention is to keep the frontend and backend in separate directories under /var/www. This helps with logs, deployments, restarts, and environment files later.
A simple structure looks like frontend for the React app and backend for the Express API. MongoDB can run on the same server for smaller setups, but if the app is customer-facing and expected to grow, a managed MongoDB instance is often safer and easier to maintain.
The main thing is consistency. Production problems become much easier to debug when paths and responsibilities are obvious.
- /var/www/mern-app/frontend for the React client
- /var/www/mern-app/backend for the Express API
- MongoDB either local or managed
- Nginx as the public entry point
Install Core Packages on Ubuntu
Start by updating Ubuntu, then install Node.js, Nginx, and the tools you need for backend process management. If you are running MongoDB on the same server, install that separately based on the MongoDB version and repository you approve for production.
The commands below set up the common runtime layer first. This is the foundation both frontend and backend will use.
sudo apt update && sudo apt upgrade -y
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs nginx
sudo npm install -g pm2
node -v
npm -v
pm2 -v
sudo systemctl enable nginx
sudo systemctl start nginx- Update Ubuntu first
- Install Node.js 20 and Nginx
- Install PM2 for backend process management
Deploy the Backend API
The backend should be treated as the persistent application process in the MERN stack. Put it in a stable directory, install packages, define production environment variables, and verify it can boot before you introduce Nginx routing.
A typical backend environment file includes the port, MongoDB connection string, JWT secret, and any third-party API keys. Never hardcode these into production source files.
mkdir -p /var/www/mern-app
cd /var/www/mern-app
git clone https://github.com/yourname/your-mern-backend.git backend
sudo chown -R $USER:$USER /var/www/mern-app
cd /var/www/mern-app/backend
npm install
nano .envPORT=5000
NODE_ENV=production
MONGO_URI=mongodb://127.0.0.1:27017/myapp
JWT_SECRET=replace-this-with-a-strong-secret
CLIENT_URL=https://example.comcd /var/www/mern-app/backend
npm run start- Clone backend into a stable path
- Create production env values before starting the API
- Test the backend directly before configuring Nginx
Run the Express API with PM2
Once the API works, hand it over to PM2. This is the process manager that will keep the backend alive, restart it if it crashes, and allow it to come back after a server reboot.
You can start the app directly from the backend directory. If your backend uses a different production command, use that instead of the simple example below.
cd /var/www/mern-app/backend
pm2 start npm --name "mern-api" -- start
pm2 logs mern-api
pm2 save
pm2 startup- Start the API with PM2
- Check logs before moving on
- Save PM2 startup state
Build and Deploy the React Frontend
The frontend side of a MERN app is usually built into static assets. That means you do not normally keep the React development server running in production. Instead, you build the frontend and let Nginx serve the generated files.
This makes the public site faster and simpler. It also reduces the number of moving parts compared with keeping both the API and frontend running as separate long-lived Node processes.
cd /var/www/mern-app
git clone https://github.com/yourname/your-mern-frontend.git frontend
cd /var/www/mern-app/frontend
npm install
nano .envVITE_API_BASE_URL=https://example.com/apicd /var/www/mern-app/frontend
npm run build- Build the frontend into static files
- Serve the build output with Nginx
- Use frontend env values that point to the production API
Configure Nginx for Both Frontend and API
Nginx should do two jobs here: serve the built React frontend and proxy API requests to the Express backend. This is one of the cleanest production patterns for a MERN stack because it keeps the frontend static and the backend isolated.
The example below assumes the frontend build output is in dist. If your React setup uses build instead, update the path accordingly.
server {
listen 80;
server_name example.com www.example.com;
root /var/www/mern-app/frontend/dist;
index index.html;
location / {
try_files $uri /index.html;
}
location /api/ {
proxy_pass http://127.0.0.1:5000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
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;
}
}sudo nano /etc/nginx/sites-available/mern-app
sudo ln -s /etc/nginx/sites-available/mern-app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx- Serve frontend build files directly
- Proxy /api requests to Express on port 5000
- Fallback unknown frontend routes to index.html
Add HTTPS and Basic Firewall Rules
Once the frontend and API routing work over HTTP, add HTTPS. This should be part of the default production setup, not a later cleanup task. If your app is public, it should be encrypted from the start.
It is also worth enabling UFW with basic rules for SSH and Nginx. That gives the server a safer default network posture.
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
sudo certbot renew --dry-run
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status- Install Certbot for Nginx
- Issue SSL for root and www domain
- Allow only the firewall ports you need
Production Deployment Workflow for Updates
Once the stack is live, updates should follow a repeatable flow. Pull backend changes, install dependencies if needed, restart the API with PM2, then pull frontend changes, rebuild, and reload Nginx if required. The goal is a deployment sequence your team can repeat without guessing.
The exact commands depend on how your repos are organized, but the pattern below is a practical baseline.
cd /var/www/mern-app/backend
git pull
npm install
pm2 restart mern-api
cd /var/www/mern-app/frontend
git pull
npm install
npm run build
sudo systemctl reload nginx- Keep backend and frontend update steps separate
- Restart PM2 after backend changes
- Rebuild frontend after frontend changes
Common MERN Production Problems
If the frontend loads but API requests fail, the first thing to check is whether the frontend is pointing to the correct production API base URL. Many MERN deployment bugs are simply environment mismatches between frontend and backend.
If Nginx returns 502, the Express API is either not running, not listening on the expected port, or crashing under PM2. If MongoDB connection errors appear in the API logs, focus on the MONGO_URI, database access rules, and whether MongoDB is reachable from the backend server.
The fastest debugging order is: PM2 logs, backend env values, MongoDB connectivity, then Nginx logs.
pm2 list
pm2 logs mern-api
sudo nginx -t
sudo tail -f /var/log/nginx/error.logBest Next Steps After the Initial Setup
Once the app is running, the next improvements should be operational, not decorative. Add backups, uptime checks, log monitoring, and a rollback habit. If the app starts receiving meaningful traffic, move MongoDB to a managed environment or at least separate it from the web layer if possible.
If you want to keep building your deployment knowledge, the best related reads are your Next.js deployment guide, campaign analytics resources, and tracking workflow pages so infrastructure and product growth stay aligned.
- Next.js deployment guide: /blog/how-to-deploy-nextjs-project-on-ubuntu-24
- Blog hub: /blog
- Campaign tracking SaaS page: /campaign-tracking-saas
- Link tracking software page: /link-tracking-software
- UTM builder tool: /utm-builder-tool
FAQ
What is the best MERN production setup?
A strong baseline is a built React frontend served by Nginx, an Express API managed by PM2, MongoDB as the database layer, and Ubuntu as the host environment.
Should the React frontend run with PM2 in production?
Usually no. In many MERN setups, the frontend is built into static files and served directly by Nginx, while PM2 is used for the backend API.
Why does my MERN app return 502 Bad Gateway?
Most often because the Express API is not running correctly under PM2 or Nginx is proxying to the wrong backend port.
Can MongoDB run on the same Ubuntu server?
Yes, especially for smaller deployments, but managed MongoDB or a separate database layer is usually safer for production growth.
What should I secure first in a MERN production setup?
Start with environment variables, HTTPS, basic firewall rules, database access, and stable PM2 plus Nginx configuration.
Related free tools
If you want to turn this topic into action, use one of ShortIQ's free tools for campaign planning, UTM structure, or QR distribution.
Continue Reading
Explore more guides on link shortener SaaS strategy, Bitly alternatives, and white label link management.