docs: correct cutover and redeploy runbooks against the real deployment (#26)

Dry-running CUTOVER.md against production surfaced four things that would
have failed mid-cutover:

- The volume is named after the compose project, which is the lowercased
  directory name (mangabookmark), not the repo name. Both runbooks hardcoded
  bookmarkmanager_bookmarks-data. Derive it from docker instead.
- §1 asserted a clean stop leaves no -wal. compose stop SIGKILLs after 10s,
  and a surviving -wal holds writes bookmarks.db alone does not, so the
  export would silently lose them. Check rather than assume.
- jq is not installed on the server; §5's read-path check now uses python3,
  which the runbook already requires.
- REDEPLOY §1 still listed the pre-split table set, omitting readers and
  sessions from both the \dt output and the pg_restore contents.

Also records the git-pull failure the redeploy hits on a checkout whose
remote is the HTTPS clone URL.
This commit is contained in:
2026-08-08 15:46:05 +07:00
parent 2cc1e69f5d
commit 01de8903b4
2 changed files with 36 additions and 17 deletions
+10 -5
View File
@@ -59,7 +59,7 @@ network can reach it — so every command below goes in through the container:
```bash
$COMPOSE exec -T postgres psql -U bookmarks -d bookmarks -c '\dt'
# -> bookmarks, schema_migrations, series
# -> bookmarks, readers, schema_migrations, series, sessions
```
Inside the container that connects over the local socket as the `bookmarks`
@@ -99,8 +99,10 @@ you will act as though you have one:
docker run --rm -v "$BACKUP_DIR":/backup postgres:17-alpine \
pg_restore --list "/backup/bookmarks-$STAMP.dump" | grep 'TABLE DATA'
# -> 1234; 0 0 TABLE DATA public bookmarks bookmarks
# -> 1235; 0 0 TABLE DATA public schema_migrations bookmarks
# -> 1236; 0 0 TABLE DATA public series series
# -> 1235; 0 0 TABLE DATA public readers bookmarks
# -> 1236; 0 0 TABLE DATA public schema_migrations bookmarks
# -> 1237; 0 0 TABLE DATA public series bookmarks
# -> 1238; 0 0 TABLE DATA public sessions bookmarks
# 2. Sanity-check the live row count you just captured.
$COMPOSE exec -T postgres psql -U bookmarks -d bookmarks \
@@ -161,10 +163,12 @@ ls -1t "$BACKUP_DIR"/bookmarks-*.dump | tail -n +31 | xargs -r rm -v
declared in `docker-compose.yml` any more, which is what keeps `docker compose
down -v` from taking it with the rest of the stack. It is not the live database
and nothing reads it — the one-way move out of it is `CUTOVER.md`. Once the
Postgres data has been trusted for a while, remove it by hand — nothing else will:
Postgres data has been trusted for a while, remove it by hand — nothing else will.
Its full name is `<compose project>_bookmarks-data`, and the project name is the
lowercased directory name of the checkout, so ask Docker rather than typing it:
```bash
docker volume rm bookmarkmanager_bookmarks-data
docker volume rm "$(docker volume ls -q --filter name=_bookmarks-data)"
```
---
@@ -395,6 +399,7 @@ panel works on the phone.
| `postgres` never leaves `starting`; `bookmark-api` never starts either | The healthcheck (`pg_isready`) is failing and `bookmark-api` waits on it. `$COMPOSE logs postgres` — usually `postgres-data` was initialised by a different major version ("database files are incompatible with server"), or the disk is full. |
| `pg_restore`: `cannot drop … other objects depend on it` / `being accessed by other users` | Live connections block `--clean`. `$COMPOSE stop bookmark-api` first (§6). If they persist: `$COMPOSE exec -T postgres psql -U bookmarks -d postgres -c "select pg_terminate_backend(pid) from pg_stat_activity where datname='bookmarks' and pid <> pg_backend_pid()"`. |
| Dump is 0 bytes, or `pg_restore`: `did not find magic string in file header` | You ran `exec` without `-T`. The allocated TTY rewrites newlines in the binary stream and corrupts the archive in flight (§1). |
| `git pull`: `could not read Username for 'https://…'` | The checkout's remote is the HTTPS clone URL and the server has no credential helper, so the pull prompts into a closed stdin. Switch it to SSH once — `git remote set-url origin ssh://git@gitea.violetcrown.my.id:2222/sulthan/mangaBookmark.git`. Gitea's SSH listens on **2222**, not 22; port 22 is the host's own sshd and answers `Permission denied (publickey)` no matter which key is registered. |
Full first-time setup: `DEPLOY.md`. The one-off SQLite→Postgres move:
`CUTOVER.md`. Config reference and endpoints: `README.md`.