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:
- backendNginx 作为负载均衡器,必须独立部署。
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: 34.生产环境最佳实践
混合部署策略:
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";
}
}