容器中composer install卡在“loading composer repositories”是因为默认直连packagist.org,国内无法访问;必须用run composer config -g repo.packagist {"type": "composer", "url": "https://mirrors.aliyun.com/composer/"}全局覆盖源,且该配置须在copy composer.*之前执行,否则构建时仍超时失败。

为什么容器里 composer install 总卡在 “Loading composer repositories”
这不是 DNS 解析慢,是 Composer 2.2+ 默认硬编码直连 packagist.org,而国内网络根本连不上;更隐蔽的问题是:即使你改了 composer.json 里的 repositories,create-project 或全局命令(如 composer require)仍走默认源,完全不受影响。
必须用 composer config -g repo.packagist 全局覆盖,且值必须是完整 JSON 结构,比如:{"type": "composer", "url": "https://mirrors.aliyun.com/composer/"}。
如果输出是字符串、空值或仍是 packagist.org,说明没生效。
- 别信宿主机的
~/.composer/config.json会透传进容器——它不会 - 别用
COMPOSER_REPO_PACKAGIST环境变量临时覆盖——它只对当前命令有效,后续composer install或require还会回退 - 验证真实请求地址:加
-vvv跑一次,grepDownloading,确认 URL 是https://mirrors.aliyun.com/composer/而不是packagist.org
Dockerfile 中必须写的三行关键配置
官方 PHP 镜像(如 php:8.3-cli)虽预装 composer,但默认源仍是 packagist.org。构建阶段不固化配置,等于裸奔。
-
RUN composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/(注意末尾/和composer类型声明) -
RUN composer config -g http-max-concurrent-downloads 8(设太高易触发file_put_contents(/tmp/): failed to open stream,CI 环境建议降到 6) -
RUN apk add --no-cache ca-certificates(仅 Alpine 镜像需要,否则 SSL certificate problem 中断)
这三行必须写在 COPY composer.* . 之前,否则构建时还没配好源就去拉包,直接超时失败。
COPY 顺序错一丁点,vendor 就全重装
Docker 层缓存极其敏感。顺序错,哪怕只是调换 composer.json 和 composer.lock 的 COPY 位置,都会导致整个 vendor 层失效,每次构建都重装全部依赖。
- 必须先
COPY composer.lock .,再COPY composer.json .,最后RUN composer install --no-dev --optimize-autoloader --classmap-authoritative -
composer.lock不能被.dockerignore排除,否则composer install退化成update,破坏可重现性 - 别在
RUN composer install前COPY . /app——任何源码改动都会污染依赖层
多阶段构建中 vendor 复制容易漏掉 autoload 路径
很多人以为 COPY --from=builder /app/vendor /app/vendor 就完事了,结果运行时报 Class not found。问题常出在 autoload 生成路径和运行镜像的 PHP 扩展缺失上。
- builder 阶段必须启用所有生产所需扩展:
zip、mbstring、xml(Laravel/Symfony 必需) - builder 阶段跑
composer install时加--optimize-autoloader --classmap-authoritative,否则 autoload 文件可能指向 builder 阶段的绝对路径 - runtime 阶段的 PHP 版本、扩展名、
extension_dir必须与 builder 完全一致,否则composer dump-autoload生成的映射失效
最稳的做法是:builder 和 runtime 都用同一基础镜像 tag(如都用 php:8.3-cli),避免隐式差异。国内镜像源配置只管网络,autoload 路径和扩展兼容性才是运行时报错的真正黑盒。











