备份与恢复
sh0 可按需或按计划将数据库服务器和卷备份为压缩文件,保存在服务器上或发送到外部存储,并可原地恢复。
备份内容
每个备份都是一个 gzip 压缩文件,其内容取决于来源:
| 来源 | 生成方式 |
|---|---|
| PostgreSQL 服务器 | SQL 转储:整个服务器用 pg_dumpall,选择单个数据库时用 pg_dump |
| MySQL 或 MariaDB 服务器 | SQL 转储:mysqldump --all-databases(较新的 MariaDB 镜像使用 mariadb-dump),或单个数据库 |
| MongoDB 服务器 | 对服务器上所有数据库执行 mongodump --archive |
| Redis 服务器 | 数据目录 /data 的 tar 归档(append-only 文件和快照) |
| 应用卷 | 卷(或其子路径)的 tar 归档 |
文件以备份 ID 命名:<id>.gz,加密时为 <id>.gz.enc。不存在 .dump、.archive 或 .rdb 文件。本地备份存放在 sh0 数据目录的 backups/ 文件夹中(标准 Linux 安装为 /var/lib/sh0/backups/):
$ cd /var/lib/sh0/backups
$ ls -l 4efb5ef8-b61c-4b1f-b6dd-b546c1a01bb8.gz 9b5222c8-4c09-4805-8d96-4d80df2168c8.gz.enc | awk '{print $5, $9}'
1314 4efb5ef8-b61c-4b1f-b6dd-b546c1a01bb8.gz
1343 9b5222c8-4c09-4805-8d96-4d80df2168c8.gz.enc
$ zcat 4efb5ef8-b61c-4b1f-b6dd-b546c1a01bb8.gz | grep -m3 '^-- '
-- PostgreSQL database cluster dump
-- Drop databases (except postgres and template1)
-- Drop roles手动备份
- 在数据库服务器上:其 Overview 标签页有一个 Backup 卡片,点击 Backup Now 即可将整个服务器备份到本地,不加密。
- 在侧边栏的 Backups 页面:Trigger Backup 会询问 What do you want to back up?、Destination、是否 Encrypt,对数据库服务器还可选择单个或全部数据库。
通过 API 时,source_type 取 database_server、volume 或 database。调用返回 202,备份在后台执行;再次读取即可得到其文件:
$ curl -s -X POST https://panel.example.com/api/v1/backups/trigger \
-H "Authorization: Bearer $SH0_TOKEN" -H "Content-Type: application/json" \
-d '{"source_type":"database_server","source_id":"3afde175-12d6-4614-94ca-e504737a7cc4","destination":"local","encrypt":false}' \
-o /dev/null -w "%{http_code}\n"
202
$ curl -s https://panel.example.com/api/v1/backups/4efb5ef8-b61c-4b1f-b6dd-b546c1a01bb8 \
-H "Authorization: Bearer $SH0_TOKEN"
{"data":{"created_at":"2026-10-02 02:46:04","created_by":"50159570-e8ad-46a8-8065-e6c9096edde6","database_name":null,"destination":"local","encrypted":false,"file_path":"/var/lib/sh0/backups/4efb5ef8-b61c-4b1f-b6dd-b546c1a01bb8.gz","file_size":1314,"id":"4efb5ef8-b61c-4b1f-b6dd-b546c1a01bb8","path":null,"project_id":null,"restore_error":null,"restore_status":"completed","restored_at":"2026-10-02 02:46:31","schedule_id":null,"source_id":"3afde175-12d6-4614-94ca-e504737a7cc4","source_type":"database_server","status":"completed"}}计划备份
在 Backups 页面,Create Schedule 需要填写来源、五字段 cron 表达式、Destination 和保留数量。计划按 UTC 计算。Run Now 会立即执行一次计划备份。
$ curl -s -X POST https://panel.example.com/api/v1/backup-schedules \
-H "Authorization: Bearer $SH0_TOKEN" -H "Content-Type: application/json" \
-d '{"source_type":"database_server","source_id":"3afde175-12d6-4614-94ca-e504737a7cc4","cron":"0 3 * * *"}'
{"data":{"cron":"0 3 * * *","destination":"local","enabled":true,"id":"ed140ca5-1c47-4388-897d-52726489d3fa","last_run":null,"next_run":"2026-10-02 03:00:00","path":null,"retention":7,"service_id":null,"source_id":"3afde175-12d6-4614-94ca-e504737a7cc4","source_type":"database_server"}}
$ curl -s -X POST https://panel.example.com/api/v1/backup-schedules/ed140ca5-1c47-4388-897d-52726489d3fa/run \
-H "Authorization: Bearer $SH0_TOKEN"
{"data":{"schedule_id":"ed140ca5-1c47-4388-897d-52726489d3fa","status":"started"}}保留策略
保留策略按备份数量计算,而不是天数。默认值为 7;0 表示全部保留。每次计划备份成功后,sh0 会删除该计划中超出数量的最旧备份(记录和文件一并删除)。手动备份永远不会被清理。
存储目标
默认目标为 local。外部存储在 Settings → Storage 中添加(Backups 页面的 Add external storage provider 链接会跳转到这里)。支持的类型有:
- S3 兼容:AWS S3、Cloudflare R2、DigitalOcean Spaces、Backblaze B2、Wasabi、MinIO、Hetzner Object Storage 或任意 S3 端点
- SFTP,使用密码或 SSH 密钥
- FTP,可选 TLS
- Dropbox 和 Google Drive
- 本地路径:服务器上的另一个目录,例如已挂载的磁盘
在 API 中,destination 可取 local、存储提供方名称或 external:<provider-id>。其他值会被以 422 拒绝,而不会悄悄存到本地。
加密
加密备份(.gz.enc)使用实例主密钥以 AES-256-GCM 封装,主密钥保存在 sh0 数据目录下的 master.key 和 master.passphrase 中。只有持有该密钥的实例才能恢复它:请在服务器之外另存这两个文件的副本。
从备份恢复
在 Backups 页面的 History 中,Restore 会在您输入名称确认后,将备份回放到其来源资源中。当前数据会被覆盖,sh0 不会事先做备份。对应 API 为 POST /api/v1/backups/:id/restore,返回 202,随后备份的 restore_status 变为 completed 或 failed。
Restore from External Source 可恢复存放在已配置存储上的文件,例如另一个 sh0 实例生成的备份。
下载与删除
在历史记录中点击 Download,或调用 GET /api/v1/backups/:id/download,可按原样获取文件(application/gzip,加密时为二进制)。删除备份会同时删除其记录和文件。