You need to enable JavaScript to run this app. 两个独立Docker Compose项目如何配置Nginx实现同域名同服务器共存
优惠活动
大模型
产品
解决方案
定价
更多

两个独立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片段:
    services:
      flaskapp2:
        # 原有构建、环境变量等配置保留
        networks:
          - shared_net
    networks:
      shared_net:
        external: true
    
    示例django后端Compose片段(后端服务名可自定义,比如django_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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 09:45:01