Skip to content

1.单容器部署方式(nginx作为镜像的一部分)

Nginx作为应用内静态服务器, 打包进 Dockerfile。使用场景:

  • 简单的静态网站
  • 单页应用(SPA)
  • 文档站点(如 Vitepress)
    dockerFile:
shell
# 适用于:单个前端项目的容器化

FROM nginx:alpine
COPY dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80

#多阶段
FROM node:18-alpine as builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80

这里nginx是作为镜像的一部分,而不是独立服务。
docker-compose.yml:

yml
services:
  vitepress:
    build: .
    ports:
      - "80:80"
    # 没有独立的nginx服务定义

这种单容器架构的好处:

  • 简化部署:只有一个容器需要管理
  • 资源高效:减少容器间通信开销
  • 易于维护:所有配置在一个镜像中
  • 端口映射简单:直接映射主机端口到容器

2.多容器部署(nginx作为独立容器部署)

Nginx 作为 API 网关/反向代理,独立服务部署。
docker-compose.yml:

yml
# 这种需要两个容器
services:
  nginx:
    image: nginx:alpine
    volumes:
      - ./dist:/usr/share/nginx/html
    ports:
      - "80:80"
  
  # 如果有构建过程,还需要build服务
  builder:
    build: .
    volumes:
      - ./dist:/app/dist

# 或
services:
  # 独立的 Nginx 网关
  nginx-gateway:
    image: nginx:alpine
    container_name: api-gateway
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/ssl:/etc/nginx/ssl
      - ./logs/nginx:/var/log/nginx
    networks:
      - backend
    depends_on:
      - service-a
      - service-b
      - service-c

  # 微服务 A
  service-a:
    build: ./services/service-a
    networks:
      - backend

  # 微服务 B  
  service-b:
    build: ./services/service-b
    networks:
      - backend

Nginx 作为负载均衡器,必须独立部署。

yml
services:
  # 负载均衡器
  nginx-lb:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx/lb.conf:/etc/nginx/nginx.conf
    networks:
      - backend

  # 服务实例(多个)
  app-server-1:
    build: .
    networks:
      - backend

  app-server-2:
    build: .
    networks:
      - backend

  app-server-3:
    build: .
    networks:
      - backend


# 或
services:
  # 独立网关 - 处理所有流量路由
  gateway:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./gateway/config:/etc/nginx/conf.d
    networks:
      - frontend
      - backend
    depends_on:
      - frontend-app
      - backend-api

  # 前端应用(单页应用)
  frontend-app:
    build:
      context: ./frontend
      dockerfile: Dockerfile  # 包含 Nginx
    networks:
      - frontend

  # 后端 API 服务
  backend-api:
    build:
      context: ./backend
      dockerfile: Dockerfile  # 不含 Nginx,如 Node.js/Java
    networks:
      - backend
    environment:
      - DB_HOST=mysql
      - REDIS_HOST=redis

  # 共享中间件
  mysql:
    image: mysql:8.0
    networks:
      - backend

  redis:
    image: redis:alpine
    networks:
      - backend

networks:
  frontend:
  backend:

3.部署建议

如果项目稳定,可以考虑:

  • 1.使用多阶段构建优化镜像大小
dockerfile
# 第一阶段:构建VitePress
FROM node:alpine as builder
WORKDIR /app
COPY . .
RUN npm install && npm run build

# 第二阶段:部署
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
  • 2.添加健康检查
yml
services:
  vitepress:
    build: .
    ports:
      - "80:80"
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost"]
      interval: 30s
      timeout: 10s
      retries: 3

4.生产环境最佳实践

混合部署策略:

yml
services:
  # 1. 外部访问网关(独立)
  ingress-nginx:
    image: nginx:alpine
    container_name: ingress
    ports:
      - "443:443"
    volumes:
      - ./nginx/ingress.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/nginx/ssl
      - ./logs:/var/log/nginx
    networks:
      - ingress-net
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "nginx", "-t"]
      interval: 30s
      timeout: 10s

  # 2. 前端应用服务(容器内包含 Nginx)
  admin-panel:
    build: ./apps/admin
    networks:
      - ingress-net
    environment:
      - API_URL=http://api-gateway
    # 这个服务的 Dockerfile 包含 Nginx

  # 3. API 网关(独立)
  api-gateway:
    image: nginx:alpine
    container_name: api-gateway
    volumes:
      - ./api-gateway/routes:/etc/nginx/conf.d
    networks:
      - ingress-net
      - internal-net
    depends_on:
      - user-service
      - order-service

  # 4. 后端微服务(不包含 Nginx)
  user-service:
    build: ./services/user
    networks:
      - internal-net
    expose:
      - "3000"

  order-service:
    build: ./services/order
    networks:
      - internal-net
    expose:
      - "3000"

Nginx 网关配置:

shell
# ./nginx/ingress.conf
upstream admin_panel {
    server admin-panel:80;
}

upstream api_gateway {
    server api-gateway:80;
}

server {
    listen 443 ssl;
    server_name example.com;

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

    # 管理面板
    location /admin {
        proxy_pass http://admin_panel;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # API 请求
    location /api {
        proxy_pass http://api_gateway;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

Released under the MIT License.