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 \
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
buildStep 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:3000Multi-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 /app/dist ./dist
COPY /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