本文约 3,124 字,预计阅读 8 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:权限对了还写不了,多半是属主错了
上一节讲了 755/644。但很多人照做之后依然失败——因为权限位是给属主的,如果属主是 root,那么 644 的”属主可写”是对 root 生效的,PHP 进程(www-data)属于”其他”组,只有读权限。
属主问题常在这些操作后出现:
- 用 root 解压 WordPress 安装包;
- 用 root 执行
git pull或wp命令; - 用 root 通过 SFTP 上传主题;
- 从另一台服务器
rsync过来(保留了原属主)。
原理分析:Linux 判定写权限的顺序
Linux 检查权限时按顺序匹配,命中即停止:
- 你是文件属主吗?→ 用属主位(u)权限;
- 你属于文件属组吗?→ 用属组位(g)权限;
- 都不是 → 用其他位(o)权限。
所以:
- 文件属主 root、权限 644 → www-data 属于”其他”,只读;
- 文件属主 www-data、权限 644 → www-data 命中属主位,可写;
- 文件属主 root、属组 www-data、权限 664 → www-data 命中属组位,可写。
第三种(属主 root + 属组 www-data + 664)是很多人喜欢的”折中方案”:你用 SSH 登录能改,PHP 也能写,同时”其他”用户仍然只读。这个方案在多人协作时很实用。
保姆级实操
第一步:查看当前属主
ls -la /var/www/mimangfei.com
ls -la /var/www/mimangfei.com/wp-content/uploads | head
第二步:确认 PHP / Web 用户
# PHP-FPM 池用户
grep -E '^(user|group)' /etc/php/8.2/fpm/pool.d/www.conf
# Nginx worker 用户
grep -E '^user' /etc/nginx/nginx.conf
# Apache
grep -E '^(User|Group)' /etc/apache2/apache2.conf 2>/dev/null
常见值:
| 环境 | Web/PHP 用户 |
|---|---|
| Ubuntu/Debian + Nginx | www-data |
| Ubuntu/Debian + Apache | www-data |
| CentOS/RHEL + Nginx | nginx |
| CentOS/RHEL + Apache | apache |
| 宝塔 | www |
| Docker 官方镜像 | www-data(UID 33) |
第三步:修正属主
# 全部改为 PHP 用户
sudo chown -R www-data:www-data /var/www/mimangfei.com
# 或者:属主 root、属组 www-data
sudo chown -R root:www-data /var/www/mimangfei.com
sudo find /var/www/mimangfei.com -type d -exec chmod 775 {} \;
sudo find /var/www/mimangfei.com -type f -exec chmod 664 {} \;
sudo chmod 640 /var/www/mimangfei.com/wp-config.php
第四步:验证
用 PHP 用户身份测试写入:
sudo -u www-data touch /var/www/mimangfei.com/wp-content/.perm-test && echo OK
sudo -u www-data rm /var/www/mimangfei.com/wp-content/.perm-test
或用 WP-CLI 验证:
sudo -u www-data wp core check-update
sudo -u www-data wp plugin list
第五步:Docker 环境的 UID 映射
官方 wordpress 镜像里 www-data 的 UID/GID 是 33。宿主机挂载目录需要匹配:
sudo chown -R 33:33 /volume1/docker/wordpress/html/wp-content
或者用 user: 指令指定:
wordpress:
user: "33:33"
第六步:部署流程中避免属主错乱
在部署脚本末尾统一修复:
#!/usr/bin/env bash
set -euo pipefail
cd /var/www/mimangfei.com
git pull origin main
composer install --no-dev --optimize-autoloader
sudo chown -R www-data:www-data /var/www/mimangfei.com
find /var/www/mimangfei.com -type d -exec chmod 755 {} \;
find /var/www/mimangfei.com -type f -exec chmod 644 {} \;
wp --allow-root cache flush
wp --allow-root rewrite flush
更好的做法是用 deploy 用户而不是 root 部署,并把 deploy 加入 www-data 组:
sudo usermod -aG www-data deploy
第七步:rsync 迁移时的属主处理
rsync -avz --chown=www-data:www-data user@old:/var/www/site/ /var/www/site/
用 --chown 参数直接指定目标属主,避免迁移后还要单独修一遍。
常见踩坑与失败案例
chown -R后 wp-config.php 权限变 644 —— chown 不改权限位,但如果之前是 600 且属主变了,PHP 可能读不到。改完属主后确认wp-config.php是可读的。- 案例:运维用 root 跑
wp media regenerate,生成的缩略图属主是 root,之后后台删不掉这些图片。修复是chown -R www-data:www-data wp-content/uploads,之后所有 WP-CLI 命令都加sudo -u www-data。 - 只改了 wp-content 没改根目录 —— 更新核心时仍失败,因为核心文件属主不对。用
-R覆盖整个站点。 - NFS / 对象存储挂载 —— chown 可能无效(取决于挂载选项),需要在存储端配置。
- 共享主机无法 chown —— 只能通过面板改权限为 755/775,或联系主机商。
总结
属主问题的本质是”谁在写文件”。判断流程:先看 ls -la 确认属主 → 查 PHP-FPM 配置确认正确用户 → chown -R 修正 → 用 sudo -u 用户 touch 验证。预防措施更重要:所有涉及 WordPress 文件的操作都用 PHP 用户身份执行(sudo -u www-data wp ...),部署脚本末尾固定跑一次属主修复。养成这个习惯后,”无法更新””无法上传”这类问题基本不会再出现。
