代理配置和缓存预热必须分开处理,否则包会下载失败或缓存不生效;代理只影响网络路径,缓存命中取决于文件哈希、路径和ttl,二者不自动联动。

代理配置和缓存预热必须分开处理,否则包会下载失败或缓存不生效——代理只影响网络请求路径,缓存是否命中取决于文件哈希、路径和TTL,两者不自动联动。
代理配置后为什么缓存还是没用上
常见错误是以为设了http-proxy就自动“走缓存”,其实不是:Composer 仍会先查缓存,但若缓存过期、校验失败或cache-read-only为true且缓存目录不可写,它就会退回去走代理下载,且不会把新下载的包写进缓存。
- 确认缓存目录可写:
ls -ld $(composer config -g cache-dir),Docker 中常因权限或挂载方式导致只读 - 检查缓存是否被禁用:
composer config -g cache-read-only返回true就得关掉,除非你明确需要只读语义 - 代理本身不改变缓存逻辑,但若代理返回 403/502,Composer 可能静默跳过缓存重试,日志里只显示 “Downloading …” 没报错
如何让代理环境下的缓存真正预热
关键不是“先跑一次 install”,而是确保下载动作发生在缓存可写、网络可达、且不触发脚本失败的上下文中。CI 构建阶段最可靠。
- 在 CI 节点或构建容器中,先执行:
composer install --no-dev --prefer-dist --download-only,它只下载+缓存,不生成 vendor 或执行 scripts - 配合镜像源加速:
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/,避免代理成为瓶颈 - 若私有包走自建 Satis 或 Private Packagist,确保其域名已加入代理白名单(如
NO_PROXY=localhost,127.0.0.1,artifactory.internal) - 缓存预热后,用
composer clear-cache --gc清理无效项,再ls -lh $(composer config -g cache-dir)/files | head -5确认有近期 ZIP 文件
CI/CD 中代理与缓存共存的典型失败点
很多团队在 GitHub Actions 或 GitLab CI 里加了 HTTP_PROXY 环境变量,却忘了缓存 key 不包含代理配置,导致跨 job 缓存复用失败。
- 缓存 key 必须包含代理相关因子,例如:
composer-${{ hashFiles('**/composer.lock') }}-${{ env.HTTP_PROXY }} - PHP 版本变化时,缓存仍可复用(Composer 缓存 ZIP 包与 PHP 版本无关),但 autoload 优化产物(如 classmap)不能跨版本共享
- 使用
--no-scripts预热时,别漏掉后续启动时补php artisan config:cache的逻辑,否则缓存“存在但未激活” - Docker 构建中,
RUN composer install前没COPY composer.* .,会导致 lock 文件变更,缓存完全失效
真正卡住人的从来不是代理配不配得上,而是缓存有没有在对的时间、对的权限、对的命令下被真正“触达”。尤其在混合网络策略(部分直连 + 部分代理)下,NO_PROXY 和 cache-files-ttl 的组合比盲目加大超时更有效。











