Docker容器化部署Node.js应用最佳实践

Iniciado por joomlamz, 25 de Maio de 2026, 02:35

Respostas: 0   |   Visualizações: 12

Tópico anterior - Tópico seguinte

0 Membros e 1 Visitante estão a ver este tópico.

Docker容器化部署Node.js应用最佳实践



Tópico: Docker容器化部署Node.js应用最佳实践
Categoria: Tutoriais | Programação & Tecnologia
Idioma Principal: Português (Conteúdo de Tecnologia)

Descrição do Conteúdo / Informações:
-------------------------------------------------------------------------


Docker容器化部署Node.js应用最佳实践


Docker已成为现代应用部署的标准工具。本文将详细介绍如何将Node.js应用容器化,并分享生产环境的最佳实践。



项目准备




示例项目结构


my-node-app/
├── src/
│   ├── index.js
│   ├── routes/
│   └── controllers/
├── package.json
├── package-lock.json
├── .dockerignore
├── Dockerfile
└── docker-compose.yml



基础应用代码


// src/index.js
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
res.json({ message: 'Hello from Docker!', timestamp: new Date() });
});

app.get('/health', (req, res) => {
res.json({ status: 'healthy' });
});

app.listen(PORT, '0.0.0.0', () => {
console.log(`Server running on port ${PORT}`);
});



Dockerfile编写




基础版本


# 使用官方Node.js镜像
FROM node:20-alpine

# 设置工作目录
WORKDIR /app

# 复制依赖文件
COPY package*.json ./

# 安装依赖
RUN npm ci --only=production

# 复制源代码
COPY src/ ./src/

# 暴露端口
EXPOSE 3000

# 启动应用
CMD ["node", "src/index.js"]



生产级优化版本


# ==================== 构建阶段 ====================
FROM node:20-alpine AS builder

WORKDIR /app

# 复制依赖文件
COPY package*.json ./

# 安装所有依赖(包括devDependencies)
RUN npm ci

# 复制源代码
COPY . .

# 如果使用TypeScript,进行编译
# RUN npm run build

# ==================== 生产阶段 ====================
FROM node:20-alpine AS production

# 安全:使用非root用户
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodeapp -u 1001

WORKDIR /app

# 只复制生产依赖
COPY --from=builder --chown=nodeapp:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nodeapp:nodejs /app/package.json ./
COPY --from=builder --chown=nodeapp:nodejs /app/src ./src

# 切换到非root用户
USER nodeapp

# 环境变量
ENV NODE_ENV=production
ENV PORT=3000

EXPOSE 3000

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

# 启动应用
CMD ["node", "--max-old-space-size=512", "src/index.js"]



.dockerignore配置


# 依赖目录
node_modules
npm-debug.log

# Git
.git
.gitignore

# 测试
coverage
.nyc_output
*.test.js

# 文档
README.md
docs

# IDE
.idea
.vscode
*.swp

# 环境文件
.env
.env.local
.env.*.local

# Docker
Dockerfile
docker-compose*.yml
.dockerignore



Docker Compose配置




开发环境


# docker-compose.dev.yml
version: '3.8'

services:
app:
build:
context: .
target: builder
ports:
- "3000:3000"
volumes:
- ./src:/app/src
- ./package.json:/app/package.json
environment:
- NODE_ENV=development
command: npm run dev

mongodb:
image: mongo:7
ports:
- "27017:27017"
volumes:
- mongo_data:/data/db

volumes:
mongo_data:



生产环境


# docker-compose.prod.yml
version: '3.8'

services:
app:
build:
context: .
target: production
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- MONGODB_URI=mongodb://mongodb:27017/production
depends_on:
mongodb:
condition: service_healthy
restart: unless-stopped
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M

mongodb:
image: mongo:7
volumes:
- mongo_data:/data/db
healthcheck:
test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped

nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- app
restart: unless-stopped

volumes:
mongo_data:



Nginx反向代理配置


# nginx.conf
events {
worker_connections 1024;
}

http {
upstream app {
server app:3000;
keepalive 32;
}

server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}

server {
listen 443 ssl http2;
server_name example.com;

ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;

# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

location / {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}

location /health {
proxy_pass http://app/health;
access_log off;
}
}
}



常用命令




构建与运行


bash
# 构建镜像
docker build -t my-node-app:latest .

# 构建特定阶段
docker build --target production -t my-node-app:prod .

# 运行容器

---

📌 更多精彩内容,关注我的[博客](https://wdsega.github.io),每周更新!


Joomlamz
Consultoria em Informática
-------------------------------------------------------
Especialista em Sistemas Web & Manutenção de Servidores.
A desenvolver o novo AplPortal com suporte a PHP 8.
Precisa de ajuda profissional? Contacte-me.

Tags: