Sikau

Node.js · Day 17 · about 25 min

Running in production

Logs, health checks, graceful shutdown, processes and Docker.

It works on my machine…

Production servers restart, scale to several copies, and sit behind load balancers that ask "are you healthy?". A few conventions make Node apps behave well there.

Production habits

import express from "express";

const app = express();
const started = Date.now();

app.get("/health", (req, res) => {
  res.json({ status: "ok", uptimeSeconds: Math.round((Date.now() - started) / 1000) });
});

const server = app.listen(Number(process.env.PORT ?? 3000), () => {
  console.log(JSON.stringify({ level: "info", msg: "server started", port: 3000 }));
});

process.on("SIGTERM", () => {
  console.log(JSON.stringify({ level: "info", msg: "shutting down" }));
  server.close(() => process.exit(0));
});

console.log(await (await fetch("http://localhost:3000/health")).json());
  • Run with NODE_ENV=production; a process manager (PM2, systemd) or the platform restarts crashed apps.
  • Use every CPU core with several instances (PM2 cluster mode, containers) — Node is single-threaded per process.
  • Docker: package the app with its exact Node version; deploy the same image everywhere (DevOps course).
  • Platforms: Render, Railway, Fly.io, AWS, or a VPS behind a reverse proxy like Nginx.
FROM node:24-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", "server.js"]

The rest of this lesson

  • Graceful shutdownexplain
  • Logs you can useexplain
  • Why /health?predict
  • On SIGTERMorder
  • Production practicematch
  • Badge quizquiz
  • What you learnedrecap

Continue this lesson free — run real code in your browser

Continue with Google

See all 18 lessons of Node.js