Typecho 博客上传图片失败?Ubuntu 升级后目录权限丢失的排障复盘

Typecho 博客上传图片失败?Ubuntu 升级后目录权限丢失的排障复盘

Typecho 博客上传图片失败?Ubuntu 升级后目录权限丢失的排障复盘

Ctrl+D 收藏本站 再次访问不迷路 ~
AI摘要:文章讲述了作者在升级Ubuntu系统后,Typecho博客上传图片失败的排障过程。问题源于升级后目录权限丢失,导致PHP-FPM无法写入。通过检查日志、确认目录权限和属主,最终通过修改目录属主为`www:www`解决问题。文章总结了排查步骤和注意事项,强调权限问题通常是上传失败的原因。
2026-11-06 · 技术排障
站点:02博客网(Typecho 1.3.0 + Joe 主题,宝塔面板,PHP 8.4)

起因:换系统后,上传功能突然罢工

2026 年 10 月底,我把博客服务器从 Ubuntu 20.04 升级到 Ubuntu 24.04,宝塔面板、PHP 版本、Typecho、Joe 主题、插件全部沿用之前的配置。一切看起来正常,网站访问、后台登录、文章编辑都没问题。

直到 11 月 5 日,在后台编辑文章时上传图片,弹出一句冷冰冰的提示:"1.png 上传失败"。

换默认主题、禁用插件、重启 PHP-FPM——全都试过,问题依旧。之前Typecho 的上传机制一直很稳定。

过程:一次层层剥开的排查

第一步:确认不是插件的问题

先怀疑是图片压缩插件(SwitchImges,自动转 WebP)在捣乱。禁用插件后上传依然失败,说明问题在更底层的 Typecho 原生上传路径。

第二步:定位到 move_uploaded_file 失败

在 Typecho 的 var/Widget/Upload.php 里加了 DEBUG 日志,跟踪上传流程:

[Upload DEBUG] upload() called, method=POST, files=1
[Upload DEBUG] file: name=1.png err=0 tmp=/tmp/phpxxx
[Upload DEBUG] is_uploaded=true
[UploadHandle DEBUG] ext=png
[UploadHandle DEBUG] checkFileType=true
[UploadHandle DEBUG] upload path=/www/wwwroot/book.02clouds.cn/usr/uploads/2026/11, is_dir=true
[UploadHandle DEBUG] about to move file, path=/www/wwwroot/book.02clouds.cn/usr/uploads/2026/11/xxxx.png
[UploadHandle DEBUG] move_uploaded_file result=false
[UploadHandle DEBUG] move failed! src_exists=true
[UploadHandle DEBUG] move failed! dest_dir_exists=true
[UploadHandle DEBUG] move failed! dest_dir_writable=false

关键就在最后一行:dest_dir_writable=false。 上传目录对 PHP-FPM 来说不可写。

第三步:找到权限丢失的根因

lsattr /www/wwwroot/book.02clouds.cn/.user.ini
# 输出:----i---------e-------  (immutable 属性,宝塔保护)

namei -l /www/wwwroot/book.02clouds.cn/usr/uploads/2026/11/
# 输出:drwxr-xr-x root root ...  (属主是 root,不是 www)

Ubuntu 20 → 24 升级时,宝塔重建了 www 用户(新 UID 1000),但旧站点目录的属主没有同步更新——目录还是 root:root,PHP-FPM 以 www 用户运行,没有写入权限。

Ubuntu 20 上这些目录属主是 www,所以一切正常。升级后用户重建,目录没跟着改,上传功能就悄悄挂了。

第四步:修复

chown -R www:www /www/wwwroot/你的站点目录

一条命令,上传功能立即恢复。

修复方法总结

如果你也遇到 Typecho(或 WordPress 等 PHP 博客)上传图片失败,按这个顺序排查:

  1. 看 PHP 错误日志:宝塔面板 → PHP 设置 → 错误日志,找 move_uploaded_file 或 is_uploaded_file 相关报错
  2. 检查目录权限:ls -la 看 uploads 目录属主,应该是 www:www,如果是 root:root 就是问题
  3. 确认 PHP-FPM 用户:宝塔 PHP 8.4 的 FPM 进程以 www 用户运行,ps aux | grep php-fpm 能看到
  4. 修复权限:chown -R www:www /www/wwwroot/你的站点目录
  5. 重启 PHP-FPM:宝塔面板 → 软件商店 → PHP 8.4 → 重启(让权限生效)

如果用的是其他面板(aaPanel、1Panel 等),原理一样:站点目录属主必须和 PHP-FPM 运行用户一致。

警示:这些坑我替你踩过了

坑 1:系统升级后,权限不会自动迁移

这是最隐蔽的坑。从 Ubuntu 20 升 24、或者换了服务器重装宝塔,www 用户的 UID 可能变了,但已有站点目录的属主不会自动更新。升级后第一件事,检查所有站点的目录属主。

坑 2:宝塔的 .user.ini 有 immutable 保护

.user.ini 被宝塔设了 chattr +i(immutable 属性),直接 echo > 或 cp 覆盖会报 Operation not permitted。改之前要先 chattr -i /www/wwwroot/你的站点/.user.ini,改完可以再 chattr +i 恢复保护。

坑 3:PHP 8.4 的 open_basedir 限制

如果 .user.ini 里设了 open_basedir,注意它限制的是 PHP 进程能访问的路径范围。如果插件需要调用外部工具(如 FFmpeg、ImageMagick),要把工具路径也加进 open_basedir,否则插件里的 is_file('/usr/local/bin/ffmpeg') 会被 PHP 拒绝。

坑 4:换主题、换编辑器都没用

上传失败时,换默认主题、换编辑器都没用,因为问题在 Typecho 原生的 Widget\Upload 层,不在主题或编辑器。先看日志,再猜原因,别乱换东西。

坑 5:改代码加 DEBUG 是最快的排查方式

在 var/Widget/Upload.php 的 uploadHandle 方法里加 error_log,把每个关键步骤的返回值打到日志里,比看 nginx access log 猜快得多。日志会告诉你 $_FILES 有没有数据、is_uploaded_file 返回什么、move_uploaded_file 成功还是失败、失败时目录可不可写——所有答案都在日志里。

一句话总结

上传失败 90% 是权限问题,不是代码问题。 看到"上传失败"先查目录属主,比折腾插件、换主题、重启 PHP 都管用。


本文基于真实排障记录整理,站点信息已脱敏。如果你也遇到类似问题,欢迎留言交流。

©版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容