Deploying a Node.js application to production requires more than just running node app.js. This guide covers everything from initial setup to a production-ready deployment with process management, reverse proxy, and SSL.
sudo apt update && sudo apt upgrade -y
# Install Node.js 20.x LTS
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
# Verify installation
node --version
npm --version
sudo adduser deploy
sudo usermod -aG sudo deploy
su - deploy
cd ~
git clone https://github.com/yourusername/your-app.git
cd your-app
From your local machine:
scp -r ./your-app deploy@your_server_ip:~/
cd ~/your-app
npm install --production
nano .env
Add your environment variables:
NODE_ENV=production
PORT=3000
DATABASE_URL=your_database_url
SECRET_KEY=your_secret_key
chmod 600 .env
PM2 keeps your app running and restarts it on crashes.
sudo npm install -g pm2
pm2 start app.js --name "my-app"
# Or with npm script
pm2 start npm --name "my-app" -- start
Create ecosystem.config.js:
module.exports = {
apps: [{
name: 'my-app',
script: 'app.js',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
}
}]
};
Start with config:
pm2 start ecosystem.config.js --env production
pm2 startup
pm2 save
pm2 list # List all processes
pm2 logs my-app # View logs
pm2 monit # Monitor resources
pm2 restart my-app # Restart app
pm2 stop my-app # Stop app
pm2 delete my-app # Remove from PM2
Nginx handles incoming requests and forwards them to your Node.js app.
sudo apt install nginx
Create configuration file:
sudo nano /etc/nginx/sites-available/my-app
Add configuration:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
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_cache_bypass \$http_upgrade;
}
}
sudo ln -s /etc/nginx/sites-available/my-app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP' # After SSL setup
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Certbot sets up auto-renewal automatically. Test it:
sudo certbot renew --dry-run
Add to /etc/nginx/nginx.conf:
http {
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
# Connection settings
keepalive_timeout 65;
client_max_body_size 10M;
}
In your app, ensure:
// Trust proxy for correct IP detection
app.set('trust proxy', 1);
// Helmet for security headers
const helmet = require('helmet');
app.use(helmet());
// Compression
const compression = require('compression');
app.use(compression());
pm2 monit
pm2 logs my-app --lines 100
htop
cd ~/your-app
git pull origin main
npm install --production
pm2 restart my-app
Create deploy.sh:
#!/bin/bash
cd ~/your-app
git pull origin main
npm install --production
npm run build # If you have a build step
pm2 restart my-app
echo "Deployment complete!"
Make executable:
chmod +x deploy.sh
Check PM2 logs:
pm2 logs my-app --err
pm2 listsudo tail -f /var/log/nginx/error.logsudo certbot certificatesYour Node.js application is now running in production with:
VexaNode VPS provides the perfect infrastructure for Node.js deployments with fast NVMe storage, reliable uptime, and easy scaling options.
Join thousands of satisfied users and experience the VexaNode difference today.
View Plans