Taking your Node.js application from development to production requires careful planning. This guide covers all major deployment approaches with best practices for each.
1. Deployment Target Options
Traditional Servers
- DigitalOcean/Linode droplets
- AWS EC2 instances
- Bare metal servers
- Full control
- More maintenance
Platform as a Service
- Heroku
- Render
- AWS Elastic Beanstalk
- Simpler setup
- Less control
Serverless
- AWS Lambda
- Vercel
- Google Cloud Functions
- Auto-scaling
- Cold starts
2. Preparing for Deployment
Environment Configuration
// Use dotenv for local development
require('dotenv').config();
// production.js
module.exports = {
port: process.env.PORT || 3000,
db: {
uri: process.env.DB_URI,
options: {
poolSize: 10,
useNewUrlParser: true
}
},
jwtSecret: process.env.JWT_SECRET
};
// Load config based on NODE_ENV
const config = require(`./${process.env.NODE_ENV || 'development'}`);
Production Dependencies
{
"dependencies": {
"express": "^4.17.1",
"mongoose": "^6.0.12"
},
"devDependencies": {
"nodemon": "^2.0.15",
"jest": "^27.4.7"
},
"engines": {
"node": ">=16.0.0",
"npm": ">=8.0.0"
}
}
3. Process Management
PM2 (Recommended)
# Install globally
npm install -g pm2
# Start application
pm2 start app.js --name "my-app"
# Common commands
pm2 list # View processes
pm2 logs my-app # View logs
pm2 restart my-app # Restart
pm2 delete my-app # Stop and remove
# Cluster mode (utilize all CPUs)
pm2 start app.js -i max
# Save process list
pm2 save
pm2 startup # Generate startup script
Systemd (Linux)
# /etc/systemd/system/myapp.service
[Unit]
Description=My Node.js App
After=network.target
[Service]
User=nodeuser
WorkingDirectory=/var/www/myapp
Environment=NODE_ENV=production
ExecStart=/usr/bin/node /var/www/myapp/app.js
Restart=always
[Install]
WantedBy=multi-user.target
# Commands
sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl enable myapp
4. Deployment to Heroku
Step-by-Step Process
- Install Heroku CLI
- Create
Procfile
:web: node app.js
- Configure database addons
- Set environment variables:
heroku config:set JWT_SECRET=supersecret
- Deploy:
git push heroku main
Heroku-Specific Tips
- Use
process.env.PORT
(Heroku assigns port dynamically) - Add
engines
to package.json - Use Heroku Postgres/MongoDB Atlas for databases
- Configure log drains for production logging
5. Deployment to AWS
EC2 Deployment
- Launch EC2 instance (Ubuntu recommended)
- Install Node.js, PM2, NGINX
- Clone your repository
- Configure NGINX as reverse proxy:
server { listen 80; server_name 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_cache_bypass $http_upgrade; } }
- Set up SSL with Let’s Encrypt
Elastic Beanstalk
- Install EB CLI
- Initialize EB:
eb init -p node.js my-app
- Create environment:
eb create my-app-env
- Configure
.ebextensions
:# .ebextensions/nodecommand.config option_settings: aws:elasticbeanstalk:container:nodejs: NodeCommand: "npm start"
- Deploy:
eb deploy
6. Serverless Deployment
AWS Lambda with API Gateway
// serverless.yml
service: my-node-app
provider:
name: aws
runtime: nodejs14.x
region: us-east-1
functions:
app:
handler: app.handler
events:
- http: ANY /
- http: ANY /{proxy+}
# Install Serverless Framework
npm install -g serverless
# Deploy
sls deploy
Vercel Deployment
- Install Vercel CLI
- Create
vercel.json
:{ "version": 2, "builds": [ { "src": "app.js", "use": "@vercel/node" } ], "routes": [ { "src": "/(.*)", "dest": "app.js" } ] }
- Deploy:
vercel --prod
7. Zero-Downtime Deployments
Blue-Green Deployment
- Maintain two identical production environments
- Deploy new version to inactive environment
- Test new version thoroughly
- Switch traffic to new environment
- Keep old environment for rollback
PM2 Graceful Reload
# Install PM2 module for graceful reloads
pm2 install pm2-intercom
# Reload application with zero downtime
pm2 reload app
# Or with cluster mode
pm2 reload app --update-env
Next: Performance Optimization →
Deployment Checklist
- ✅ Environment variables properly set
- ✅ Database connection configured
- ✅ Process manager running
- ✅ Reverse proxy/load balancer configured
- ✅ SSL certificates installed
- ✅ Monitoring and alerts set up
- ✅ Backup strategy in place