docs(ops): prove the recovery backup decrypts before dropping production (issue #74)
The rollback restore dropped jyotisha before decrypting the backup; a bad key or damaged file would leave the site on an empty database. Load the host env file, check sha256, decrypt into pg_restore --list first. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LutgzyJqNhPpZy1nFsJtN3
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
40bc565a49
commit
9274491681
@@ -106,7 +106,21 @@ Gitea → Deploy production。Use workflow from:`main`。
|
||||
|
||||
1. 整库还原。没有单独按钮。只允许 `RECOVERY_FORMAT=2` 的恢复点。先看 `/opt/jyotisha-production/.state/recovery-baseline.env`:没有 `RECOVERY_FORMAT=2` 就停,回到第 4 步再点一次创建恢复点。8 月的旧备份不能用。第 4 步的 `recovery_reference` 斜杠后面就是备份文件名,例如 `production-pre-migration-20261014T120000Z.dump.enc`。文件在 `/opt/jyotisha-production/backups/` 下面。先 `sha256sum` 这个文件,和同一份 `recovery-baseline.env` 里的 `RECOVERY_SHA256` 对上,再继续。
|
||||
|
||||
先停 `api` 和 `web`,不要停 `postgres`。口令和密钥只用主机上已有的环境文件,不要贴出来。
|
||||
**先证明备份能解开、能读,再动生产库。** 顺序不能反:先删库再发现备份解不开,网站就停在一个空库上。口令和密钥只用主机上已有的环境文件,不要贴出来,也不要 `echo`:
|
||||
|
||||
```text
|
||||
cd /opt/jyotisha-production
|
||||
set -a; . ./.env.production.database; set +a
|
||||
backup=/opt/jyotisha-production/backups/<备份文件名>
|
||||
sha256sum "$backup" # 必须等于 recovery-baseline.env 里的 RECOVERY_SHA256
|
||||
postgres_id=$(sudo -n docker ps -q --filter label=com.docker.compose.project=jyotisha-production --filter label=com.docker.compose.service=postgres)
|
||||
openssl enc -d -aes-256-cbc -pbkdf2 -pass env:PRODUCTION_BACKUP_ENCRYPTION_KEY -in "$backup" \
|
||||
| sudo -n docker exec -i "$postgres_id" pg_restore --list >/dev/null && echo backup_readable=1
|
||||
```
|
||||
|
||||
上面只读备份、不碰任何库。必须看到 `backup_readable=1`;没看到(解密失败、文件损坏)就停,不要往下做,问产品负责人。
|
||||
|
||||
看到之后,再停 `api` 和 `web`,不要停 `postgres`:
|
||||
|
||||
```text
|
||||
api_id=$(sudo -n docker ps -q --filter label=com.docker.compose.project=jyotisha-production --filter label=com.docker.compose.service=api)
|
||||
@@ -119,7 +133,7 @@ sudo -n docker exec -e PGPASSWORD="$POSTGRES_PASSWORD" "$postgres_id" \
|
||||
sudo -n docker exec -e PGPASSWORD="$POSTGRES_PASSWORD" "$postgres_id" \
|
||||
psql -U "$POSTGRES_USER" -d postgres -v ON_ERROR_STOP=1 \
|
||||
-c "CREATE DATABASE jyotisha;"
|
||||
openssl enc -d -aes-256-cbc -pbkdf2 -pass env:PRODUCTION_BACKUP_ENCRYPTION_KEY -in <备份文件> \
|
||||
openssl enc -d -aes-256-cbc -pbkdf2 -pass env:PRODUCTION_BACKUP_ENCRYPTION_KEY -in "$backup" \
|
||||
| sudo -n docker exec -i -e PGPASSWORD="$POSTGRES_PASSWORD" "$postgres_id" \
|
||||
pg_restore -U "$POSTGRES_USER" -d jyotisha --exit-on-error
|
||||
sudo -n docker exec -e PGPASSWORD="$POSTGRES_PASSWORD" "$postgres_id" \
|
||||
|
||||
Reference in New Issue
Block a user