背景

我本地开发用的 php 和 nginx 都部署在 docker 中,宿主机为 MacOS
宿主机中 hosts 一个域名 127.0.0.1 abc.test,再把 nginx 容器的 80 端口映射出来。就能正常通过 abc.test 访问到 nginx 再转发给 php

看起来很完美,直到 —— 我需要在 php 中访问 abc.test 这个站点的时候
当我在 php 容器中需要解析这个域名时(例如 curl、wget),会调用到宿主机中的 hosts 文件,返回一个 127.0.0.1。导致 php 容器发出的请求又绕回到容器自身,自然是 Connection refused 了

我记得在以前我使用 Docker Desktop For Windows 时,只需要把域名加进 nginx 容器的 aliases 配置里就行了:

nginx:
  image: "nginx"
  ports:
    - "80:80"
  networks:
    php_default:
      aliases:
        - abc.test

YAML

但这次似乎行不通了,容器中解析域名依然是先调用宿主机的 hosts 返回 127.0.0.1,而不是 nginx 容器的 ip
难道是 Docker 在 Mac 上特有的问题?
我尝试了很多操作、中英文搜了很多资料,花了几个小时都没法完美解决这个问题
最后只好曲线救国……

解决方法

固定 nginx 容器的 ip,再配合 extra_hosts

networks: 
  php_default:
    name: php_default
    ipam:
      config:
        - subnet: 172.0.0.0/24

php81:
  image: "php81"
  networks:
    - php_default
  extra_hosts:
    - "abc.test:172.0.0.10"

nginx:
  image: "nginx"
  ports:
    - "80:80"
  networks:
    php_default:
      ipv4_address: 172.0.0.10
      aliases: 
        - abc.test

YAML

这很蠢,每个用到这个域名的容器都需要加 extra_hosts
但……至少能用了,实现了容器内外都能使用同一个域名进行通讯的效果