Skip to content

Deploying Node.js Applications

Getting a Node.js app running on your machine is only step one, deploying it reliably to production involves process management, configuration, and choosing the right hosting approach. This lesson covers the essentials.

What Production Deployment Actually Requires

A production Node.js deployment needs more than node index.js running in a terminal: the process must restart automatically if it crashes, environment-specific configuration must be injected securely, logs must go somewhere durable, and the app must handle graceful shutdowns during deploys.

Most of these concerns are solved by either a process manager (like PM2) running directly on a server, or a containerized approach (Docker) deployed to a platform (Railway, Render, Fly.io, AWS, and others) that handles restarts, scaling, and health checks for you.

# Using PM2 as a process manager
npm install -g pm2

pm2 start index.js --name my-api
pm2 logs my-api
pm2 restart my-api
pm2 startup   # configure PM2 to start on server boot

PM2 automatically restarts your app if it crashes, manages logs, and can run multiple instances (similar in spirit to clustering) with a single command.

A Minimal Production Dockerfile

FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]
  • Use a specific Node.js version tag (node:22-alpine), not latest, for reproducible builds.
  • Copy package*.json and run npm ci before copying the rest of the source, to leverage Docker's layer caching.
  • --omit=dev skips installing development-only dependencies in the production image.
  • EXPOSE documents the port; the platform or orchestrator still needs to map it externally.

Deployment Cheatsheet

Common approaches for getting a Node.js app into production.

Approach Good For
PM2 on a VM Simple deployments, small teams, direct server control
Docker + a PaaS Reproducible builds, easy scaling, managed infrastructure
Kubernetes Large-scale, multi-service deployments needing fine control
Serverless (Lambda, etc.) Sporadic traffic, pay-per-invocation workloads
Managed Node.js hosts Fastest path to production for smaller apps

Graceful Shutdown During Deploys

When a new deploy replaces a running instance, the old process typically receives a SIGTERM signal. Handling it properly, stopping new connections, finishing in-flight requests, then exiting, avoids dropped requests during every single deploy.

process.on('SIGTERM', () => {
  console.log('SIGTERM received, shutting down gracefully');
  server.close(() => {
    db.disconnect();
    process.exit(0);
  });
});

Health Check Endpoints

Most hosting platforms and orchestrators expect a health check endpoint (commonly /health or /healthz) to confirm the app is running correctly before routing traffic to it, and to detect and restart unhealthy instances automatically.

app.get('/health', (req, res) => {
  res.status(200).json({ status: 'ok', uptime: process.uptime() });
});

Common Mistakes

  • Deploying without a process manager or restart policy, letting a crash take down the app indefinitely.
  • Hardcoding configuration instead of injecting environment variables per deployment target.
  • Ignoring SIGTERM, causing dropped connections and failed requests during every deploy.
  • Using the node:latest Docker tag, risking unpredictable builds as the underlying image changes over time.

Key Takeaways

  • Production deployment requires automatic restarts, secure configuration, and durable logging, beyond just running the app.
  • Process managers (PM2) or containerized platforms both solve most of these concerns out of the box.
  • Graceful shutdown (SIGTERM handling) prevents dropped requests during deploys.
  • Health check endpoints let platforms detect and route around unhealthy instances automatically.

Pro Tip

Add a /health endpoint and proper SIGTERM handling to every project before its very first deploy, not after the first production incident caused by their absence. Both take only a few minutes to implement and are expected by nearly every modern hosting platform.