diff --git a/.woodpecker/migrate-authentik-db.yml b/.woodpecker/migrate-authentik-db.yml index 36cc37dc..4be31a69 100644 --- a/.woodpecker/migrate-authentik-db.yml +++ b/.woodpecker/migrate-authentik-db.yml @@ -72,7 +72,31 @@ steps: # pipeline simple. PG refuses to run as root, so use `su postgres`. - mkdir -p "$PGDATA" && chown postgres:postgres "$PGDATA" - su postgres -c "/usr/lib/postgresql/16/bin/initdb -D $PGDATA --auth=trust --encoding=UTF8 --no-locale --username=postgres" - - su postgres -c "/usr/lib/postgresql/16/bin/pg_ctl -D $PGDATA -l /tmp/pg.log -o '-c listen_addresses=127.0.0.1' -w start" + # Configure continuous WAL archiving so the begin/end_wal of the + # base backup actually lands in the Barman WAL archive — without + # this, PG recycles the closed segment on pg_switch_wal and the + # file named never gets uploaded, causing CNPG recovery + # to fail with "object storage or file not found ". + - | + cat > /usr/local/bin/archive_wal.sh <<'SH' + #!/bin/sh + exec barman-cloud-wal-archive \ + --cloud-provider aws-s3 \ + --endpoint-url "$GARAGE_ENDPOINT" \ + --gzip -e AES256 \ + "$BARMAN_DEST" "$BARMAN_SERVER" "$1" + SH + chmod +x /usr/local/bin/archive_wal.sh + - | + cat >> "$PGDATA/postgresql.conf" <: WAL not found". + # Force a WAL switch so PG archives the segment that covers + # the base backup's end_wal (the checkpoint/consistency LSN). + # archive_command fires asynchronously — wait for archive_status + # to drain so the "*.ready" files are gone before we stop PG. - psql -h 127.0.0.1 -U postgres -d postgres -c "CHECKPOINT; SELECT pg_switch_wal();" - | - for wal in "$PGDATA"/pg_wal/*; do - [ -f "$wal" ] || continue - name=$(basename "$wal") - case "$name" in *.partial) continue ;; esac - echo "Archiving WAL $name" - barman-cloud-wal-archive \ - --cloud-provider aws-s3 \ - --endpoint-url "$GARAGE_ENDPOINT" \ - --gzip -e AES256 \ - "$BARMAN_DEST" "$BARMAN_SERVER" "$wal" + for i in $(seq 1 30); do + ready=$(ls "$PGDATA/pg_wal/archive_status"/*.ready 2>/dev/null | wc -l) + echo "archive_status: $ready .ready file(s) remaining" + [ "$ready" -eq 0 ] && break + sleep 2 done - su postgres -c "/usr/lib/postgresql/16/bin/pg_ctl -D $PGDATA -m fast -w stop" - echo "Seed written. Next fresh bootstrap of ak-pg will recover this backup." diff --git a/.woodpecker/migrate-paperless.yml b/.woodpecker/migrate-paperless.yml index a57ee5e3..4a0d9b9e 100644 --- a/.woodpecker/migrate-paperless.yml +++ b/.woodpecker/migrate-paperless.yml @@ -74,7 +74,26 @@ steps: # step container, not as a Woodpecker service. - mkdir -p "$PGDATA" && chown postgres:postgres "$PGDATA" - su postgres -c "/usr/lib/postgresql/16/bin/initdb -D $PGDATA --auth=trust --encoding=UTF8 --no-locale --username=postgres" - - su postgres -c "/usr/lib/postgresql/16/bin/pg_ctl -D $PGDATA -l /tmp/pg.log -o '-c listen_addresses=127.0.0.1' -w start" + # See migrate-authentik-db.yml for rationale on continuous WAL + # archiving during the seed. + - | + cat > /usr/local/bin/archive_wal.sh <<'SH' + #!/bin/sh + exec barman-cloud-wal-archive \ + --cloud-provider aws-s3 \ + --endpoint-url "$GARAGE_ENDPOINT" \ + --gzip -e AES256 \ + "$BARMAN_DEST" "$BARMAN_SERVER" "$1" + SH + chmod +x /usr/local/bin/archive_wal.sh + - | + cat >> "$PGDATA/postgresql.conf" <- @@ -93,21 +112,13 @@ steps: --host 127.0.0.1 --port 5432 --user postgres "$BARMAN_DEST" "$BARMAN_SERVER" - barman-cloud-backup-list --cloud-provider aws-s3 --endpoint-url "$GARAGE_ENDPOINT" "$BARMAN_DEST" "$BARMAN_SERVER" - # Archive the WAL segments that cover the base backup so CNPG - # bootstrap.recovery can locate the `end_wal` file. See - # migrate-authentik-db.yml for the rationale. - psql -h 127.0.0.1 -U postgres -d postgres -c "CHECKPOINT; SELECT pg_switch_wal();" - | - for wal in "$PGDATA"/pg_wal/*; do - [ -f "$wal" ] || continue - name=$(basename "$wal") - case "$name" in *.partial) continue ;; esac - echo "Archiving WAL $name" - barman-cloud-wal-archive \ - --cloud-provider aws-s3 \ - --endpoint-url "$GARAGE_ENDPOINT" \ - --gzip -e AES256 \ - "$BARMAN_DEST" "$BARMAN_SERVER" "$wal" + for i in $(seq 1 30); do + ready=$(ls "$PGDATA/pg_wal/archive_status"/*.ready 2>/dev/null | wc -l) + echo "archive_status: $ready .ready file(s) remaining" + [ "$ready" -eq 0 ] && break + sleep 2 done - su postgres -c "/usr/lib/postgresql/16/bin/pg_ctl -D $PGDATA -m fast -w stop" - echo "Seed written. Next fresh bootstrap of pprl-pg will recover this backup."