如何配置Docker Compose文件使其同时识别用户自定义网络与默认网络?
问题场景
你现在用Caddy做反向代理,靠一个叫srv的自定义Docker网络把代理和各个应用容器(比如helloworld)连起来,每个应用的Docker Compose文件里都得显式配置这个外部网络,就像下面这样:
networks: srv: external: true name: srv services: helloworld: image: helloworld container_name: helloworld networks: - srv
这套配置目前跑起来没问题,反向代理能精准把外部请求路由到helloworld:7888。但你现在想换成Docker默认的bridge网络,还不想在每个Compose文件里都写一堆网络相关的配置,甚至还可能需要容器同时能访问自定义网络和默认网络的资源?
实现方案
1. 让容器同时接入自定义网络和默认网络
如果你需要容器既能和srv网络里的Caddy代理保持连通,又能和默认bridge网络中的其他服务通信,只需要在Compose的networks列表里加上default就行——因为Docker Compose默认会自动创建并管理一个默认网络,不用你显式定义:
networks: srv: external: true name: srv services: helloworld: image: helloworld container_name: helloworld networks: - srv - default # 加入默认网络,无需额外定义
这样配置后,你的helloworld容器就同时属于srv和默认网络了,两边的通信都不会受影响。
2. 完全切换到默认网络,无需显式配置网络块
如果你想彻底抛弃自定义srv网络,只用默认bridge网络,那更简单——直接删掉Compose文件里所有和networks相关的代码!
Docker Compose会自动把容器加入到为当前项目创建的默认网络里(这个网络本质是基于bridge驱动的,而且支持容器间用服务名直接DNS解析)。示例Compose文件会变成这样:
services: helloworld: image: helloworld container_name: helloworld
要是你想强制让容器加入Docker全局的默认bridge网络(注意:这个全局网络不支持服务名解析,容器之间只能用宿主机IP+容器端口通信),可以加上network_mode配置:
services: helloworld: image: helloworld container_name: helloworld network_mode: bridge
不过这种情况下,你得同步更新Caddy的反向代理配置,比如把原来的helloworld:7888改成宿主机IP+容器映射的端口,或者给helloworld容器配置一个静态IP,确保代理能找到它。
小提示
自定义网络相比默认bridge其实有不少优势,比如自动DNS、更好的隔离性。要是你只是嫌每个Compose都要重复写srv网络的配置,可以用Compose的扩展字段(比如x-networks)来复用配置,能省不少事。
备注:内容来源于stack exchange,提问作者WoJ

