Docker Tutorials

Containerizing a Node.js App

30 min

Containerizing a Node.js App

Containerizing a Node.js Application

Overview

Learn how to containerize a Node.js application with best practices and optimization techniques.


Step 1: Create Dockerfile

dockerfile
FROM node:18-alpine

WORKDIR /app

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm ci --only=production

# Copy application code
COPY . .

# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001
USER nodejs

EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD node healthcheck.js || exit 1

CMD ["npm", "start"]

Step 2: Create .dockerignore

text
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
.DS_Store
dist
build

Step 3: Build Image

bash
# Build image
docker build -t my-node-app:1.0 .

# Run container
docker run -d -p 3000:3000 my-node-app:1.0

# Verify
curl http://localhost:3000

Multi-Stage Build Example

dockerfile
# Build stage
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
USER node
EXPOSE 3000
CMD ["npm", "start"]

Docker Compose Example

yaml
version: "3.8"

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      NODE_ENV: production
      DATABASE_URL: postgres://user:pass@db:5432/myapp
    depends_on:
      db:
        condition: service_healthy
    volumes:
      - ./logs:/app/logs

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  db-data:

Best Practices

✅ Node.js Containerization Best Practices

✅ DO Use Alpine base image for smaller size
Alpine images are 5-10x smaller than regular Node images
✅ DO Use npm ci instead of npm install
npm ci is faster and more reliable for CI/CD environments
✅ DO Run as non-root user
Improves security by limiting container privileges
✅ DO Use multi-stage builds
Separate build and runtime environments for smaller images
✅ DO Include health checks
Enable container health monitoring for production
❌ DON'T Use latest tag
Specify exact versions for reproducible builds
❌ DON'T Include node_modules in COPY
Use .dockerignore to exclude node_modules and let npm install them

Next Steps

Press j for next, k for previous