${var}仅在docker-compose.yml解析时生效,不能自动配置composer镜像源;必须通过dockerfile的arg+run或容器entrypoint脚本显式执行composer config命令,并确保变量透传至运行时且权限正确。

直接在 docker-compose.yml 里用 ${VAR} 引用环境变量,不能让 Composer 自动换镜像源——因为 Composer 的镜像配置(如 composer config -g repo.packagist)是运行时行为,不是 Docker Compose 的变量插值作用域。必须把变量“透传”进容器,并在容器启动阶段或构建阶段真正执行配置动作。
为什么 ${COMPOSER_MIRROR} 写在 environment: 里没用
Compose 的 environment: 字段只把变量注入容器的运行时环境(即 env),但 Composer 不会自动读取某个环境变量来切换镜像源。它需要显式执行 composer config 命令,且该命令必须在 PHP 容器内、Composer 可用的前提下运行。
-
environment:中的COMPOSER_MIRROR=mirrors.aliyun.com只是设了个 shell 变量,Composer 完全不认 - 如果你在
docker-compose.yml里写command: composer config -g repo.packagist ${COMPOSER_MIRROR},会失败——因为${COMPOSER_MIRROR}是 Compose 解析的,而command是容器启动后才执行的,此时变量已丢失 -
.env文件里的变量也无法被 Composer 运行时自动消费,除非你手动在 entrypoint 里读取并调用composer config
正确做法:用 entrypoint 或构建时 RUN 设置镜像源
有两种可靠路径:构建镜像时固化配置(推荐用于 CI/CD 或稳定环境),或容器启动时动态设置(适合多环境快速切换)。
- 构建时设置(Dockerfile 内):
RUN composer config -g repo.packagist composer://packagist.phpcomposer.com \ && composer config -g repo.packagist composer://<code>${MIRROR_HOST}</code>注意:${MIRROR_HOST}必须是ARG,不是ENV;需在docker-compose.yml的build.args中传入 - 运行时设置(entrypoint.sh):
#!/bin/sh if [ -n "$COMPOSER_MIRROR" ]; then composer config -g repo.packagist "https://$COMPOSER_MIRROR"/packagist fi exec "$@"
然后在docker-compose.yml中挂载该脚本为entrypoint,并确保COMPOSER_MIRROR通过environment:或env_file:注入 - 别用
command:替代entrypoint:,否则无法保证composer config在应用启动前执行
env_file 和 .env 的优先级陷阱
很多人以为把 COMPOSER_MIRROR=mirrors.huaweicloud.com 放进 .env 就万事大吉,结果发现容器里还是走官方源。问题出在变量未真正“抵达” Composer 配置环节。
-
.env文件只影响 Compose 解析docker-compose.yml时的插值(比如image: php:${PHP_VERSION}),不影响容器内进程行为 -
env_file:指定的文件(如./config/composer.env)确实会把变量注入容器,但仅限于 shell 环境变量,仍需你自己在启动逻辑中读取并调用composer config - 如果同时在 shell 中
export COMPOSER_MIRROR=xxx,又在.env里写了同名变量,前者优先级更高——但依然不会自动触发 Composer 配置
验证是否生效的唯一方式
别依赖 docker-compose config 输出,它只显示 YAML 解析结果,不反映容器内实际配置。必须进容器查真实状态:
- 运行容器后执行:
docker-compose exec app composer config -g repo.packagist
输出应为类似https://mirrors.aliyun.com/packagist,而不是https://packagist.org - 如果看到
Warning: Failed to parse JSON,说明composer config执行失败,大概率是权限问题(/root/.composer/config.json不可写)或网络不通 - 临时测试可加
-v参数看详细日志:composer config -g -v repo.packagist https://xxx
最易被忽略的一点:Composer 全局配置写在 /root/.composer/config.json(root 用户)或 /home/www-data/.composer/config.json(非 root),不同基础镜像默认用户不同,composer config -g 可能写到错误位置。务必确认容器内实际运行 Composer 的用户是谁,再决定用 -g 还是 --global,或者改用 --no-interaction --working-dir=/app 指定作用域。











