docker中composer install总重下包的根本原因是缓存链断裂——copy . /app若出现在run composer install之前,任何文件变动都会使vendor层失效;必须先copy composer.json和composer.lock,再run composer install,中间不可插入其他run指令,且需正确配置镜像源、并发数及挂载持久化缓存目录。

为什么Docker里composer install总重下包
不是网络慢,是缓存链断了——只要COPY . /app出现在RUN composer install之前,哪怕只改了一个空格,整个vendor层就失效。Docker构建缓存只认指令内容字面一致,不看语义。你改了README.md,它照样重跑composer install,因为上层COPY的哈希变了。
-
COPY顺序必须是:COPY composer.json composer.lock ./→RUN composer install→COPY . . -
composer.lock必须和composer.json一起COPY,缺一个就跳过缓存 - 中间不能插任何
RUN指令(比如chmod、mkdir),否则缓存链断裂 - 多阶段构建中,若用
FROM php:8.2-cli AS builder,别忘了在final阶段COPY --from=builder /app/vendor /app/vendor
镜像源没生效,缓存再好也白搭
缓存层能复用,但下载仍走packagist.org?那说明镜像源配置根本没进构建环境。宿主机的~/.composer/config.json不会透传进容器,composer config -g必须在RUN里执行,且得验证输出。
- 在
Dockerfile里写:RUN composer config -g repo.packagist composer https://mirrors.tuna.tsinghua.edu.cn/composer/ - 验证是否生效:
RUN composer config -g repo.packagist输出必须是完整JSON,含"url": "https://mirrors.tuna.tsinghua.edu.cn/composer/" - 别用已停用的阿里云旧地址
https://mirrors.aliyun.com/composer/(2026年已不可用) - 项目级
composer.json里若硬编码了"repositories"字段,会覆盖全局配置,得删或改成镜像地址
并发数设太高,反而触发file_put_contents(/tmp/): failed to open stream
这不是磁盘满,是容器tmpfs的inode耗尽。Composer 2.2+默认并发下载数等于CPU核数,但在CI容器里常只有1–2核,设http-max-concurrent-downloads=15会导致临时文件竞争失败。
- 安全值是
6~8:在RUN里加&& composer config -g http-max-concurrent-downloads 6 - 别用弃用参数
parallel-downloads,它在2.2+静默无效 - 如果CI仍报错,降到
4;同时确认COMPOSER_CACHE_DIR已设为持久路径(如/tmp/composer-cache)并挂载volume -
--no-progress可减少日志I/O压力,对缓存无影响但能降低中断概率
缓存目录没挂载,每次都是裸奔
就算composer install层缓存命中,如果~/.composer/cache没挂载,每次构建仍要重下所有zip包——因为缓存只存在容器临时层,构建完就丢。
- 构建时用BuildKit,加
# syntax=docker/dockerfile:1开头,然后用RUN --mount=type=cache,target=/root/.composer/cache composer install ... - 传统方式:在
RUN前设环境变量ENV COMPOSER_CACHE_DIR=/tmp/composer-cache,并在docker build时用--build-arg COMPOSER_CACHE_DIR=/tmp/composer-cache配合volume挂载 - CI环境推荐固定路径+命名卷:
docker build --cache-from=... --cache-to=... -v $(pwd)/.composer-cache:/tmp/composer-cache . - 注意权限:挂载目录需对容器内用户(如
www-data)可写,否则Failed to create cache directory会静默降级为无缓存模式
缓存失效后最麻烦的不是重下,而是错误叠加:镜像源不对 + 并发太高 + 缓存目录不可写,三者同时发生时,composer install会卡在“Loading composer repositories”十几分钟,日志里却只显示0%。先用composer config -g repo.packagist和curl -I确认源可用,再检查COPY顺序和挂载路径,最后调并发数——顺序错了,调再多参数也没用。











