多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

