将 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;
}
}
相关阅读
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。