WordPress 安装或更新插件提示「无法创建目录」:权限、磁盘空间与 FS_METHOD 排查

典型现象:后台「插件 → 安装插件」或「更新」时弹出「无法创建目录」「Could not create directory」「Installation failed」;主题上传同样失败;有时媒体库上传正常,只有解压到 wp-content/plugins / themes 才挂。FTP/SSH 能登录服务器,但 WordPress 自己写不进去。

多数不是「WordPress 坏了」,而是 Web 进程对 wp-content 没有写权限、磁盘/inode 满了、open_basedir 拦住了解压路径,或主机强制要求 FTP/FS_METHOD 却没配对。下面按「先看完整报错 → 查磁盘与 inode → 查属主权限 → 查 open_basedir → 再定 FS_METHOD」走。

0. 先把完整错误记下来

安装失败时不要只截半截弹窗。打开:

  1. 浏览器开发者工具 Network,看 update.php / admin-ajax.php 的响应正文;
  2. 若已开 WP_DEBUG_LOG,看 wp-content/debug.log 里同一时刻的 PHP Warning/Fatal。

把原文关键词对齐:

报错片段 优先怀疑
无法创建目录 / Could not create directory 目录权限或属主
没有足够的权限 / Destination folder already exists 后半截失败 半截目录残留 + 权限
Could not copy file / Failed to write 磁盘满或只读挂载
Unable to locate WordPress content directory WP_CONTENT_DIR / 路径配置异常
要求输入 FTP 主机 主机判定「直接写文件系统不可用」

先别改 FS_METHOD,否则会掩盖真正的权限问题。

1. 查磁盘空间与 inode

SSH 到站点所在机器(跑 PHP-FPM / Apache 的那台):

bash 复制代码
df -h /
df -i /
# 若站点在独立挂载,换成实际挂载点,例如
df -h /var/www && df -i /var/www

Use% 接近 100%,或 inode 用尽(IUse% 100%)时,创建目录必然失败,表现却常被说成「权限问题」。清日志、旧备份、wp-content/uploads 里的残留大文件后再试。

临时确认 Web 用户能否在插件目录建文件夹:

bash 复制代码
# 把路径换成你的站点;用户名按发行版:www-data / nginx / apache
sudo -u www-data mkdir -p /var/www/example.com/wp-content/plugins/_write_test \
  && sudo -u www-data rmdir /var/www/example.com/wp-content/plugins/_write_test \
  && echo OK || echo FAIL

FAIL 就先修权限,不要急着填 FTP。

2. 核对 wp-content 属主与权限

WordPress 后台解压插件用的是 PHP 进程用户 ,不是你 SSH 登录的个人账号。常见错法:用 root 解压过主题/插件,目录属主变成 root,www-data 再也写不进去。

bash 复制代码
SITE=/var/www/example.com
# 看当前属主
ls -la $SITE/wp-content
ls -la $SITE/wp-content/plugins | head
# 按实际 Web 用户调整(Debian/Ubuntu 常见 www-data)
sudo chown -R www-data:www-data $SITE/wp-content
# 目录可写、文件可读(按主机规范微调;勿一刀切 777)
sudo find $SITE/wp-content -type d -exec chmod 755 {} \;
sudo find $SITE/wp-content -type f -exec chmod 644 {} \;

注意:

  1. 共享主机若面板指定了专用用户(如 u123456),属主必须跟面板一致,不要强行改成 www-data;
  2. 修完权限后,删掉上次失败留下的半截目录(例如 plugins/some-plugin 空壳),再在后台重装;
  3. 不要图省事对整个站点 chmod -R 777,后续会被安全扫描盯上,也解决不了属主错误。

3. 查 open_basedir 与只读挂载

部分面板会给 PHP 加 open_basedir,解压临时目录若落在限制外,也会报「无法创建目录」。

bash 复制代码
# CLI 与 FPM 可能不是同一份配置,以后台 phpinfo 或面板为准
php -i | grep -E 'open_basedir|upload_tmp_dir|sys_temp_dir'

在站点健康或临时 phpinfo() 页确认 Web 所用 的 open_basedir 是否包含:

  • 站点根与 wp-content;
  • PHP 上传/系统临时目录(常见 /tmp)。

若站点在只读根文件系统 + 可写数据盘的容器里,确认 wp-content 挂在可写卷上:

bash 复制代码
findmnt -T /var/www/example.com/wp-content
touch /var/www/example.com/wp-content/.rw_test && rm /var/www/example.com/wp-content/.rw_test && echo writable

4. 何时才改 FS_METHOD

仅当 Web 用户确实不能 直接写 wp-content,而主机又提供了可靠的 FTP/SSH 写通道时,再在 wp-config.php(That's all, stop editing! 之前)指定方式:

php 复制代码
// 直接写本地文件系统(多数 VPS / 容器首选;能直接写就不要改)
define('FS_METHOD', 'direct');

// 仅在主机强制 FTP 时再考虑(需同时能在后台填对账号,或 define FTP_*)
// define('FS_METHOD', 'ftpext');

验证建议:

  1. 设 direct 前,先用上一节的 sudo -u www-data mkdir 测通;测不通就先修权限;
  2. 改完 wp-config.php 后清对象缓存(若有),再试安装一个很小的插件;
  3. 若弹 FTP 框:核对主机名(多数是 localhost 或面板给出的内网 FTP)、端口、账号是否对同一站点目录有写权限;账号对了但路径指到别的家目录,仍会「无法创建目录」。

5. 残留半截目录与「Destination folder already exists」

更新失败时,常留下不完整的 wp-content/plugins/foo。下次再装同名插件会卡在「目标文件夹已存在」或解压覆盖失败。

处理:

  1. 先在插件列表停用(若还显示);
  2. SSH/SFTP 删掉该插件目录(先备份);
  3. 确认父目录 plugins 属主正确后,再从后台干净安装或上传 zip。

主题同理,目录在 wp-content/themes。

6. 快速验收清单

做完一轮后,用同一条路径验收:

bash 复制代码
sudo -u www-data mkdir -p /var/www/example.com/wp-content/plugins/_write_test \
  && sudo -u www-data rmdir /var/www/example.com/wp-content/plugins/_write_test

后台再装一个体积小的插件或主题:应不再出现「无法创建目录」。若媒体上传也曾经失败,可对照同一套权限/磁盘结论一起核对。


本文由 DEVDIY 整理。我们日常更多在做 WordPress / Shopify 外贸站和微信小程序的具体开发与故障排查,把排障步骤写清楚方便自己和同行复用。

原文/延伸阅读:https://devdiy.cn/wordpress/

相关推荐
李纲明4 小时前
WordPress 询盘同步不到 CRM 或来源丢失:先核推送接口与隐藏字段,再查去重
crm·wordpress·去重·devdiy·表单线索·来源追踪·隐藏字段
李纲明6 小时前
微信小程序租赁归还说本来就坏或配件对不上:先核借还点验与随单存证,再查差异计价公示
微信小程序·devdiy·租赁点验·借还拍照·随单存证·差异计价·押金释放
李纲明6 小时前
WordPress 备份做了却还原失败或只放在本机:先核异地存放与文件完整性,再做恢复演练
数据恢复·wordpress·异地备份·恢复演练·devdiy·网站备份·备份完整性
李纲明17 小时前
WordPress 打开页面直接报 500 而不是白屏:先核伪静态与文件权限,再查服务器错误日志
nginx·wordpress·文件权限·伪静态·错误日志·devdiy·500错误
李纲明1 天前
WordPress 更新插件后按钮没反应或表单结账突然失效:先留日志与备份,再按二分法定位冲突插件
wordpress·二分法·插件冲突·devdiy·debug.log·health check·更新插件
李纲明1 天前
微信小程序次卡跨店对不上账或前台随手改余次:先核流水只增不改与统一日切,再查冲正权限与总部只读
微信小程序·devdiy·核销流水·跨店次卡·日切对账·冲正权限·总部只读
李纲明1 天前
微信小程序维修拆机后口头加价或未确认就开工:先核验机快照与报价确认,再查补充报价与取机核验
微信小程序·devdiy·维修验机·报价确认·报价快照·补充报价·取机核验
李纲明1 天前
WooCommerce 加购后购物车是空的或结账串了会话:先核页面缓存排除与会话 Cookie,再查 CDN 与对象缓存前缀
cdn·页面缓存·购物车·woocommerce·对象缓存·devdiy·会话cookie
李纲明1 天前
微信小程序场地长租月底对不上或口头占场撞场:先核合约预约与核销流水出账,再查附加费与转租归属
微信小程序·devdiy·场地长租·月结账单·核销流水·附加费·转租归属
李纲明2 天前
WordPress 首页 LCP 很差或首屏大图很晚才出来:先分清是未压缩原图还是脚本挡住渲染,再查字体与预加载
字体·wordpress·图片优化·预加载·lcp·core web vitals·devdiy