Skip to content

outline: deep

Docker Compose 中 --add-host 等效配置

问题描述

从 Docker 20.10 版本开始,引入了一个特殊的 host-gateway 字符串,可以在 --add-host 运行标志中使用,允许在基于 Linux 的系统上从 Docker 容器内部直接连接到本地机器。

在命令行中使用时,配置如下:

bash
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 参数来实现相同的功能:

yaml
version: '3.9'

services:
  postgres:
    image: postgres:14.1-bullseye
    environment:
      POSTGRES_PASSWORD: ****
    ports:
      - "5433:5432"
    extra_hosts:
      - "host.docker.internal:host-gateway"

验证配置

启动服务后,可以通过以下命令验证配置是否生效:

bash
docker-compose up -d
docker-compose exec postgres bash

在容器内部:

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 文件中明确定义网络:

yaml
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

验证网关地址:

bash
docker inspect tmp_postgres_1 -f '{{range .NetworkSettings.Networks}}{{.Gateway}}{{end}}'
# 输出:172.18.0.1

替代方案:加入默认桥接网络

你也可以让容器加入默认的 bridge 网络:

yaml
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 网络后,你的容器可以与网络上的所有其他容器通信(如果它们有公开的端口),反之亦然。如果需要与这些其他容器保持隔离,最好不要这样做,而是使用自定义网络。

故障排除

如果遇到网络配置错误,可以尝试以下解决方法:

bash
# 重启 Docker 服务
sudo service docker restart

# 清理网络(可能不够)
docker network prune -f

总结

在 Docker Compose 中实现 --add-host=host.docker.internal:host-gateway 的最简单方法是使用 extra_hosts 配置。但为了确保网络连接的稳定性和可预测性,建议明确定义自定义网络配置。

根据你的具体需求和安全考虑,选择最适合的网络配置方案。