Nodejs Deployment
title: Node.js Deployment — Complete Guide to Deploying Node.js to Production description: 'Learn Node.js deployment: process managers, environment configuration, CI/CD pipelines, monitoring, logging, load balancing, and cloud platform deployment.' date: 2026-06-28 lastmod: 2026-06-28 weight: 41 tags: [backend, nodejs]
Node.js deployment involves preparing applications for production, configuring process managers, setting up CI/CD, monitoring performance, and deploying to cloud platforms reliably.
## What You'll Learn
By the end of this tutorial, you'll use PM2 for process management, configure environment-specific settings, set up GitHub Actions CI/CD, implement monitoring with logging, and deploy to cloud platforms.
## Why Deployment Matters
Development is half the work. Deploying reliably, monitoring health, and handling failures in production separates professional applications from hobby projects.
## Real-World Use
A production Node.js API runs under PM2 with 4 instances, automatic restart on crash, log rotation, and health checks. GitHub Actions runs tests and deploys to AWS Elastic Beanstalk on every merge.
## Deployment Learning Path
```mermaid
flowchart LR
A[Docker] --> B[Deployment]
B --> C[DevOps]
C --> D[Production]
D --> E[Next Steps]
A --> F{You Are Here}
style F fill:#f90,color:#fff
PM2 Process Manager
npm install -g pm2
// ecosystem.config.js
module.exports = {
apps: [{
name: "api-server",
script: "server.js",
instances: "max", // Use all CPU cores
exec_mode: "cluster", // Cluster mode for load balancing
env: { NODE_ENV: "development" },
env_production: { NODE_ENV: "production" },
max_memory_restart: "500M",
log_date_format: "YYYY-MM-DD HH:mm:ss",
error_file: "./logs/error.log",
out_file: "./logs/output.log",
merge_logs: true
}]
};
Environment Configuration
// config.js
const config = {
development: {
port: 3000,
databaseUrl: "postgresql://localhost:5432/dev",
logLevel: "debug"
},
production: {
port: parseInt(process.env.PORT, 10) || 8080,
databaseUrl: process.env.DATABASE_URL,
logLevel: "info"
}
};
export default config[process.env.NODE_ENV || "development"];
Health Check Endpoint
app.get("/health", (req, res) => {
const health = {
status: "ok",
timestamp: new Date().toISOString(),
uptime: process.uptime(),
memory: process.memoryUsage(),
pid: process.pid
};
res.json(health);
});
CI/CD with GitHub Actions
name: Deploy
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: "22" }
- run: npm ci
- run: npm test
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to production
run: |
echo "Deploying to production server..."
# rsync, SSH, or platform CLI
Monitoring and Logging
pm2 monit # Real-time monitoring
pm2 logs # View logs
pm2 status # Process status
pm2 show api-server # Detailed info
Deployment Platforms
// Platform-specific adjustments
// Heroku: process.env.PORT is provided
// AWS: Use Elastic Beanstalk or ECS
// DigitalOcean: App Platform or Droplets
// Railway/Vercel: Zero-config Node.js hosting
const PORT = process.env.PORT || 3000;
app.listen(PORT, "0.0.0.0", () => {
console.log(`Server running on port ${PORT}`);
});
Common Mistakes
1. Hardcoding Port or Host
Use process.env.PORT and bind to 0.0.0.0. Cloud platforms assign ports dynamically.
2. No Graceful Shutdown
Not handling SIGTERM causes dropped connections. Listen for shutdown signals and close connections gracefully.
3. Running as Root
Never run Node.js as root. Create a dedicated user or use process managers that drop privileges.
4. No Log Rotation
Without rotation, log files grow indefinitely filling disk space. Configure PM2 log rotation or use external logging.
5. Not Monitoring Application Health
Without health checks and monitoring, you won't know the app is down until users complain.
Practice Questions
1. What is PM2 and why use it?
PM2 is a production process manager that keeps apps alive forever, reloads without downtime, manages logs, and provides monitoring.
2. How do you implement zero-downtime deployment?
Use PM2 in cluster mode with --reload instead of --restart. Reload restarts workers one by one without dropping connections.
3. How do you handle environment-specific configuration?
Use NODE_ENV variable and load the appropriate config file. Never hardcode production credentials in code.
4. What is a graceful shutdown?
Listening for SIGTERM/SIGINT, stopping accepting new requests, finishing in-flight requests, closing DB connections, then exiting.
5. Challenge: Create a deployment-ready Node.js server with health check, graceful shutdown, and PM2 config.
const server = app.listen(PORT, () => console.log(`Running on ${PORT}`));
process.on("SIGTERM", () => {
console.log("SIGTERM received. Shutting down...");
server.close(() => process.exit(0));
});
FAQ
Mini Project: Production-Ready Express Server
Create a deployment-ready Express server with graceful shutdown and health checks.
import express from "express";
const app = express();
app.get("/health", (req, res) => res.json({ status: "ok", uptime: process.uptime() }));
const server = app.listen(process.env.PORT || 3000, "0.0.0.0", () => {
console.log(`Server running in ${process.env.NODE_ENV} mode`);
});
const shutdown = (signal) => {
console.log(`${signal} received. Shutting down gracefully...`);
server.close(() => {
console.log("HTTP server closed");
process.exit(0);
});
setTimeout(() => process.exit(1), 10000);
};
process.on("SIGTERM", () => shutdown("SIGTERM"));
process.on("SIGINT", () => shutdown("SIGINT"));
What's Next
Docker Compose CI/CD Pipeline Express Security
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro