自托管
备份与恢复
一切都在一个数据卷里 —— SQLite 数据库与附件目录,必须一起备份。
你的交易日志在磁盘上就是两样东西,且必须一起备份:
| 内容 | 默认位置(Docker) |
|---|---|
| 数据库 | tm_data 数据卷中的 /data/tradermemos.db(SQLite) |
| 附件与笔记媒体 | 同一数据卷中的 /data/attachments |
附件的元数据保存在数据库中 —— 只恢复其中之一会造成截图失效或文件成为孤儿。
方式 1 —— 应用层导出(任何部署都适用)
应用内的导入 → 导出(或 GET /api/v1/exports)可生成:
| 格式 | 内容 |
|---|---|
| ZIP | export.json + attachments/ 下的全部截图 —— 完整的可携带备份 |
| JSON | 交易、成交、日志笔记、现金流水、策略手册(不含图片) |
| CSV | 已平仓交易的日志表格,便于在其他工具中分析 |
在任意 TraderMemos 实例导入 ZIP / JSON 即可恢复 —— 全新安装时初始化向导的可选导入步骤 可以直接接收,之后任何时候也可通过导入页面完成。成交记录在服务端自动去重,重复导入 是安全的。
在主机之间迁移、切换数据库(SQLite ↔ Postgres),或想要一份真正能打开的异地副本时, 用这种方式最合适。
方式 2 —— 数据卷快照(Docker,完整拷贝)
SQLite 运行在 WAL 模式下,不要直接复制正在使用的数据库文件 —— 请先停止 API (仅几秒停机),否则可能丢失最近的写入:
cd TraderMemos
docker compose stop api
docker run --rm --volumes-from "$(docker compose ps -aq api)" -v "$PWD":/backup alpine \
tar czf "/backup/tradermemos-$(date +%F).tar.gz" -C /data .
docker compose start api在全新主机上恢复:
cd TraderMemos
make up # 创建容器与空数据卷
docker compose stop api
docker run --rm --volumes-from "$(docker compose ps -aq api)" -v "$PWD":/backup alpine \
sh -c "rm -rf /data/* && tar xzf /backup/tradermemos-2026-08-01.tar.gz -C /data"
docker compose start api可用 cron 自动化,并将压缩包同步到异地(rclone、restic 等)。数据卷中的
tradermemos.db.migrate.lock 是临时文件,可放心排除。
Postgres
导出数据库并复制附件数据卷:
docker compose exec postgres pg_dump -U tm tradermemos > tradermemos-$(date +%F).sql
# 附件仍在 tm_data 数据卷中 → 按方式 2 备份 /data/attachments恢复时用 psql -U tm tradermemos < backup.sql 导入空数据库,再启动 API
(迁移会自动对齐)。
每次升级前
升级版本前先做一次快照 —— schema 迁移在启动时自动执行,且不支持自动降级。参见 更新升级。