outline: deep
Docker Compose 中 --add-host 等效配置
问题描述
从 Docker 20.10 版本开始,引入了一个特殊的 host-gateway
字符串,可以在 --add-host
运行标志中使用,允许在基于 Linux 的系统上从 Docker 容器内部直接连接到本地机器。
在命令行中使用时,配置如下:
docker run \
--rm \
--name postgres \
-p "5433:5432" \
-e POSTGRES_PASSWORD=**** \
--add-host=host.docker.internal:host-gateway \
-d postgres:14.1-bullseye
但在 Docker Compose 文件中,如何实现相同的 --add-host
功能呢?
解决方案
基础配置:使用 extra_hosts
在 Docker Compose 中,可以通过 extra_hosts
参数来实现相同的功能:
version: '3.9'
services:
postgres:
image: postgres:14.1-bullseye
environment:
POSTGRES_PASSWORD: ****
ports:
- "5433:5432"
extra_hosts:
- "host.docker.internal:host-gateway"
验证配置
启动服务后,可以通过以下命令验证配置是否生效:
docker-compose up -d
docker-compose exec postgres bash
在容器内部:
apt update && apt -y install netcat
nc -vz host.docker.internal 80
网络配置的注意事项
重要提示
使用 Compose 文件启动容器时,默认情况下容器会加入 Compose 创建的专用网络,该网络的网关地址通常是随机分配的(如 172.22.0.1
),而不是默认的 Docker 网关 172.17.0.1
。
如果你的主机服务仅允许来自 172.17.0.1
的连接,这可能会导致连接问题。
推荐方案:自定义网络配置
为了避免上述问题,建议在 Compose 文件中明确定义网络:
version: '3.9'
networks:
network1:
name: my-network
attachable: true
ipam:
driver: default
config:
- subnet: 172.18.0.0/16
ip_range: 172.18.5.0/24
gateway: 172.18.0.1
services:
postgres:
image: postgres:14.1-bullseye
environment:
POSTGRES_PASSWORD: ****
ports:
- "5433:5432"
networks:
- network1
验证网关地址:
docker inspect tmp_postgres_1 -f '{{range .NetworkSettings.Networks}}{{.Gateway}}{{end}}'
# 输出:172.18.0.1
替代方案:加入默认桥接网络
你也可以让容器加入默认的 bridge
网络:
version: '3.9'
services:
postgres:
image: postgres:14.1-bullseye
environment:
POSTGRES_PASSWORD: ****
ports:
- "5433:5432"
network_mode: bridge
extra_hosts:
- "host.docker.internal:host-gateway"
安全考虑
加入 bridge
网络后,你的容器可以与网络上的所有其他容器通信(如果它们有公开的端口),反之亦然。如果需要与这些其他容器保持隔离,最好不要这样做,而是使用自定义网络。
故障排除
如果遇到网络配置错误,可以尝试以下解决方法:
# 重启 Docker 服务
sudo service docker restart
# 清理网络(可能不够)
docker network prune -f
总结
在 Docker Compose 中实现 --add-host=host.docker.internal:host-gateway
的最简单方法是使用 extra_hosts
配置。但为了确保网络连接的稳定性和可预测性,建议明确定义自定义网络配置。
根据你的具体需求和安全考虑,选择最适合的网络配置方案。