# 通知 / digest / systemd 最终上线清单 这份清单按“上线前 -> 首次启动 -> 验证 -> 定时任务”来执行。 ## A. 上线前参数确认 ### 1. backend / compose 确认 `deploy/docker/config.yaml` 至少已经填写: - `compose_env.DATABASE_URL` - `compose_env.REDIS_URL` - `compose_env.JWT_SECRET` - `compose_env.APP_BASE_URL` - `compose_env.PUBLIC_API_BASE_URL` - `compose_env.ADMIN_API_BASE_URL` - `compose_env.ADMIN_FRONTEND_BASE_URL` - `compose_env.TERMI_ADMIN_TRUST_PROXY_AUTH=true` - `compose_env.TERMI_ADMIN_LOCAL_LOGIN_ENABLED=false` - `compose_env.TERMI_ADMIN_PROXY_SHARED_SECRET` ### 2. SMTP 订阅 double opt-in 和邮件通知需要: - `compose_env.SMTP_ENABLE=true` - `compose_env.SMTP_HOST` - `compose_env.SMTP_PORT` - `compose_env.SMTP_SECURE` - `compose_env.SMTP_USER` - `compose_env.SMTP_PASSWORD` - `compose_env.SMTP_HELLO_NAME` ### 3. Caddy / TinyAuth / Pocket ID 确认宿主机 Caddy 已经: - `blog.init.cool` -> `127.0.0.1:4321` - `admin.blog.init.cool` -> `127.0.0.1:4322` - `admin.blog.init.cool/api/*` -> `127.0.0.1:5150` - `admin.blog.init.cool` 整体挂了 `import tinyauth` - `/api/*` 转发时附带: - `X-Termi-Proxy-Secret: {$TERMI_ADMIN_PROXY_SHARED_SECRET}` 可直接参考: - `deploy/caddy/Caddyfile.tohka.production.example` ## B. 首次启动 推荐命令: ```bash python deploy/scripts/render_compose_env.py \ --input deploy/docker/config.yaml \ --output deploy/docker/.env docker compose \ -f deploy/docker/compose.package.yml \ -f deploy/docker/compose.tohka.override.yml \ --env-file deploy/docker/.env up -d ``` 然后确认容器状态: ```bash docker compose \ -f deploy/docker/compose.package.yml \ -f deploy/docker/compose.tohka.override.yml \ --env-file deploy/docker/.env ps ``` 应该至少看到: - `backend` - `backend-worker` - `frontend` - `admin` ## C. 首次验证 ### 1. 健康检查 ```bash curl -I http://127.0.0.1:5150/healthz curl -I http://127.0.0.1:4321/healthz curl -I http://127.0.0.1:4322/healthz ``` ### 2. 后台 SSO 打开: - `https://admin.blog.init.cool` 确认: - 可以被 TinyAuth / Pocket ID 正常拦截与登录 - 登录后后台可进入 - 会话信息显示为代理登录(不是本地账号密码) ### 3. 订阅链路 至少做一次: 1. 前台提交邮箱订阅 2. 收到确认邮件 3. 点击确认链接 4. 能打开偏好页 5. 偏好页可暂停 / 恢复 / 退订 ### 4. ntfy / webhook / digest 后台里至少验证一次: - 手动发送测试通知 - 手动发送周报 - 手动发送月报 - 查看 delivery 是否从 `queued` 变成 `sent` 如果 delivery 一直卡在 `queued`: - 优先检查 `backend-worker` 是否在运行 - 检查 `REDIS_URL` - 检查 SMTP / ntfy / webhook 目标 ## D. 安装 systemd timers ```bash sudo cp deploy/systemd/*.service /etc/systemd/system/ sudo cp deploy/systemd/*.timer /etc/systemd/system/ sudo systemctl daemon-reload ``` 启用: ```bash sudo systemctl enable --now termi-retry-deliveries.timer sudo systemctl enable --now termi-weekly-digest.timer sudo systemctl enable --now termi-monthly-digest.timer sudo systemctl enable --now termi-backup-all.timer sudo systemctl enable --now termi-backup-prune.timer sudo systemctl enable --now termi-backup-offsite-sync.timer ``` 查看状态: ```bash systemctl list-timers --all | grep termi ``` ## E. 当前默认调度时间 ### 通知 / digest - `termi-retry-deliveries.timer` - 每 5 分钟执行一次 - `termi-weekly-digest.timer` - 每周一 09:00 - `termi-monthly-digest.timer` - 每月 1 日 09:30 ### 备份 - `termi-backup-all.timer` - 每天 03:10 - `termi-backup-prune.timer` - 每天 04:15 - `termi-backup-offsite-sync.timer` - 每天 04:40 如果时区不是你们想要的,改 `.timer` 里的 `OnCalendar=` 后重新: ```bash sudo systemctl daemon-reload sudo systemctl restart termi-retry-deliveries.timer sudo systemctl restart termi-weekly-digest.timer sudo systemctl restart termi-monthly-digest.timer sudo systemctl restart termi-backup-all.timer sudo systemctl restart termi-backup-prune.timer sudo systemctl restart termi-backup-offsite-sync.timer ``` ## F. 上线后一周内建议额外确认 - [ ] 有真实订阅确认邮件成功送达 - [ ] 有真实 ntfy / webhook 通知成功送达 - [ ] 至少有一条 digest 成功发出 - [ ] retry timer 能把失败投递重新入队 - [ ] 备份目录持续产生新文件 - [ ] prune 正常清理旧备份 - [ ] offsite sync 确实有异地副本 - [ ] 至少做过一次恢复演练