根本问题是宿主机与容器内用户ID(UID/GID)不一致,导致挂载目录在容器中不可写;需先用id -u/-g和ls -ld确认宿主机UID/GID及目录属主,再通过docker-compose.yml的user字段或构建参数统一映射,最后清理残留目录并以当前用户重装依赖。

根本问题是宿主机与容器内用户ID(UID/GID)不一致,导致挂载目录在容器中不可写。这不是权限数字(如755)不对,而是文件属主和运行进程的用户不匹配。
确认当前用户身份
在宿主机上运行:
- id -u 和 id -g,记下 UID 和 GID 数值
- 检查项目目录归属:ls -ld ./src 或 ls -ld ./vendor,看第三列(属主)是否为你当前用户
- 进入容器验证:docker-compose exec php id,确认容器内 PHP 进程 UID/GID 是否与宿主机一致
统一UID/GID映射
在 docker-compose.yml 中显式指定用户上下文:
- 在服务配置里加 user: "${UID:-1000}:${GID:-1000}"
- 确保构建或启动时能读取环境变量,例如在 shell 中执行 export UID=$(id -u) GID=$(id -g) 再运行 docker-compose up
- 若使用自定义镜像,在 Dockerfile 中避免硬编码 USER 指令,改用构建参数或运行时覆盖
清理并重建挂载内容
所有权漂移常因历史操作残留引发,需彻底重置:
- 停容器:docker-compose down
- 删掉已挂载的 vendor/、bootstrap/cache/、storage/logs/ 等目录(宿主机侧)
- 删掉 composer.lock(如有),避免旧依赖锁死属主信息
- 用当前用户重新运行:composer install --no-scripts(先跳过脚本避免权限失败),再 docker-compose up -d
避免 chmod 777 和 root 初始化
这类操作治标不治本,还可能失效或引入风险:
- chmod 777 在 NFS、Docker bind mount、某些云存储卷上完全无效
- 用 sudo composer install 会把 vendor/ 属主设为 root,后续普通用户无法修改
- 一旦发生,必须先 sudo chown -R $USER:$USER vendor/,再清理重装

















