离线环境使用Composer必须提前准备依赖,不能依赖composer install自动联网下载;最稳方案是复制已构建好的vendor目录,或用Satis预生成静态私有仓库并配置本地源。

离线环境里 Composer 不能联网,就别指望 composer install 能自动拉包——它默认行为就是发 HTTP 请求。真离线,必须提前把所有依赖“打包进镜像”或“预生成静态仓库”,而不是 runtime 去凑合。
为什么 composer install --no-network 还是报错
这个参数只是跳过网络检查,但不解决根本问题:如果 vendor/ 不存在、composer.lock 里有没缓存过的包、或者 repo.packagist 配置没真正禁用,它照样会尝试读取远程 packages.json。
-
COMPOSER_DISABLE_NETWORK=1必须设为环境变量,否则--no-network不生效 -
composer config --global repo.packagist false才算硬性关闭源,只写config --unset不等于禁用 - 项目级
composer.json中的repositories字段会覆盖全局配置,得手动删或用composer config --unset repositories
最稳的离线方案:把 vendor/ 当资产 COPY 进去
适合 CI 构建后部署、Docker 镜像打包等场景。核心是“不在容器里装,而在构建机上装好再搬”。
- 在有网机器上,用相同 PHP 版本 + 相同 Composer 版本执行:
composer install --no-dev --optimize-autoloader - 确认
vendor/完整,且composer.lock已提交 - Dockerfile 中用
COPY vendor ./vendor,不要RUN composer install - 加一行
RUN composer dump-autoload -o(可选),确保 autoloader 是最优状态
要支持动态增删包?得用 Satis 预生成私有镜像
纯 COPY vendor/ 灵活性差。若需在离线环境运行 composer require 或更新依赖,就得搭一个本地静态源。
- 在可联网服务器上装 Satis:
composer create-project composer/satis - 写
satis.json,重点设:"require-all": false(别全量抓),只列你真用的包名 - 运行:
php bin/satis build satis.json web/,输出是含packages.json和dist/zip 的静态目录 - 把整个
web/目录扔进内网 Web 服务(Nginx/Apache),确保能通过http://internal-mirror/packages.json访问 - 离线机上执行:
composer config --global repos.offline composer http://internal-mirror/
最容易被忽略的验证点
很多人跑完 composer --version 就以为搞定了。但真正关键的是:断网后能否走通完整安装流程。
- 进容器后先执行:
ip link set eth0 down(Linux)或断开物理网线 - 再跑:
composer install --no-plugins --no-scripts --no-autoloader --ignore-platform-reqs - 如果报
Could not fetch https://...,说明某处配置漏了——大概率是repo.packagist没设成false,或项目级repositories还在偷偷启用 - 用
composer config --list | grep repo查实际生效的源,比看文档更准


















