两个独立Docker Compose项目如何配置Nginx实现同域名同服务器共存
部署问题解决方案
根因说明
- 两个项目各自启动的Nginx容器均绑定宿主机
80:80、443:443端口,同一宿主机端口无法被两个进程同时占用,因此触发443端口占用报错。 - 两个Nginx容器使用了相同的容器名
hnginx,Docker不允许同一主机下存在同名容器。 - 两套Nginx配置均监听同一域名的443端口,配置逻辑冲突。
核心部署思路
仅保留1个统一的Nginx网关对外暴露80/443端口,将两个项目的后端服务纳入同一Docker网络,通过路径规则区分请求转发到对应后端。
实施步骤
1. 清理原有冲突配置
- 删除myapi项目Compose文件中的
nginx服务块 - 删除django_web项目Compose文件中的
nginx服务块 - 提前创建统一Docker网络,供所有后端服务和网关通信:
docker network create shared_net - 调整两个项目的后端服务配置,将其接入统一网络:
示例myapi后端Compose片段:
示例django后端Compose片段(后端服务名可自定义,比如services: flaskapp2: # 原有构建、环境变量等配置保留 networks: - shared_net networks: shared_net: external: truedjango_app):services: django_app: # 原有构建、环境变量等配置保留 networks: - shared_net networks: shared_net: external: true
2. 配置统一Nginx网关
新建网关配置目录./gateway/conf.d,写入合并后的Nginx配置(约定API请求统一走/api/前缀,和Django前端路由区分):
upstream flask_server { server flaskapp2:8000; } upstream django_server { server django_app:8080; } # 80端口统一重定向到HTTPS server { listen 80; server_name www.example.com example.com; location / { return 301 https://$server_name$request_uri; } } # 443统一服务配置 server { listen 443 ssl; server_name www.example.com example.com; client_max_body_size 20M; # 统一SSL配置 ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # Django静态文件 location /static/ { alias /www/django_static/; } # WebSocket配置 location /websocket/ { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://django_server; } # API请求转发到myapi location /api/ { proxy_redirect off; 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-Host $server_name; proxy_no_cache 1; proxy_cache_bypass 1; # 如不需要保留/api前缀,可添加 rewrite ^/api/(.*)$ /$1 break; proxy_pass http://flask_server; } # 其余请求转发到django_web location / { proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://django_server; } }
3. 启动统一Nginx网关
编写网关的Compose文件./gateway/docker-compose.yml:
services: nginx_gateway: image: nginx:stable container_name: unified_nginx restart: always ports: - "80:80" - "443:443" volumes: - ./conf.d:/etc/nginx/conf.d - /etc/letsencrypt:/etc/letsencrypt/ # 挂载两个项目的静态、媒体文件目录 - /宿主机路径/django/static:/www/django_static/ - /宿主机路径/django/media:/www/django_media/ networks: - shared_net networks: shared_net: external: true
执行启动命令:docker-compose up -d
4. 验证配置
- 校验Nginx配置合法性:
docker exec unified_nginx nginx -t - 检查端口占用:仅网关进程绑定80、443端口即可
- 分别访问Django前端页面、API接口,确认转发正常
注意事项
- 两个项目的后端服务无需对外暴露宿主机端口,仅通过Docker内部网络通信即可,减少安全风险。
- 如现有API请求无统一
/api/前缀,需和前端、后端团队约定新增前缀,避免和Django路由冲突。 - 原有重复的
hnginx容器需手动删除,避免后续启动冲突。
内容的提问来源于stack exchange,提问作者ProcolHarum
相关产品推荐
相关产品推荐

