多用户环境里 composer config -g 总不生效是因为全局配置写入当前用户的 ~/.composer/config.json,而宝塔、ci 等实际以 www 或 runner 用户运行,读不到该路径;正确做法是为对应用户单独配置(如 sudo -u www composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/),或改用 /etc/composer/config.json(composer 2.2+ 支持)及项目级 repositories 配置,并删 vendor 和 composer.lock 后重装。

多用户环境里 composer config -g 为什么总不生效
因为 -g 写的是当前 shell 用户的 ~/.composer/config.json,而 Web 服务(如宝塔、Nginx)或 CI 环境(如 GitHub Actions runner)通常以 www、www-data 或临时用户身份运行,根本读不到你的配置。你本地配好了,php-fpm 进程照样连 packagist.org 卡住。
- 常见表现:终端里
composer install正常,但网页打开就报Loading composer repositories卡死 - 验证方式:切换到真实运行用户执行
sudo -u www composer config -g repo.packagist,输出为空或null就说明没配对 - 错误操作:用
sudo composer config -g—— 这会写进root的配置,www用户仍不可见
/etc/composer/config.json 是唯一真正全局生效的路径
Composer 2.2+ 会优先加载 /etc/composer/config.json,它不依赖用户 HOME,所有用户(包括 www-data)都认这个文件,但必须同时满足四个硬性条件:
-
/etc/composer/目录存在,权限为755,属主root:root - 配置文件路径必须是
/etc/composer/config.json(不能是/etc/composer.json) -
"repositories"必须是对象结构,键名严格为"packagist.org"(不是"packagist"或"repos") -
"url"值必须是 HTTPS 且末尾带/,例如:"https://mirrors.aliyun.com/composer/"
正确示例:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
{
"config": {},
"repositories": {
"packagist.org": {
"type": "composer",
"url": "https://mirrors.aliyun.com/composer/"
}
}
}
项目级配置才是跨环境最稳的兜底方案
即使系统级配置下发失败,只要 composer.json 里有正确的 repositories,就能强制走镜像。但注意写法细节:
- 进项目根目录后运行:
composer config repo.packagist composer https://mirrors.aliyun.com/composer/(去掉-g) - 该命令会向
composer.json的"repositories"数组追加条目,不破坏已有私有源(如 Git VCS) - 必须显式在
composer.json根节点加"packagist.org": false,否则 Composer 仍可能偷偷 fallback 到官方源 - 改完必须删掉
vendor/和composer.lock,再跑composer install—— 否则composer.lock里记录的dist.url还是旧地址,根本不走镜像
为什么不能共享 ~/.composer/cache
所有试图让多个用户共用 ~/.composer/cache 或统一 COMPOSER_HOME 的做法,都会直接失败,不是慢一点,而是校验失败或链接断裂:
-
auth.json存的是个人 token,共享等于泄露凭证 -
cache/下 ZIP 包的哈希值依赖 PHP 版本、openssl版本甚至glibc小版本,A 机缓存 B 机上可能报Hash mismatch -
vendor/bin里的软链接指向各自安装路径,共享会导致链接失效 - 团队目标不是“共享缓存”,而是“所有人走同一镜像、用各自干净缓存”
最容易被忽略的点是 composer.lock 里的 dist.url —— 它记录的是实际包文件地址,镜像只加速元数据,不托管 ZIP;一旦 lock 文件里还是 https://api.github.com/,Composer 就绕过镜像直连。










