如何使用多个docker-compose.yml文件配置Nginx统一代理多容器?
我之前折腾过这个场景,其实核心思路就是用Docker共享网络让独立的compose项目和全局Nginx容器互通,再通过Nginx反向代理把各个服务暴露出去。下面是一步步的实操方案,亲测靠谱:
核心方案概述
我们会创建一个全局的Docker网络,让所有需要对外暴露的服务容器和Nginx容器都加入这个网络;然后用一个单独的compose来管理全局Nginx,每个业务项目的compose只需要把服务接入这个共享网络,最后通过Nginx配置反向代理规则,把不同域名/路径指向对应的业务容器。
步骤1:创建全局共享网络
首先创建一个所有容器都能接入的全局网络,这样Nginx就能直接访问各个业务容器:
docker network create nginx-proxy
步骤2:部署全局Nginx容器
新建一个单独的目录(比如~/nginx-proxy),创建docker-compose.yml来管理全局Nginx,这样方便后续维护配置和证书:
version: '3.8' services: nginx: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./conf.d:/etc/nginx/conf.d # 挂载自定义配置目录 - ./certs:/etc/nginx/certs # 挂载HTTPS证书目录(可选) - ./html:/usr/share/nginx/html networks: - nginx-proxy restart: unless-stopped # 容器崩溃自动重启 networks: nginx-proxy: external: true # 指定使用我们之前创建的全局网络
然后启动Nginx:
docker-compose up -d
步骤3:配置业务项目的docker-compose.yml
每个业务项目的compose只需要把对外服务加入nginx-proxy网络,不需要再把端口暴露到宿主机(Nginx会通过共享网络访问)。比如一个电商项目的compose:
version: '3.8' services: e-commerce-api: image: my-ecommerce-api:v1.0 container_name: e-commerce-api # 固定容器名,方便Nginx配置里直接引用 networks: - default # 保留项目自身的私有网络 - nginx-proxy # 加入全局共享网络 # 这里不需要写ports: - "8080:8080",避免端口冲突 networks: nginx-proxy: external: true
启动这个业务项目:
docker-compose up -d
步骤4:配置Nginx反向代理规则
在~/nginx-proxy/conf.d目录下新建对应业务的配置文件,比如e-commerce.conf:
server { listen 80; server_name api.my-ecommerce.com; # 你的业务域名 location / { proxy_pass http://e-commerce-api:8080; # 用容器名+服务内部端口访问 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
修改配置后重启Nginx生效:
docker-compose -f ~/nginx-proxy/docker-compose.yml restart nginx
注意事项
- 容器名必须全局唯一,避免不同项目的容器名冲突;如果不想固定容器名,也可以用compose自动生成的服务名,格式是
项目目录名_服务名_1(比如e-commerce_e-commerce-api_1) - 如果需要HTTPS,可以用certbot工具生成证书,把证书文件放到
~/nginx-proxy/certs目录,然后修改Nginx配置监听443端口并指定证书路径 - 后续新增业务项目,只需要把服务加入
nginx-proxy网络,再新增对应的Nginx配置文件即可,完全不影响现有服务
这样一来,你就可以在同一服务器上运行多个独立的docker-compose项目,所有对外服务都通过这一个全局Nginx容器暴露,完美解决了单个compose作为服务器级配置的问题。
内容的提问来源于stack exchange,提问作者Harold Smith
相关产品推荐
相关产品推荐

