
在 docker 容器中运行 php 时,`mkdir()` 报错 “permission denied”,根本原因是 apache(以 `www-data` 用户身份运行)无权在 `/var/www/html/` 下创建目录;需通过 `chown` 正确设置目录所有权。
当你在基于 php:7.3-apache 的 Docker 容器中执行 mkdir(),却遇到如下错误:
Warning: mkdir(): Permission denied in /var/www/html/test.php on line 9
这并非 PHP 配置或代码逻辑问题,而是典型的 Linux 文件权限与用户上下文不匹配问题:Apache 子进程默认以 www-data 用户身份运行,而你通过 COPY . /var/www/html/ 复制进容器的文件/目录,其属主仍是构建时的 root(或宿主机用户),导致 www-data 无法写入。
✅ 正确解决方案:在 Dockerfile 中显式授权
只需在 COPY 指令后、EXPOSE 前添加一行 chown,将 /var/www 及其子目录所有权递归赋予 www-data:www-data:
FROM php:7.3-apache RUN apt-get update && apt-get install -y git RUN docker-php-ext-install pdo pdo_mysql mysqli RUN a2enmod rewrite COPY . /var/www/html/ RUN chown -R www-data:www-data /var/www # ← 关键修复行 EXPOSE 80/tcp EXPOSE 443/tcp
? 注意:chown -R www-data:www-data /var/www 必须放在 COPY 之后、容器启动之前(即构建阶段),确保运行时 www-data 对整个 Web 根目录拥有读写权限。
? 补充说明与最佳实践
- 不要依赖 0777 权限掩码:即使 mkdir($path, 0777, true) 显式设为全权限,若父目录对 www-data 不可写(如属主为 root),创建仍会失败。权限掩码仅控制新目录的 初始 权限,不解决属主问题。
- 避免在运行时 chmod 777:临时修改权限存在安全风险,且容器重启后失效;应在镜像构建阶段固化权限模型。
-
验证是否生效:可在容器内执行 docker exec -it php6 ls -ld /var/www /var/www/html,确认输出类似:
drwxr-xr-x 1 www-data www-data 4096 ... /var/www drwxr-xr-x 1 www-data www-data 4096 ... /var/www/html
-
额外加固建议(可选):若项目无需写入整个 /var/www,可更精确授权,例如:
RUN chown -R www-data:www-data /var/www/html/login /var/www/html/movie
✅ 修复后你的 PHP 代码即可正常运行
无需修改原有逻辑,以下代码将顺利创建嵌套目录:
立即学习“PHP免费学习笔记(深入)”;
⚠️ 小提示:你原代码中 $dirPathpr = $root . $postk . " / " . $room_id; 的 " / " 含空格,会导致路径非法(如 login/1220 / foile),请务必删除空格,改为 " / " → "/"。
至此,mkdir() 权限问题彻底解决——核心在于让运行 PHP 的 www-data 用户真正拥有目标目录的归属权,而非仅靠 chmod 或代码参数“硬扛”。这是 Docker 化 PHP 应用的标准化权限治理实践。











