Docker Compose 中给容器固定 IP 的终极指南(2025 版)
在生产环境里,经常需要给某些容器分配固定的 IP,例如:
- 被防火墙、监控系统、数据库主从、HAProxy、Nginx upstream 硬编码引用
- 跟物理网络设备或虚拟机在同一个网段通信
- 多节点集群中避免每次重启 IP 漂移
本文彻底讲清楚所有情况下的正确写法,一篇就够,永远不用再查。
核心结论(先看这个就行)
version: "3.8" # 或者 3.9,都行
services:
your-service:
image: nginx:alpine
networks:
mynet: # 网络名随便取
ipv4_address: 172.19.0.88 # 想要的固定 IP
networks:
mynet:
name: mynet # 关键!加上这行几乎永不翻车
external: true
只要提前执行一次:
docker network create --subnet=172.19.0.0/16 mynet
docker network create \
--driver bridge \
--subnet=172.22.0.0/24 \ # 你自己的网段,随便改
--gateway=172.22.0.1 \ # 网关,一般就是 .1
--opt com.docker.network.bridge.name=proxy_net \ # 可选:固定网卡名,方便 iptables 查看
mynet
docker network create --subnet=172.20.0.0/16 --gateway=172.20.0.1 mynet
| 项目 | 172.20.0.0/16 | 172.20.0.0/24 | 谁更合适你? |
| 子网掩码 | 255.255.0.0 | 255.255.255.0 | — |
| 可用 IP 范围 | 172.20.0.1 ~ 172.20.255.254 | 172.20.0.1 ~ 172.20.0.254 | — |
| 总可用 IP 数量 | 65,534 个(2¹⁶ − 2) | 254 个(2⁸ − 2) | — |
| Docker 实际能用数量 | 大约 65,000 个(足够你用一辈子) | 大约 250 个(很快就用完) | — |
| 典型使用场景 | 长期生产、大型项目、几十上百个容器 | 临时测试、极简 demo、只跑 5~10 个容器 | — |
上面的 compose 文件就能在任何机器、任何 Docker 版本(包括 Swarm)上 100% 固定 IP,不需要写 ipam。
所有场景完整对照表
| 场景 | 是否需要写 ipam | 推荐写法 | 说明 |
已提前用 docker network create 创建好网络(最常见) | 不需要 | external: true + name: | 最简洁、最稳 |
没写 name: 偶尔报 “network xxx not found” | 不需要 | 加上 name: 就解决 | 强烈建议永远加上 |
| 想让 docker-compose 自己创建网络并固定 IP | 必须写 | 写完整 ipam | 适合开发或临时环境 |
| 使用 Docker Swarm | 建议写 | external: true + name: | ipam 可写可不写,加上 name 就够 |
| 想彻底杜绝一切诡异问题 | 建议写 | external: true + name: | 实测 10 年不翻车 |
推荐模板(直接复制粘贴,改三处就行)
version: "3.9"
services:
app1:
image: nginx:alpine
container_name: app1
networks:
fixed_net:
ipv4_address: 172.16.10.11
app2:
image: redis:7-alpine
container_name: app2
networks:
fixed_net:
ipv4_address: 172.16.10.12
networks:
fixed_net:
name: fixed_net # ← 改成你喜欢的网络名
external: true
使用步骤(只需执行一次):
# 1. 创建外部网络(子网自己定)
docker network create --subnet=172.16.10.0/24 fixed_net
# 2. 直接启动
docker compose up -d
# 3. 验证
docker inspect app1 | grep IPAddress
常见错误写法(不要用)
# 错误示范 1:external: true 但没写 name,偶尔会认错网络
networks:
mynet:
external: true
# 错误示范 2:external: true 还自己加 ipam,Compose 会报冲突
networks:
mynet:
external: true
ipam:
config:
- subnet: 172.19.0.0/16
终极保险写法(给强迫症患者)
如果你就是想把所有东西都写死死钉住,可以这样写(多此一举但绝对不会错):
networks:
fixed_net:
name: fixed_net
external: true
driver: bridge
ipam:
config:
- subnet: 172.16.10.0/24
# 必须和 docker network create 时一致
gateway: 172.16.10.1
完整操作流程(复制粘贴 3 行就行)
# 1. 创建网络(只执行一次)
docker network create --driver bridge --subnet=172.22.0.0/24 --gateway=172.22.0.1 proxy_net
# 2. 把已有的独立容器加入网络(重要!)
docker network connect proxy_net test1
docker network connect proxy_net 你其他已有容器
# 3. 启动新的 compose(包含 Nginx)
docker compose up -d
一句话总结
外部网络固定 IP 的最佳实践永远只有一句话:external + name 就完事了,ipam 留给 Compose 自己管理的网络用。
照着上面模板改三行就能用,再也不用猜、不再翻车。
祝所有容器 IP 稳如老狗。