在docker-compose.yml服务中显式配置dns: [内网DNS, 公网DNS]和dns_search: [后缀],确保容器内DNS解析精准低延迟,避免host模式、错误泛化配置及CNAME未递归等问题。

docker-compose 里怎么配内网 DNS 让 composer install 快起来
容器里 composer install 慢,八成不是源的问题,而是 DNS 解析卡在 packagist.org 或 mirrors.aliyun.com 上——宿主机的 systemd-resolved 或默认 DHCP DNS 在容器里转发不稳定,尤其内网有自建 CoreDNS/dnsmasq 时更明显。
最稳的做法是在 docker-compose.yml 的服务定义里显式写死 DNS:
-
dns列表第一项必须是你的内网 DNS(比如192.168.10.5),确保curl https://mirrors.aliyun.com/composer/能秒回 - 第二项补一个公网兜底(如
114.114.114.114),防内网 DNS 故障时整个挂掉 - 加
dns_search: ["svc.cluster.local", "internal"],这样composer config -g repos.packagist写的域名能自动补后缀,避免硬编码完整地址 - 别碰
network_mode: host—— 此时dns字段直接被 Docker 忽略,/etc/resolv.conf完全继承宿主机,不可控
为什么改了 /etc/resolv.conf 还没用
你在容器里手动改 /etc/resolv.conf,重启就丢;或者进容器执行 nslookup packagist.org 看得通,但 composer install 仍卡住——大概率是 PHP 的 cURL 库绕过了系统 DNS,直接走 glibc 或 musl 的解析逻辑,而它不读 resolv.conf 的 search 行。
真正起效的方式只有两个:
- 启动容器时用
--dns和--dns-search参数(docker run场景) - 在
docker-compose.yml的services.xxx.dns和dns_search下配置(推荐,可版本控制)
验证是否生效:进容器跑 cat /etc/resolv.conf,确认 nameserver 和 search 行和你写的完全一致;再跑 php -r "var_dump(dns_get_record('mirrors.aliyun.com', DNS_A));",看返回 IP 是否是你内网 DNS 返回的(不是 114.114.114.114 那种公共 IP)。
内网 DNS 配好了,composer 还是 resolve 不到包
常见错误现象:Resolving dependencies 卡超 2 分钟、Could not fetch https://mirrors.aliyun.com/composer/packages.json、反复 retry 后报 cURL error 28。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
这时候 DNS 其实通了,问题出在 HTTP 层:
- 检查
http.timeout是否太小:运行composer config -g http.timeout 600(单位秒),默认 300 秒在弱网或高延迟内网链路上不够 - 确认内网 DNS 能解析 HTTPS 域名的 CNAME:比如
mirrors.aliyun.com实际指向aliyun-composer-mirror.oss-cn-hangzhou.aliyuncs.com,如果内网 DNS 没递归查 CNAME,就会 404 - 别让
parallel-downloads搞垮 DNS:设太高(如 20)会导致并发 A 记录查询压爆内网 DNS,建议composer config -g http-max-concurrent-downloads 6(Composer ≥2.2) - 如果用了私有镜像,
repositories里的 URL 必须以/结尾,否则 Composer 会拼错路径,根本不去请求你的内网 DNS
别把 DDNS-GO 或监控容器也塞进同一套 DNS 配置
看到别人在 docker-compose.yml 里给所有服务统一配 dns,你也照搬?危险。
像 ddns-go、blackbox-exporter、node-exporter 这类工具,它们只上报自己 IP 或采集指标,不需要解析 packagist.org 或 github.com。强行塞进内网 DNS,反而可能因 DNS 查询失败导致启动失败或日志刷屏。
正确做法:
- 只给真正需要调用 Composer、下载包、连外部镜像的服务加
dns(如php-cli、build-env) - 对纯内网通信服务(如
redis、mysql),甚至可以不配dns,靠 Docker 内嵌 DNS(127.0.0.11)直解服务名 - 若用
networks.xxx.driver: bridge定义了自定义网络,可在网络层统一设dns,但前提是所有接入服务都真需要这套策略
内网 DNS 优化不是“配了就快”,关键在精准命中:谁需要、谁不需要、查什么、兜什么底——漏掉任一环,composer install 就可能在某个你没想到的地方卡住。

















