You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Docker Compose中为Nginx容器配置环境变量实现动态端口代理

Docker Compose + Nginx 多环境部署动态端口配置方案

问题场景

  • 项目采用CI/CD流程分开发(dev)、预发布(staging)、正式发布(release)三个阶段部署,每个阶段对应独立的docker-compose配置
  • 需要Nginx根据部署阶段将请求转发到对应API服务,写死静态端口会导致多环境并行启动时出现宿主机端口占用冲突
  • 预期效果:Nginx配置中proxy_pass的端口值可直接读取docker-compose为Nginx容器注入的API_PORT环境变量,不需要每次修改配置文件
  • 原有预期Nginx配置片段:
server {
    listen       443 ssl;

    ssl_certificate /etc/ssl/server/cert.pem;
    ssl_certificate_key /etc/ssl/server/privkey.pem;

    location / {
        proxy_pass https://api:$API_PORT;
        proxy_set_header Host $host;
        # 其余配置省略
    }
}
  • 原有docker-compose配置片段:
version: "3"

services:
  api:
    # 省略部分配置
    ports:
      - 4000:4000
  nginx:
    # 省略部分配置
    environment:
      - API_PORT=4000
    ports:
      - 5180:80
      - 5181:443

实现步骤

原生Nginx默认不支持直接读取系统环境变量替换配置内容,利用官方Nginx镜像自带的模板渲染能力就能实现需求,同时解决端口冲突问题:

  1. 调整Nginx配置为模板文件
    不要直接编写最终的default.conf,新建default.conf.template作为配置模板,内容和预期配置一致,仅把需要注入的端口变量改为${API_PORT}格式:
server {
    listen       443 ssl;

    ssl_certificate /etc/ssl/server/cert.pem;
    ssl_certificate_key /etc/ssl/server/privkey.pem;

    location / {
        proxy_pass https://api:${API_PORT};
        proxy_set_header Host $host;
        # 其余原有配置保持不变即可
    }
}

注意:模板中Nginx原生内置变量比如$host保持原有写法即可,渲染逻辑只会替换${变量名}格式的内容,不会误改Nginx自有变量。

  1. 调整docker-compose配置,解决端口冲突
    同一docker-compose下的服务默认走独立的内部隔离网络通信,API服务不需要把端口映射到宿主机就能被同compose下的Nginx访问,从根源避免多环境并行的宿主机端口冲突:
version: "3"

services:
  api:
    # 保留原有api服务的所有业务配置
    # 删除原有的ports映射到宿主机的配置,避免多环境启动时4000端口冲突
    expose:
      - "4000" # 仅声明容器内部监听端口,不映射到宿主机,无冲突风险
  nginx:
    image: nginx:stable-alpine # 直接使用官方稳定版镜像,自带模板渲染能力
    # 保留原有nginx的基础配置
    volumes:
      # 将配置模板挂载到官方镜像指定的模板扫描目录
      - ./default.conf.template:/etc/nginx/templates/default.conf.template:ro
      # 原有证书等文件挂载路径保持不变
      - ./your/ssl/path:/etc/ssl/server:ro
    environment:
      # 此处端口为API容器内部监听端口,所有环境统一写4000也不会冲突
      - API_PORT=4000
    ports:
      # 不同环境的compose文件仅需修改此处的宿主机端口即可,完全无冲突
      # 示例:dev用5180/5181,staging用6180/6181,release用7180/7181
      - "5180:80"
      - "5181:443"
    depends_on:
      - api

实现原理

官方Nginx镜像的内置入口脚本会在启动Nginx主进程前,自动扫描/etc/nginx/templates/目录下所有.template后缀的文件,通过envsubst工具将模板中${变量名}格式的内容替换为容器当前的环境变量值,最终生成的配置文件会自动输出到Nginx默认加载的/etc/nginx/conf.d/目录下,不需要自定义启动脚本,也不会破坏镜像原有启动逻辑。


内容的提问来源于stack exchange,提问作者Jancer Lima

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:42:09