fix(ops): make backup/restore work, and give upgrades a pin and a rollback
DX-13: both shell scripts ran bare 'docker compose', which has no config
file to find in the layout docs/self-hosting.md tells people to use (only
docker-compose.selfhost.yml is downloaded) — they now fall back to it, while
a source checkout keeps resolving docker-compose.yml as before. The two
PowerShell scripts moved the dump through the PS pipeline, which corrupts
binary on 5.1 and cannot express -Encoding Byte at all on 7 ('Byte' is not a
supported encoding name), so they simply failed there; they now write inside
the container and 'docker compose cp' it across. backup.sh also wrote its
output straight into backups/, leaving a truncated file that looks like a
real backup when pg_dump fails — it writes a .part and promotes on success.
Both restores report a non-zero pg_restore rather than printing 'Restored'
over it. Docs now state that a backup is the dump PLUS .env: without
TOKEN_ENCRYPTION_KEY every encrypted secret in the restored database is
unreadable, which the old one-line 'back up the volume' never said.
DX-14: 'latest' moves with every release and migrations run on every boot,
so self-hosters had no way to choose when they move and no way back. Docs
gain IMAGE_TAG pinning, a rollback recipe (image-only vs schema-bearing) and
the migration-failed-at-boot case; CHANGELOG.md is generated from
releaseNotes.ts so the file cannot drift from what the app shows, and
'siftlode release' refuses on a stale one rather than regenerating it into
the clean tree it just demanded.
Verified: dump + restore round-trip on both platforms against localdev into
a scratch database (8 users, 262822 videos, schema 0082_invite_lang), and
IMAGE_TAG=0.80.0 resolves on both services in 'compose config'.
This commit is contained in:
+22
-2
@@ -1,11 +1,31 @@
|
||||
#!/bin/sh
|
||||
# Restores a Siftlode Postgres dump created by backup.sh into the running db container.
|
||||
# Usage: ./scripts/restore.sh backups/siftlode-YYYYMMDD-HHMMSS.dump
|
||||
#
|
||||
# Restoring the database does NOT restore the secrets that decrypt it. If this dump is from an
|
||||
# instance with a different TOKEN_ENCRYPTION_KEY than the current .env, the encrypted sysconfig
|
||||
# values and refresh tokens will not be readable. See docs/self-hosting.md § Backups.
|
||||
set -e
|
||||
|
||||
# See backup.sh: the documented self-host layout ships only docker-compose.selfhost.yml, so plain
|
||||
# `docker compose` has no configuration file to find there.
|
||||
if [ -z "${COMPOSE_FILE:-}" ] && [ ! -f docker-compose.yml ] && [ -f docker-compose.selfhost.yml ]; then
|
||||
COMPOSE_FILE=docker-compose.selfhost.yml
|
||||
export COMPOSE_FILE
|
||||
fi
|
||||
|
||||
FILE="$1"
|
||||
if [ -z "$FILE" ]; then echo "Usage: restore.sh <dumpfile>"; exit 1; fi
|
||||
if [ ! -f "$FILE" ]; then echo "Dump file not found: $FILE"; exit 1; fi
|
||||
USER_NAME="${POSTGRES_USER:-siftlode}"
|
||||
DB_NAME="${POSTGRES_DB:-siftlode}"
|
||||
docker compose exec -T db pg_restore -U "$USER_NAME" -d "$DB_NAME" --clean --if-exists < "$FILE"
|
||||
echo "Restored $FILE"
|
||||
|
||||
# pg_restore exits non-zero for ignorable warnings too (--clean --if-exists on a fresh database
|
||||
# reports every missing object it tried to drop), so a non-zero code is reported as "check this",
|
||||
# not swallowed and not dressed up as success.
|
||||
if docker compose exec -T db pg_restore -U "$USER_NAME" -d "$DB_NAME" --clean --if-exists < "$FILE"; then
|
||||
echo "Restored $FILE"
|
||||
else
|
||||
echo "pg_restore reported errors while restoring $FILE — read the output above before treating this instance as restored." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user