016 · Memos 白屏 / 静态资源失败、502 与根盘满(PM2 日志)
问题现象
- 浏览器访问
memos.*:白屏;开发者工具中多个/assets/*.js报net::ERR_CONTENT_LENGTH_MISMATCH(Content-Length与实际下载字节不一致)。 - Memos 日志或接口侧出现
database or disk is full、failed to store refresh token、SQLitedisk I/O error。 - 经 Nginx 访问为 502;宿主机上
docker ps显示memos容器Exited,或podman system prune后已无memos容器。 - 容器日志中曾出现
/var/opt/memos is not writable(与磁盘满或权限并存时需区分)。
环境备注:宿主机 baotazhen-instance,容器引擎为 Podman,CLI 提示 Emulate Docker CLI using podman。
排查过程
- 用
curl比对静态 JS 的Content-Length与实际wc -c,确认为「宣称长度 ≫ 实际收到」,与浏览器报错一致。 df -h /:根分区Use% 100%,Avail 0,为阻塞写入的直接信号。df -i:inode 充足,排除「inode 满」作为主因。du -xh / --max-depth=1:/root约 25G;下钻/root/.pm2发现:/root/.pm2/pm2.log约 20G~21G/root/.pm2/logs/openclaw-bot-error.log约 3Gjournalctl --disk-usage:journal 约占 3.4G,执行journalctl --vacuum-size=200M可回收大量归档日志。podman system prune -a会删除 已停止的容器;当时memos已退出,导致 实例被删,仅靠start无法恢复,需docker/podman run重建。
根因
- 根分区被日志与大文件撑满,导致全机 写入失败:SQLite、Memos 数据目录、乃至 HTTP 下发异常(表现为静态资源半截、长度不匹配)。
- PM2 写入
pm2.log与应用 error 日志无有效轮转,长期在/root堆积到 数十 GB。 - Memos 容器在故障期间停止;清理磁盘时
prune删掉已停止实例,叠加 上游无监听 → Nginx 502。
解决方案(已验证)
腾出根分区空间(必做)
- 清空超大 PM2 日志(保留 inode,进程可继续写):
其它异常大的 *.log 可按 ls -lah /root/.pm2/logs 逐项处理。
- 收缩 systemd journal:
- (可选)
dnf clean all/yum clean all:清理包缓存。
恢复 Memos 容器(实例被删时)
确认本地镜像(示例):localhost/neosmemo/memos:stable(与 DaoCloud 拉取后经 docker tag 的产物一致)。
mkdir -p /data/memos
chmod 755 /data/memos
docker rm -f memos 2>/dev/null
docker run -d \
--name memos \
--restart unless-stopped \
-p 5230:5230 \
-v /data/memos:/var/opt/memos \
localhost/neosmemo/memos:stable
Podman 环境将 docker 换为 podman 即可;若 SELinux 导致数据卷不可写,可尝试挂载加 :z(按需)。
自检:
改进计划
pm2 install pm2-logrotate,限制单文件体积与保留份数;关注pm2.log是否仍会单列暴涨(必要时 cron +truncate或调低 daemon 日志级别)。- 排查
openclaw-bot高频报错,避免openclaw-bot-error.log再次滚到 GB 级。 - 宿主磁盘监控:告警阈值建议:
/可用空间低于约 15% 即处理;单盘 40G 场景下对/root、/var/log、journal 定期抽查。 - 执行
podman/docker system prune -a前确认memos等关键容器若为Exited会先被删掉,应先run再起或暂不 prune。
经验教训
「前端白屏 + 静态资源 CONTENT_LENGTH_MISMATCH」在无 CDN 自愈时,优先核对宿主机磁盘与应用日志,常与 SQLite / 反代异常同源;单靠 Nginx 调参不能代替 释放磁盘与修复写入。