Docker 部署 Node.js:Express / Nest.js 后端服务的容器化实战

详解 Node.js 后端服务(Express / Nest.js / Fastify)的 Docker 容器化:多阶段构建减小镜像、PM2 进程管理、Nginx 反向代理、环境变量安全注入、docker-compose 编排 API + 数据库 + Redis 全栈。

将 Node.js 应用 Docker 化是生产部署的最佳实践:保证开发/生产环境一致、简化部署流程、方便扩缩容。本文覆盖 Express、Nest.js、Fastify 三大主流框架的容器化方案。


一、Express.js 的 Docker 化

1.1 项目结构

my-api/
├── src/
│   ├── index.js
│   └── routes/
├── package.json
├── .env
└── Dockerfile

1.2 Dockerfile

# 构建阶段
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .

# 运行阶段
FROM node:20-alpine
WORKDIR /app
ENV NODE_ENV=production

# 创建非 root 用户
RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nodejs:nodejs /app/src ./src
COPY --from=builder --chown=nodejs:nodejs /app/package.json ./

USER nodejs
EXPOSE 3000
CMD ["node", "src/index.js"]

1.3 docker-compose.yml(API + Postgres + Redis)

version: '3.8'
services:
  api:
    build: .
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://postgres:${DB_PASSWORD}@db:5432/api
      REDIS_URL: redis://redis:6379
      JWT_SECRET: ${JWT_SECRET}
    depends_on:
      - db
      - redis

  db:
    image: postgres:15-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}

  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:

二、Nest.js 的 Docker 化

# Nest.js 编译为 JS 后运行
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
EXPOSE 3000
CMD ["node", "dist/main.js"]

三、PM2 在容器内的使用

FROM node:20-alpine
RUN npm install -g pm2
WORKDIR /app
COPY . .
EXPOSE 3000
CMD ["pm2-runtime", "start", "ecosystem.config.js"]
// ecosystem.config.js
module.exports = {
  apps: [{
    name: 'api',
    script: './src/index.js',
    instances: 'max',       // 使用所有 CPU 核心
    exec_mode: 'cluster',
    env: { NODE_ENV: 'production' }
  }]
};

四、Nginx 反向代理

# nginx.conf
upstream api {
    server api:3000;
}

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://api;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

相关阅读

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「saas」更多文章