
Memos 如何设置实例访问模式 ACCESS 并理解首次启动的一次性初始化行为【免费下载链接】memosOpen-source, self-hosted note-taking tool built for quick capture. Markdown-native, lightweight, and fully yours.项目地址: https://gitcode.com/GitHub_Trending/me/memos在 Memos 的部署环境中ACCESS是实例级的访问策略设置它通过InstanceAccessMode枚举控制未认证用户能否访问实例内容只有两个合法值INSTANCE_ACCESS_MODE_PRIVATE和INSTANCE_ACCESS_MODE_PUBLIC见 proto/api/v1/instance_service.proto。部署者需要在启动阶段确定访问模式并理解一件事旧版本靠实例 URL 是否为空来决定匿名访问的 legacy 行为在新版本中会被一次性固化成数据库里的ACCESS行——这是本文要讲清楚的两件事如何把ACCESS显式配置成你想要的模式以及首次启动时这一行是怎么产生的、之后为什么不会再变。两个关键边界先说清楚规范的对外实例 URL--instance-url参数或环境变量MEMOS_INSTANCE_URL是独立的部署属性不决定谁可以访问实例它只要求是绝对 HTTP(S) URL不能带凭据、query 或 fragmentMemos 会在启动时裁剪首尾空白和尾部斜杠。实例 URL 一旦用于首次初始化后续增删或修改它永远不会改变访问策略。部署文件扫描的基本规则Memos 在数据库迁移和 demo 种子数据之后、HTTP 与后台服务启动之前扫描/etc/secrets目录默认目录见 store/deployment_config.go只读取文件名符合模式的直接子文件不递归子目录、不创建或修改目录中的任何内容。规则摘要完整说明见 docs/configuration-provisioning.md实例设置文件名模式为memos-instance-setting-label.jsonlabel必须是小写 kebab 形式[a-z0-9](?:-[a-z0-9])*ACCESS的规范文件名是memos-instance-setting-access.json。每个文件必须是且仅包含一条memos.store.InstanceSetting的 protobuf JSON不允许未知字段不能超过 1 MiB消息里的key才是资源身份改文件名不会改变资源身份。同一个设置 key 只允许一个文件声明BASIC和TAGS这两个 key 不允许通过部署文件配置会被拒绝。目录不存在、或目录可读但没有匹配文件属于正常空操作目录或匹配文件不可读则是启动错误。启动日志会打印各资源类型的匹配数量因此拼错的文件名是可以被发现的以memos-开头但不匹配支持模式的直接子文件会产生警告。任何一个匹配文件无效快照就不会发布启动直接失败。方式一通过部署文件固定 ACCESS 模式这是部署场景的主路径把访问策略作为部署配置随进程生命周期生效且不会被 UI 或 API 写操作改掉。在/etc/secrets/memos-instance-setting-access.json写入文档中的示例{ key: ACCESS, accessSetting: { accessMode: INSTANCE_ACCESS_MODE_PRIVATE } }需要公开实例时把accessMode改为INSTANCE_ACCESS_MODE_PUBLIC。注意accessMode必须显式选择 PRIVATE 或 PUBLIC省略或不指定会在启动校验时被拒绝accessSetting must be populated for key ACCESS / accessSetting.accessMode must be PRIVATE or PUBLIC。这个文件的运行效果文件声明的ACCESS组会整体遮蔽shadow数据库中同 key 的system_setting行认证、API 和后台服务读取到的都是文件中的值数据库里的行不被修改。UI 和管理员 API 对ACCESS的创建、更新、删除都会返回codes.FailedPreconditioninstance setting ACCESS is configured by the deployment前端会如实展示这个错误。删除文件并重启进程ACCESS回落到数据库里存储的值这不是恢复文件的值而是移除运行时覆盖。文件在启动后发生修改不生效必须重启进程。按安全要求/etc/secrets及其中文件应视为敏感明文建议使用仅限属主或应用组可读的文件系统权限日志不会记录文件内容。方式二通过管理员 API 更新 ACCESS没有部署文件时管理员可以在运行中的实例上通过 API 更新。UpdateInstanceSetting的路径是PATCH /api/v1/instance/settings/ACCESSresource 名称格式为instance/settings/{setting}见 proto/api/v1/instance_service.proto。请求需要携带管理员身份的认证凭据——实现中会检查当前用户非管理员会得到PermissionDenied见 server/router/api/v1/instance_service.go。请求体是setting资源本身update_mask字段存在但当前实现标注为待实现、实际未应用{ name: instance/settings/ACCESS, accessSetting: { accessMode: INSTANCE_ACCESS_MODE_PUBLIC } }两个适用条件如果ACCESS已由部署文件提供该请求会在任何校验之前被拒绝返回FailedPrecondition更新写入数据库后其他副本在下一次访问策略检查时即可看到变化——ACCESS的读取路径有意绕开了通用的十分钟实例设置缓存见 store/instance_setting.go 中GetInstanceAccessSetting避免 public 到 private 的收紧被别的进程用过期缓存的 public 判定放行。首次启动的一次性初始化行为这是升级或首次启用 ACCESS 支持时必须理解的机制。启动序列是见 docs/configuration-provisioning.md 与 store/migrator.go 中initializeInstanceAccessSetting初始化或迁移数据库 - 启用时应用 demo 种子数据 - 用 legacy 实例 URL 行为初始化缺失的 ACCESS 行 - 读取所有匹配的部署配置文件 - 解码并校验每个资源 - 校验相关的跨资源约束 - 发布一份不可变的运行时快照 - 构建 HTTP 与后台服务 - 开始接收请求一次性初始化的具体规则迁移阶段结束时如果数据库中还没有ACCESS行Memos 会创建一条数据库支持的ACCESS设置。取值来自 legacy 启动 profile 的规范实例 URL--instance-url/MEMOS_INSTANCE_URL非空时记为PUBLIC否则记为PRIVATE。这精确保留了旧版本实例 URL 非空即允许匿名访问的行为。这是一次性的兼容决定行存在之后无论实例 URL 如何增删或修改访问策略都不再随之改变要改变策略只能走上面两种显式途径。注意顺序数据库里这条行是在读取部署文件之前创建的。即使你挂载了ACCESS部署文件首次启动仍会先建立数据库行按实例 URL 推导随后文件再遮蔽它数据库行始终保留原值。如果部署文件在启动后被移除实例回落到这条数据库行的值——所以升级前就配了实例 URL 的旧实例在删掉部署文件后会回到PUBLIC而不是你以为的PRIVATE。验证配置是否生效文档给出的可核对信号启动日志成功加载部署配置时打印loaded deployment configuration附带 identity provider 与 instance setting 的匹配数量没有memos-instance-setting-*文件时该计数为 0。接口返回GET /api/v1/instance/profile返回的InstanceProfile中包含access_mode字段其值直接取自当前生效的访问策略数据库行与部署遮蔽均已解析GET /api/v1/instance/settings/ACCESS返回ACCESS设置资源可在响应中核对accessSetting.accessMode。行为判定生效模式为PUBLIC时允许匿名访问PRIVATE时不允许——实例策略检查函数AllowsAnonymousAccess只在模式等于PUBLIC时返回 true。失败信号ACCESS文件的accessMode省略、未知字段、非法枚举值、超过 1 MiB 等情况都会使启动失败且不会发布任何配置快照此时应修正文件后重启而不是部分降级运行。多副本与跨版本边界的限制每个副本在启动时独立加载部署配置同一部署的所有副本必须挂载相同的文件。滚动发布期间可能短暂同时存在新旧两代配置Memos 不做分布式协调修改认证或存储配置时应采用不会把流量路由到不同文件代际副本的发布策略。跨越引入ACCESS的版本边界需要协调发布旧副本会忽略ACCESS继续沿用实例 URL 非空即允许匿名访问的 legacy 规则。在修改ACCESS之前先排空所有旧副本回滚前则先把旧规则对齐到目标策略——目标为 public 时保证实例 URL 非空、目标为 private 时保证实例 URL 为空——再排空新副本。否则会出现存储策略为PRIVATE但实例 URL 非空的旧副本继续对外暴露实例的情况。小结三条路径的优先级同一时刻生效的ACCESS值只有一个存在部署文件时文件值遮蔽数据库行且 UI/API 写操作被拒不存在部署文件时数据库行生效且读取不受十分钟设置缓存拖累。首次启动时按实例 URL 推导出的那条数据库行是 legacy 行为的一次性快照理解这一点才能在删文件回退跨版本回滚修改实例 URL这些操作前正确预判实例最终是 PRIVATE 还是 PUBLIC。【免费下载链接】memosOpen-source, self-hosted note-taking tool built for quick capture. Markdown-native, lightweight, and fully yours.项目地址: https://gitcode.com/GitHub_Trending/me/memos创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考