VPS 上的 Memos 升级到 0.31:RSS、访问权限与备份回退怎么处理

已有VPS实例升级Memos0.31前,处理RSS移除与管理员权限变化,分开配置URL和访问模式,并做好SQLite停机备份及匹配旧版本的数据回退。

·10 minDockerVPSMemos备份
把应用部署到土耳其|BRNCHOST · 土耳其 VDS
云服务器,积分可续期|雨云 · 国内外节点 · 积分兑换权益
低价年付,大流量 VPS|RackNerd · SSD 存储 · 1Gbps 端口
香港轻量,搭个小站|晚安云 · 香港云服务器
香港 VPS,大带宽可选|野草云 · BGP 直连
大陆访问,精品线路|搬瓦工 · CN2 GIA / CTGNet 套餐
资料归档,交给 AI 整理|WorkBuddy · 本地文件处理
建站起步,先看应用镜像|腾讯云 · 轻量应用服务器
CN2 GIA,中国方向优化|DMIT · Premium 网络
双 ISP 原生住宅 IP|丽萨主机 · 美国 9929 精品线路
高频 CPU,多地部署|Evoxt · 云服务器 · 每周异地备份
京东云轻量云主机:129元/年,新人专享,限购1台

如果 VPS 上已经运行 Memos,升级到 0.31 前先看自己怎么使用它:有没有把公开笔记订阅到阅读器,是否多人共用,附件放在哪,浏览器扩展和脚本又调用了哪些接口。这次更新加入了 Spaces、日历和地图。更新镜像之前,还需要处理旧订阅和权限变化。

本文围绕 Docker Compose 管理的单机实例,给出一套升级安排。示例的数据库是 SQLite,数据通过宿主机目录持久化。使用外部 PostgreSQL、MySQL 或对象存储的实例,需要另外备份对应数据,不能直接照搬目录打包方案。

RSS 订阅会停,先处理依赖它的地方

Memos 0.31.0 的正式发布说明明确移除了 RSS。过去的 Explore 和用户订阅地址不再提供订阅内容,旧地址返回 404;新版没有可以直接替换的内置 RSS 入口。

这会影响把公开笔记当作微型博客、通过 RSS 阅读器追踪更新的人。如果阅读器里只有历史缓存,看上去可能仍然有文章,但之后不会继续更新。升级前把这类订阅列出来,也检查定时脚本、网页组件和自动化平台是否还在读取旧 feed。

API 和 webhook 可以用于不同的集成任务,但它们不是 RSS 地址的直接替换。阅读器通常需要订阅格式;API 要处理认证、分页和更新逻辑,webhook 则要有接收事件的服务。如果目前依赖 RSS,又没有替代安排,可以先保留现有版本,评估相关维护与安全风险后再决定升级时间。不要为了更新界面,悄悄中断已经在使用的订阅。

Memos 官方升级文档中的 0.31 访问策略说明

图中是官方升级文档页面,并非本站运行实例的界面。迁移前应查看自己跨过的每个版本,不能把旧版教程中的功能描述直接套到新版。

共享实例要重新理解“私密”

0.31 的实例管理员与 Space 管理员有不同权限。正式版说明中,处于有效状态的实例管理员可以读取和管理单条笔记,包括私密笔记和仅 Space 成员可见的笔记,即使管理员不是作者,也没有加入对应 Space。集合列表仍按可见范围过滤;这不意味着管理员会自动成为 Space 成员。

因此,在朋友或同事维护的 Memos 实例中把笔记设为私密,不等于只有自己在技术上能够读取它。服务器运营者本来就可能接触数据库、备份和存储,现在还需要了解应用本身的权限。密码、数据库连接串、身份证件和其他敏感材料,不应仅靠一项“私密”设置来隔离。

如果是个人 VPS、个人管理账号,这项变化通常不会改变日常使用方式。如果多人共用,升级之前就应把权限告诉使用者;不能等升级后才发现大家对隐私范围有不同理解。

Spaces 用来组织共同使用的笔记,并不取消笔记作者和成员关系的作用。旧笔记升级后保持原有身份与可见性,不会自动归入一个默认 Space。尤其要注意删除操作:移除成员与删除整个 Space 是两回事,删除 Space 会永久删除直接分配给它的笔记及其拥有的资源。整理旧内容时,先确认归属,再决定是否删除。

URL 与访问模式现在分别配置

MEMOS_INSTANCE_URL 表示实例对外使用的标准地址。0.31 把实例的公开或私密访问模式与这个 URL 分开,配置了域名并不代表必须开放匿名阅读,之后修改域名也不会自动改变已有的访问策略。

部署配置文档提供了文件管理方式。以下配置用于已经决定采用私密实例、并由部署文件控制访问模式的场景。不要在升级时顺便覆盖现有 SSO、存储或其他完整配置组。

在 Compose 文件所在目录创建 memos-secrets/memos-instance-setting-access.json:

{
  "key": "ACCESS",
  "accessSetting": {
    "accessMode": "INSTANCE_ACCESS_MODE_PRIVATE"
  }
}

该文件通过只读挂载交给 Memos。匹配文件必须能被容器用户读取,内容错误会阻止启动。文件配置在启动时加载并对该进程生效,不能假设修改文件后应用会自动重载。这个访问模式也不会撤销已经存在的分享链接;如需停止分享,要另外检查和处理分享记录。

下面是单机 SQLite 的 Compose 参考配置。它展示升级后的目标形态;已有实例只修改确认需要的项,原来的数据目录、数据库驱动和容器名称要保持一致。

services:
  memos:
    image: neosmemo/memos:0.31.0
    container_name: memos
    restart: unless-stopped
    ports:
      - "127.0.0.1:5230:5230"
    volumes:
      - ./data:/var/opt/memos
      - ./memos-secrets:/etc/secrets:ro
    environment:
      MEMOS_PORT: 5230
      MEMOS_DRIVER: sqlite
      MEMOS_INSTANCE_URL: https://memos.example.com

memos.example.com 是示例域名,要换成自己的地址。这里把端口绑定到本机回环地址,适合宿主机上的反向代理连接;如果 Caddy 也在容器内,不能直接把另一个容器的 127.0.0.1 当作 Memos,需要使用共享容器网络和服务名。

给宿主机 Caddy 增加站点时,可以使用下面的入口。域名应指向服务器,80、443 端口应按证书和访问需求开放;Memos 的 5230 端口不用额外开放到公网。

memos.example.com {
    reverse_proxy 127.0.0.1:5230
}

这套配置强调固定版本。stable 标签会随发布变化,重新拉取时可能取到不同版本;0.31.0 让升级目标清楚,也便于保存与备份配套的部署记录。它仍需要后续维护,不意味着可以永久不更新。

先确认旧版本和数据目录,再停机备份

不要从网上复制一个 ./data 路径,就认定自己的笔记在那里。有人使用命名卷,有人改过宿主机目录,也有人把附件放到 S3。先在原部署目录查看 Compose 文件和实际挂载:

docker compose ps
docker inspect memos --format '{{range .Mounts}}{{println .Source "->" .Destination}}{{end}}'
docker inspect memos --format '{{.Config.Image}}'

示例容器名是 memos;名称不同要相应替换。记录当前镜像版本或镜像摘要,保留原 Compose 文件及环境文件,弄清所有附件存储位置。不要把含密钥的配置、日志和备份放到公开仓库。

对于本文的 SQLite、./data 挂载,停掉服务后打包完整目录,能避免在持续写入时只复制数据库主文件。下面的命令在原 Compose 目录执行,假定使用的是 compose.yaml,且没有其他进程写入这份数据库:

umask 077
backup_dir="./backups/before-memos-031-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$backup_dir"
cp compose.yaml "$backup_dir/compose.yaml"
docker compose stop memos
sudo tar -czf "$backup_dir/data.tar.gz" -C ./data .
sudo tar -tzf "$backup_dir/data.tar.gz" > /dev/null

目录权限、磁盘剩余空间、实际文件名都应事先确认。如果打包失败,先处理备份问题,不要继续升级。只想恢复旧服务时,保持原配置并启动原版本即可。备份目录也应再复制到另一处可靠存储;与实例放在同一块盘上的文件无法应对整机或磁盘损坏。

这里的 tar 列表检查只能证明归档可读取,不证明恢复后的应用一定可用。涉及对象存储时,目录打包不会包含远端对象;要保存被旧附件引用的存储配置和对象。使用 PostgreSQL、MySQL 时还要做数据库备份,具体范围见官方备份说明。

个人导出适合搬走自己的内容,但不能替代实例备份。它不包含其他用户的数据与完整实例设置;多人实例恢复时,这些遗漏会直接影响账号、权限和使用方式。

拉取新镜像后,先看迁移日志

备份完成后,再修改原 Compose 中的镜像版本;访问策略文件也要先确认内容和权限。随后执行:

docker compose config --quiet
docker compose pull memos
docker compose up -d memos
docker compose logs --tail=100 memos

如果使用环境文件,保留原来加载该文件的方式,不要另开一个缺少参数的新部署。配置检查不启动应用,也不验证数据迁移;镜像成功拉取同样只说明文件下载完成。Memos 会在启动时运行数据库迁移,需要继续查看日志并访问应用。

登录之后,先打开一条旧笔记,检查标题、正文和附件,再写入一条可以删除的临时笔记。共享实例应分别用普通成员和管理员账号确认权限,也用退出登录的窗口确认匿名访问范围。反向代理域名下的附件、分享链接和登录跳转都要检查,不能只看容器处于运行状态。

旧的 Shortcuts 会迁移到 Views,但外围程序不一定自动适应。调用 Shortcut API 的脚本需要改为对应 View 操作;保存的页面入口也要检查。0.31 的 reaction API 不再接受 contentId,还在传旧字段的集成要更新。先按实际使用的客户端逐个核对,暂时用不上的集成可以停用,避免后台一直报错却没人发现。

出问题时,把程序与数据一起恢复

官方升级指南明确指出,已经迁移过的数据库不能交给旧版本直接使用。把镜像标签改回去,并不是完整回退。

需要回退时,先停止新版本,保留失败现场的数据和日志,避免丢失升级之后的写入记录。然后用升级前备份恢复到一个独立目录,恢复对应版本的 Compose 与环境配置,再让旧版本连接恢复的数据。外部数据库与对象存储也要按对应备份恢复,不能只恢复 SQLite 示例中的一个目录。

例如,在另一个空的部署目录中还原本文的停机归档:

mkdir -p ./data
sudo tar -xzf /path/to/backup/data.tar.gz -C ./data

/path/to/backup/data.tar.gz 是占位路径。还原后检查数据目录的所有者和容器读取权限,并把升级前保存的配置放回对应位置。确认旧镜像版本、挂载路径和访问入口之后再启动。不要把恢复的数据混入迁移后的目录,也不要通过删除现有数据库来试错。

如果升级后已经产生新笔记,恢复升级前备份会丢掉这些新增数据。是否等待修复、另行导出新增内容或正式回退,要在重启写入之前决定。小型个人实例可以安排短暂停写窗口;多人实例则应提前约定维护时间。