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

多Docker Compose文件下Nginx无法自动更新容器IP的问题求助

问题描述

我有两个独立的Docker项目,分别位于caipora/和classificacao/目录下,各自包含docker-compose.yml文件。

caipora项目配置

docker-compose.yml

version: '3.5'
networks:
    pge:
      name: pge
      driver: bridge

services:
  
  caipora:
    build:
      context: ./caipora-sso/build/docker/
    container_name: caipora
    restart: unless-stopped
    volumes:
      - ./data/caipora:/caipora
    networks:
      - pge

  proxy:
    image: nginx
    container_name: proxy
    mem_limit: 128m
    restart: unless-stopped
    volumes:
        - ./config/nginx.conf:/etc/nginx/nginx.conf
        - ./config/nginx.htpasswd:/etc/nginx/conf.d/nginx.htpasswd 
    ports:
        - 80:80
        - 443:443
    networks:
      - pge            

nginx.conf

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    upstream lineu{
        server frontend:3000;
    }
    upstream default{
        server caipora:8080;
    }
    server {

     listen *:80  default_server; 
     server_name homologacao.sistemas.pge.pi.gov.br;
    client_max_body_size 0;

    set  $allowOriginSite *;
    add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
    if_modified_since off;
    expires off;
    etag off;

    root /var/www/html;
    location ~ \.php$ {
        return 404;
    }

    location /.well-known/acme-challenge/ {
        autoindex on;
        root /var/www/certbot;
    }

    location /lineu {
        proxy_pass         http://lineu/;
        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;
    }
    location / {

        set $accept_language "pt-br";
        proxy_pass         http://default;
        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;
    }
}
    }
}

classificacao项目配置

docker-compose.yml

version: '3.5'
networks:
    pge:
      name: pge
      external: true

services:
  frontend:
    build:
      context: ./classificacao-frontend
    container_name: frontend
    restart: unless-stopped
    networks:
      - pge

问题详情

初始状态下,proxy容器能正常通过容器名frontend解析到对应IP,将/lineu路径反向代理到frontend容器。但重启frontend容器或整个classificacao项目后,frontend的IP会变更,而proxy容器仍保留旧的IP解析结果,只有重启proxy容器才能恢复正常访问。

需要无需合并两个docker-compose.yml文件的解决方案,比如实现frontend重启时自动重启proxy,或者让proxy能自动感知frontend的IP变化。

解决方案

方法1:修改Nginx配置,动态刷新DNS解析

Nginx默认会长期缓存DNS解析结果,导致容器IP变更后无法及时更新。可以利用Docker内置的DNS服务器(地址为127.0.0.11),在Nginx配置中缩短DNS缓存有效期:

全局配置(推荐)

在nginx.conf的http块中添加以下配置:

http {
    resolver 127.0.0.11 valid=1s;
    # 其他原有配置...
}

valid=1s表示DNS缓存有效期设为1秒,Nginx会每隔1秒重新解析一次容器域名,能快速感知frontend的IP变化。

针对特定上游服务配置

如果只想对lineu这个上游服务生效,可直接在upstream块中添加:

upstream lineu{
    server frontend:3000;
    resolver 127.0.0.11 valid=1s;
}

方法2:通过Docker Compose依赖关联实现自动重启

可以在caipora项目的docker-compose.yml中,给proxy服务添加对外部frontend容器的依赖,配合restart策略实现自动重启:

修改caipora/docker-compose.yml中的proxy服务:

proxy:
    image: nginx
    container_name: proxy
    mem_limit: 128m
    restart: always
    volumes:
        - ./config/nginx.conf:/etc/nginx/nginx.conf
        - ./config/nginx.htpasswd:/etc/nginx/conf.d/nginx.htpasswd 
    ports:
        - 80:80
        - 443:443
    networks:
      - pge
    depends_on:
      frontend:
        condition: service_started
    external_links:
      - frontend

注意:此方法需要Docker Compose版本3.9及以上,且需确保classificacao项目的frontend容器先启动。当frontend重启时,Docker会检测到依赖关系变化,自动重启proxy容器。

方法3:服务发现工具(适合复杂集群场景)

如果后续项目规模扩大,可引入Consul等服务发现工具,让Nginx通过服务发现动态获取容器的最新IP。不过该方案需要额外部署服务,小型项目推荐优先使用方法1。

内容的提问来源于stack exchange,提问作者Sergio Baiao

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 20:53:20