搜索全站
安全防护 8 分钟阅读

chown 修复 WordPress 文件属主:解决无法更新与写入失败

用 root 上传或解压文件后,WordPress 会无法更新、无法上传。本文讲清如何判断当前属主、用 chown 批量修正、处理不同 Web 服务用户(www-data/nginx/apache)的差异、Docker 环境的 UID 映射,以及部署流程中避免属主再次错乱的做法。

U
UFO_PF 2019-10-13 · 阅读 8 分钟
ch 安全防护
阅读提示
本文约 3,124 字,预计阅读 8 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:权限对了还写不了,多半是属主错了

上一节讲了 755/644。但很多人照做之后依然失败——因为权限位是给属主的,如果属主是 root,那么 644 的”属主可写”是对 root 生效的,PHP 进程(www-data)属于”其他”组,只有读权限。

属主问题常在这些操作后出现:

  • 用 root 解压 WordPress 安装包;
  • 用 root 执行 git pull 或 wp 命令;
  • 用 root 通过 SFTP 上传主题;
  • 从另一台服务器 rsync 过来(保留了原属主)。

原理分析:Linux 判定写权限的顺序

Linux 检查权限时按顺序匹配,命中即停止:

  1. 你是文件属主吗?→ 用属主位(u)权限;
  2. 你属于文件属组吗?→ 用属组位(g)权限;
  3. 都不是 → 用其他位(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 参数直接指定目标属主,避免迁移后还要单独修一遍。

常见踩坑与失败案例

  1. chown -R 后 wp-config.php 权限变 644 —— chown 不改权限位,但如果之前是 600 且属主变了,PHP 可能读不到。改完属主后确认 wp-config.php 是可读的。
  2. 案例:运维用 root 跑 wp media regenerate,生成的缩略图属主是 root,之后后台删不掉这些图片。修复是 chown -R www-data:www-data wp-content/uploads,之后所有 WP-CLI 命令都加 sudo -u www-data。
  3. 只改了 wp-content 没改根目录 —— 更新核心时仍失败,因为核心文件属主不对。用 -R 覆盖整个站点。
  4. NFS / 对象存储挂载 —— chown 可能无效(取决于挂载选项),需要在存储端配置。
  5. 共享主机无法 chown —— 只能通过面板改权限为 755/775,或联系主机商。

总结

属主问题的本质是”谁在写文件”。判断流程:先看 ls -la 确认属主 → 查 PHP-FPM 配置确认正确用户 → chown -R 修正 → 用 sudo -u 用户 touch 验证。预防措施更重要:所有涉及 WordPress 文件的操作都用 PHP 用户身份执行(sudo -u www-data wp ...),部署脚本末尾固定跑一次属主修复。养成这个习惯后,”无法更新””无法上传”这类问题基本不会再出现。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。