答案:容器内必须在Dockerfile中配置镜像源,因宿主机的composer config -g不透传;需执行RUN composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/并确保URL末尾带/、版本≥2.2、缓存链完整且禁用Xdebug。

直接改宿主机的 composer config -g 对构建完全无效——容器里压根不读你本地的 ~/.composer/config.json,必须把镜像源写进 Dockerfile 构建流程里。
为什么 composer install 卡在 downloading?
不是网络差,是容器默认直连 packagist.org,DNS 解析 + TLS 握手 + 下载全走 Docker 网络栈,还叠加了默认 DNS 转发延迟。更关键的是:没配镜像源,等于裸奔。
- 现象:日志反复卡在
Downloading https://packagist.org/packages.json或某个包的.zip - 验证是否生效:
composer config -g repo.packagist输出必须是完整 JSON,如{"type": "composer", "url": "https://mirrors.aliyun.com/composer/"} - 别信“宿主机已配好”,它不会透传;也别用
--global写入/root/.composer,基础镜像可能根本没创建该目录或权限不对
RUN composer config -g 怎么写才不失败?
全局配置最稳,但路径、权限、版本三者缺一不可。
- 必须加
--global参数(-g),否则只对当前命令生效 - URL 末尾必须带
/,否则会解析成无效 JSON - 并发数别乱设:
http-max-concurrent-downloads 8是安全值;设到 15 容易触发file_put_contents(/tmp/): failed to open stream(不是磁盘满,是 tmpfs inode 不够) - 先确认版本:
composer --version必须 ≥ 2.2,否则http-max-concurrent-downloads静默无效
怎么避免每次改代码都重装 vendor?
缓存链断一次,就白跑几分钟。核心就一条:让 COPY composer.json composer.lock ./ 和 RUN composer install 构成连续、无干扰的缓存层。
-
COPY . /app绝不能出现在RUN composer install之前——哪怕只改一个空格,vendor 层全废 - 这两行之间不能插任何指令(比如
RUN chmod、RUN mkdir),否则缓存链断裂 - 必须同时
COPY composer.json和composer.lock,缺一不可;只拷composer.json会让 Docker 认为这一层“可能不同”,跳过缓存 - 参数要精简:
--no-dev --optimize-autoloader --no-scripts,跳过 dev 包、autoload 生成和 post-install-cmd
镜像源不是万能的,这些情况它不管用
换源只解决 packagist.org 下载慢,但很多卡顿来自其他地方。
- 如果
composer.lock里锁的是git地址(比如"type": "package", "source": {"url": "https://github.com/xxx"}),Composer 仍会直连 GitHub,镜像源完全绕不过 - Xdebug 默认启用会让
composer install慢 3–5 倍,尤其在 autoload 阶段;得手动关:RUN docker-php-ext-disable xdebug - opcache 在安装阶段建议关闭,避免字节码缓存干扰 autoloader 生成逻辑
- CI 环境中,
--no-autoloader可省掉 30%+ 时间,后续用composer dump-autoload --optimize单独补
真正卡住的地方,往往不在“换源”本身,而在于缓存层被意外打断、Xdebug 没关、或者 composer.lock 里混着 Git 依赖——这些点不排查,光改镜像 URL 就是徒劳。


















