根本原因是Web服务器用户与目录属主不匹配,须逐级确认用户(如www-data)、重置项目属主为deploy:www-data、锁定代码层640、放开public750、runtime设770/660,并验证www-data可写。

ThinkPHP6.x项目在Linux服务器上部署后报错“mkdir(): Permission denied”或日志无法写入、缓存生成失败,根本原因几乎全是运行目录权限配置错误——不是所有目录都该755,也不是所有文件都该644,必须按角色区分Web服务器用户(如www-data)、部署用户(如deploy)和PHP进程实际身份,逐目录精准赋权。
确认Web服务器运行用户与组
执行 ps aux | grep -E '(apache|httpd|nginx)' 查看主进程用户。Apache通常以 www-data:www-data 运行,Nginx多为 www-data:www-data 或 nginx:nginx。若用systemd托管PHP-FPM,则需查 systemctl show php-fpm.service | grep -E 'User|Group'。这一步跳过会导致后续所有chmod操作失效。
用 id -u www-data && id -g www-data 验证该用户真实存在。若返回“no such user”,说明未安装对应服务或用户被删,需先修复环境再继续。
核心五目录权限设置
进入项目根目录后,按以下顺序执行(顺序不可颠倒):
立即学习“PHP免费学习笔记(深入)”;
- 第一步:重置整个项目所有权
执行chown -R deploy:www-data .——这里 deploy 是你日常维护项目的普通用户,www-data 是Web服务器组。【必须是组而非用户,否则public下静态资源无法被Web进程读取】 - 第二步:锁定代码层只读
find . -path "./app" -o -path "./config" -o -path "./extend" -o -path "./route" | xargs chmod -R 640——这些目录含业务逻辑与配置,PHP进程只需读取,绝不能写入。 - 第三步:放开public入口与静态资源
chmod 750 public && chmod 640 public/index.php && chmod -R 750 public/static——index.php必须可执行(Apache需+x才能解析),static子目录要让Web服务器能遍历读取。 - 第四步:runtime必须可写且隔离
chmod -R 770 runtime/ && find runtime/ -type f -exec chmod 660 {} \;——目录770确保deploy用户和www-data组都能进、读、写;文件660防止其他用户窥探日志内容。 - 第五步:上传目录单独强化
若config/filesystem.php中定义了'root' => app()->getRootPath() . 'public/storage',则执行chmod -R 770 public/storage并确认该路径不在Git追踪中。这一步漏掉会导致用户上传头像、附件时直接500。
Apache与Nginx的特殊处理
方法一:Apache启用mod_rewrite并确保.htaccess生效
编辑 /etc/apache2/sites-enabled/000-default.conf,在 <Directory "/var/www/html/your-project"> 块内添加:AllowOverride All 和 Require all granted。重启前务必执行 a2enmod rewrite,否则ThinkPHP路由全部404。
方法二:Nginx需手动透传PATH_INFO
在server块location ~ \.php$中加入:fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;fastcgi_param PATH_INFO $fastcgi_path_info; ——缺后者会导致URL参数丢失,例如 /index/index?id=1 解析失败。
注意:Nginx默认不读.htaccess,所有重写规则必须写进conf,ThinkPHP的伪静态规则要转成Nginx语法,直接复制Apache规则会彻底失效。
验证权限是否生效
切换到www-data用户模拟运行:sudo -u www-data -s → cd /var/www/html/your-project → php think build。若提示“Permission denied”在runtime/log目录,说明第4步没执行到位;若报错“Cannot write to config/app.php”,说明第2步误对config目录用了755。
退出后立即执行:sudo -u www-data touch runtime/test_write && sudo -u www-data rm runtime/test_write ——这条命令成功即证明runtime写权限闭环完成。



















