简介:本文详细介绍如何通过Docker与Nginx实现二级域名访问多个Web项目,涵盖容器化部署、Nginx反向代理配置及域名解析优化,助力开发者高效管理多项目网络架构。
在微服务架构和DevOps实践中,开发者常需在同一服务器上部署多个Web项目(如前端应用、API服务、后台管理系统等)。传统方式需为每个项目配置独立端口,导致访问路径复杂(如http://ip:8080、http://ip:8081)。通过二级域名(如api.example.com、admin.example.com)访问可显著提升用户体验和系统可维护性。
核心需求:
# 安装必要工具sudo apt updatesudo apt install -y docker.io docker-compose nginx# 验证安装docker --versionnginx -v
以两个Node.js项目为例:
项目1(api.example.com):
# api-service/DockerfileFROM node:16-alpineWORKDIR /appCOPY package*.json ./RUN npm installCOPY . .EXPOSE 3000CMD ["npm", "start"]
项目2(admin.example.com):
# admin-panel/DockerfileFROM node:16-alpineWORKDIR /appCOPY package*.json ./RUN npm install --productionCOPY . .EXPOSE 3001CMD ["node", "server.js"]
构建镜像:
docker build -t api-service ./api-servicedocker build -t admin-panel ./admin-panel
创建/etc/nginx/conf.d/multi-project.conf:
# 主服务器配置server {listen 80;server_name example.com;return 301 https://$host$request_uri;}# API服务代理server {listen 443 ssl;server_name api.example.com;ssl_certificate /etc/nginx/ssl/fullchain.pem;ssl_certificate_key /etc/nginx/ssl/privkey.pem;location / {proxy_pass http://api-service:3000;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}}# 管理后台代理server {listen 443 ssl;server_name admin.example.com;ssl_certificate /etc/nginx/ssl/fullchain.pem;ssl_certificate_key /etc/nginx/ssl/privkey.pem;location / {proxy_pass http://admin-panel:3001;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_pass:指向Docker容器内部服务ssl_certificate:需提前准备Let’s Encrypt或其他证书proxy_set_header:确保真实IP和Host头信息传递创建docker-compose.yml:
version: '3.8'services:api-service:image: api-service:latestrestart: unless-stoppednetworks:- webnetadmin-panel:image: admin-panel:latestrestart: unless-stoppednetworks:- webnetnginx-proxy:image: nginx:alpineports:- "80:80"- "443:443"volumes:- ./nginx.conf:/etc/nginx/conf.d/multi-project.conf- /etc/letsencrypt:/etc/nginx/ssldepends_on:- api-service- admin-panelnetworks:- webnetnetworks:webnet:driver: bridge
在DNS管理界面添加:
api → 指向服务器IPadmin → 指向服务器IP*.example.com
# docker-compose.yml 增强示例services:api-service:healthcheck:test: ["CMD", "curl", "-f", "http://localhost:3000/health"]interval: 30stimeout: 10sretries: 3
# Nginx性能优化配置worker_processes auto;worker_rlimit_nofile 100000;events {worker_connections 4000;use epoll;multi_accept on;}http {sendfile on;tcp_nopush on;tcp_nodelay on;keepalive_timeout 65;types_hash_max_size 2048;client_max_body_size 20m;}
server_tokens off;
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;server {location / {limit_req zone=one burst=5;}}
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
现象:Nginx无法代理到容器服务
排查步骤:
docker network inspect webnetdocker psdocker exec -it nginx-proxy sh → curl http://api-service:3000解决方案:
sudo certbot --nginx -d api.example.com -d admin.example.com
sudo certbot renew --dry-run
工具推荐:
location /nginx_status {stub_status on;access_log off;allow 127.0.0.1;deny all;}
docker statsab -n 1000 -c 100 http://api.example.com/
# .gitlab-ci.yml 示例stages:- build- deploybuild_api:stage: buildscript:- docker build -t api-service:$CI_COMMIT_SHA ./api-service- docker push api-service:$CI_COMMIT_SHAdeploy_production:stage: deployscript:- docker stack deploy -c docker-compose.prod.yml my_stackenvironment:name: productionurl: https://api.example.com
建议采用以下目录结构:
.├── environments/│ ├── prod/│ │ ├── docker-compose.yml│ │ └── nginx.conf│ ├── staging/│ │ └── ...│ └── dev/│ └── ...└── projects/├── api-service/└── admin-panel/
<项目>-<环境>格式(如api-prod)通过本方案实现的二级域名访问架构,可支持横向扩展至数十个Web项目,同时保持99.9%以上的可用性。实际生产环境中,建议结合Kubernetes实现更高级的编排能力,但对于中小型项目,本文介绍的Docker+Nginx组合已能提供卓越的性价比。