在使用 CloudPanel (CLP) 的过程中,我们遇到了这样一个让人头疼的问题:上传文件时报错 Permission denied
,手动修改权限可以解决。但 每次重启 Nginx 后问题又复发,权限被“自动”改回去了。
这篇文章将详尽分析问题出现的原因,并给出一次性彻底解决这个权限恢复问题的稳定方案。
为什么权限会被重置?
我们逐一排查了:systemd tmpfiles.d
?
使用:
grep -r "/var/lib/nginx/body" /etc/tmpfiles.d/ /usr/lib/tmpfiles.d/ /run/tmpfiles.d/
没有结果。
排查了CloudPanel 自动脚本?
使用:
grep -r "/var/lib/nginx/body" /home/clp/
也没有任何发现。
结论:
Nginx 本身在某些情况下可能在启动时会重新初始化该目录,尤其是当该目录为空时。
终极解决方案:使用 systemd 的 ExecStartPost
我们采用 systemd 的机制,在 Nginx 每次启动完成后自动设置正确权限。
步骤 1:编辑 Nginx 的 override.conf
sudo EDITOR=vi systemctl edit nginx
如果你不熟
nano
,用上面的命令指定vi
,否则直接运行sudo systemctl edit nginx
即可。
在打开的编辑器中,最上方插入以下内容:
[Service]
ExecStartPost=/bin/chown clp:clp /var/lib/nginx/body
ExecStartPost=/bin/chmod 750 /var/lib/nginx/body
完成后按 Esc
,输入 :wq
保存退出
步骤 2:重新加载 systemd 配置
sudo systemctl daemon-reload
步骤 3:重启 Nginx 测试
sudo systemctl restart nginx
然后检查目录权限:
ls -ld /var/lib/nginx/body/
# 你应该看到:
# drwxr-x--- 2 clp clp 4096 ...
现在,每次重启 nginx 后,权限都会自动恢复为正确状态,不再需要再手动干预。
延伸:为什么不用 tmpfiles.d?
虽然 systemd 支持 tmpfiles.d 机制去设置目录权限,但 /var/lib/nginx/body/
并不是系统默认管理的目录(没有相关配置文件),所以 ExecStartPost
更直接、更有效、更好控制。
后记:
如果你使用的是 CloudPanel 并为上传失败、权限丢失头疼,不妨试试这套方案,稳定、优雅、一次配置,永久省心!