离线容器中不能用apt install composer,因基础镜像默认无Composer且该命令会触发网络下载deb包而失败;正确做法是在联网机生成composer二进制并COPY进镜像,同时设ENV COMPOSER_DISABLE_NETWORK=1和composer config --global repo.packagist false彻底禁网。

离线容器里直接 apt install composer 为什么必挂
因为基础镜像(比如 php:8.3-cli)默认不带 Composer,而 apt install composer 会触发 apt 自身的网络请求去拉 deb 包——这在断网容器里直接失败。更隐蔽的问题是:即使你用 curl 下载安装脚本,它也会联网校验签名、拉取最新版本,根本绕不开网络。
怎么把 Composer 二进制 baked 进离线镜像
必须当成静态资产打包,不能运行时安装。关键动作有四步:
- 在联网机上执行:
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"→ 再用哈希校验后运行php composer-setup.php --install-dir=/usr/local/bin --filename=composer - 确认生成的是普通 PHP 脚本(非 Phar 封装):
file /usr/local/bin/composer,否则某些离线环境因缺phar扩展报错 - Dockerfile 中用
COPY直接复制该文件,别用RUN curl | php - 务必加
RUN chmod +x /usr/local/bin/composer,否则容器内执行报Permission denied
禁用 Packagist 的硬性配置必须写死
光有二进制还不够。Composer 在 install 阶段仍会主动请求 https://repo.packagist.org/packages.json,这个行为默认开启,且无法跳过——除非你从配置和环境变量双管齐下:
-
RUN composer config --global repo.packagist false(全局关掉 fallback 源) -
ENV COMPOSER_DISABLE_NETWORK=1(这是强制开关,不设它,--no-network参数无效) - 若要用本地 artifact 仓库,路径必须是容器内真实存在的绝对路径,例如:
RUN composer config repositories.offline '{"type":"artifact","url":"/opt/artifacts/"}' - 检查项目级
composer.json里是否还残留"repositories": [{"type": "packagist", "url": "https://packagist.org"}],删掉它
离线 install 命令组合不能省任何参数
哪怕 vendor/ 和 composer.lock 全都存在,只跑 composer install 依然大概率报错。真正稳的命令是:
COMPOSER_DISABLE_NETWORK=1 composer install --no-plugins --no-scripts --no-autoloader
执行完必须立刻补一记:composer dump-autoload -o,否则运行时报 Class not found。容易被忽略的点是:--no-plugins 不仅防插件联网,还避免 hirak/prestissimo 等插件在离线时卡住;--no-autoloader 是为了跳过 autoload 重建阶段那些可能触发远程类查找的自定义逻辑。











