Composer怎么在没有网络的环境安装_Composer离线镜像包制作方法【特技】

2次阅读

离线安装 composer 依赖必须使用 satis 构建本地镜像,而非仅复制 vendor 或依赖 composer.lock;需在有网环境生成完整 packages.json 和 zip 包,内网通过 http 服务提供,并在项目 composer.json 中配置本地仓库地址且禁用 packagist.org。

Composer怎么在没有网络的环境安装_Composer离线镜像包制作方法【特技】

离线安装 Composer 依赖,靠的是提前固化资源,不是“跳过联网”

没有网络时 composer install 能成功,前提是它根本不需要联网——这只有在 composer.lock 存在、且所有包的 ZIP 文件或源码已本地可得时才成立。直接把 vendor 目录打包复制到另一台机器,90% 情况下会失败,因为 autoload 映射缺失、扩展依赖未满足、或路径硬编码导致类找不到。

用 Satis 构建完整离线镜像(推荐长期方案)

Satis 是 Composer 官方维护的静态仓库生成工具,它不运行服务、不依赖数据库,只输出 packages.json 和一 ZIP 包,nginxpython3 -m http.server 就能跑起来。关键不是“下载缓存”,而是“构建一个功能等价的 packagist.org 替身”。

  • 在有网机器上执行:composer create-project composer/satis --stability=stable
  • 写好 satis.json,明确列出项目实际用到的所有顶层包(别信 "require-all": true,它会拉下几十 GB 的无用包)
  • 运行:php bin/satis build satis.json web/ —— 这一步会递归解析依赖、下载 dist ZIP、生成 autoload 信息,并全部放进 web/ 目录
  • 把整个 web/ 目录拷进内网机器,用 python3 -m http.server 8000 启动,访问 http://127.0.0.1:8000/packages.json 能打开就算成功

项目里怎么告诉 Composer:“别上网,就认这个本地地址”

光有镜像没用,项目必须主动切换源。最稳妥的方式是改 composer.json,而不是全局 config——后者会影响所有项目,且容易被忽略。

  • composer.json 中添加 "repositories" 块,把本地镜像放第一位:
  • "repositories": [   { "type": "composer", "url": "http://127.0.0.1:8000" } ], "packagist.org": false
  • 运行前务必清缓存:composer clear-cache,否则 Composer 可能仍从旧缓存读取元数据
  • 再执行:composer install --no-interaction,它会从 http://127.0.0.1:8000/packages.json 拉清单,再从同域名下的 dist/xxx.zip 下载安装

私有包、git 依赖、dev 包这些怎么处理?

如果项目用了公司内网 gitlab 的私有库,或 require-dev 里的测试工具(如 phpunit/phpunit),Satis 默认不会拉它们——除非你显式写进 satis.json"require" 里,或启用 "require-dependencies": true(但要小心 dev 包污染生产镜像)。

  • 对私有 Git 库:改用 "type": "package" + "dist" 方式,把代码打成 ZIP 放进内网 HTTP 可访问路径,然后在 composer.json 里声明 URL
  • 对 dev 包:若离线环境也要跑测试,satis.json 中需保留 "skip-dev": false,并在 archive 配置里确保 dist 目录包含它们
  • 最容易漏的是“间接依赖”:比如你 require guzzlehttp/guzzle,但它内部 require psr/http-client,而你没在 satis.json 里列出来——Satis 就不会下载,安装时就会报错“package not found”

真正卡住人的从来不是命令记不住,而是以为 composer.lock + vendor 复制就能离线,结果 autoload 错、扩展缺、私有包 404。Satis 镜像不是可选项,是离线场景的基础设施——它强制你把整个依赖树显式声明、提前验证、物理固化。

text=ZqhQzanResources