关键在于使用自定义bridge网络实现容器名直连与DNS自动解析:创建nginx-net网络,将Nginx和后端容器(如api-server)加入同一网络,Nginx配置中即可直接用proxy_pass http://api-server:8080,无需IP且支持自动更新解析。

用 Docker 部署 Nginx 实现容器间互联与服务发现,关键不在 Nginx 本身,而在于网络规划 + 容器命名 + DNS 自动解析。Docker 内置的 bridge 网络已支持容器名直连,配合自定义网络和合理配置,无需额外工具就能完成基础服务发现。
用自定义 bridge 网络打通容器通信
Docker 默认的 bridge 网络不支持容器名解析,必须创建自定义 bridge 网络才能启用内置 DNS 服务(即容器启动后自动注册名字,其他同网容器可直接用名字访问)。
- 创建专用网络:
docker network create nginx-net(不指定子网时 Docker 自动分配,推荐留默认) - 启动后端服务(如 API 或 Tomcat)并加入该网络:
docker run -d --name api-server --network nginx-net -p 8080:8080 my-api-image - 启动 Nginx 并加入同一网络:
docker run -d --name nginx-proxy --network nginx-net -p 80:80 -v $(pwd)/conf.d:/etc/nginx/conf.d:ro nginx:latest - 此时在 Nginx 配置中可直接写
proxy_pass http://api-server:8080;,Docker 会自动解析api-server为对应容器 IP
Nginx 配置里用服务名代替 IP 地址
只要容器在同一个自定义网络中,Nginx 的 upstream 或 proxy_pass 就能直接使用容器名,这是 Docker 内置 DNS 在后台工作的结果,不需要改 hosts、也不需要手动查 IP。
- 示例
/conf.d/app.conf:
upstream backend {
server api-server:8080;
server app2:8080;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
}
}
- 注意:容器名必须是合法 DNS 名(小写字母、数字、短横线),且不能用下划线;启动时用
--name显式指定,不要依赖随机名 - 如果后端容器重启,IP 变了,但名字不变,Nginx 不需要 reload —— Docker DNS 会自动更新解析记录(缓存 TTL 很短,默认几秒)
进阶:多节点或跨主机场景下的轻量服务发现
单机多容器用自定义网络足够;若涉及多个物理机或频繁扩缩容,可引入 Consul + Registrator 方案,但多数中小项目没必要。
- Consul 提供服务注册中心,Registrator 监听 Docker 事件,自动把新容器注册为服务
- Nginx 通过
nginx-upstream-check-module或 Lua 脚本调用 Consul HTTP API 获取实时后端列表 - 更简单替代:用
docker-compose启动整套服务,它默认创建专属网络并管理服务名生命周期,天然适配 Nginx 反向代理
验证是否连通的三步检查法
别只看 Nginx 日志报错,按顺序确认底层链路是否真实通达:
- 进入 Nginx 容器:
docker exec -it nginx-proxy sh,执行ping api-server—— 应成功 - 再执行
curl -v http://api-server:8080/health—— 看是否返回预期响应 - 最后检查 Nginx 配置语法:
docker exec nginx-proxy nginx -t,再重载:docker exec nginx-proxy nginx -s reload


















