Skip to main content

Restore

Before any restore
  1. Back up the current state (even if damaged): you may need to go back to it.
  2. Warn the users: the application is unavailable during the operation.
  3. Restore in pre-production first whenever possible, to validate the file.

Database from a dump​

cd ~/pch-sig
F=docker-compose.prod.yml # or docker-compose.preprod.yml
PG=$(docker ps --filter name=pch_postgres --format '{{.Names}}' | grep -v exporter | head -1)

# 1. Stop the backend (no more writes)
docker compose -f $F stop backend

# 2. Recreate an empty database
docker exec "$PG" sh -c 'dropdb -U "$POSTGRES_USER" --if-exists "$POSTGRES_DB" && createdb -U "$POSTGRES_USER" "$POSTGRES_DB"'
docker exec "$PG" sh -c 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "CREATE EXTENSION IF NOT EXISTS postgis; CREATE EXTENSION IF NOT EXISTS unaccent;"'

# 3. Load the dump
gunzip -c ~/backups/pch_sig_YYYYMMDD_HHMMSS.sql.gz | docker exec -i "$PG" sh -c 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB"'

# 4. Restart the backend (runs missing migrations and resets permissions)
docker compose -f $F up -d --no-deps backend
docker exec pch_backend curl -s http://127.0.0.1:8000/api/health

After the restore:

  • Reindex the assistant's document base: docker exec -u www-data pch_backend php bin/console app:assistant:indexer --sans-vecteurs.
  • In production, notify the recovery host team: replication must be re-initialised from the new database.

Production database from the recovery host​

If the production server is lost, the most recent database is the axone-dr replica (or its latest restic snapshot). This is done with the team that runs that host: promote the replica or export a dump, then restore it on the new server as above.

Uploaded files​

docker run --rm -v pch-sig_backend_uploads:/data -v ~/backups:/in alpine \
sh -c 'rm -rf /data/* && tar -xzf /in/uploads_YYYYMMDD.tar.gz -C /data'
docker compose -f $F up -d --no-deps backend # gives ownership back to www-data

GitLab (pre-production)​

A restore needs both files of the same day: the application archive and the configuration (gitlab-secrets.json). Without the latter, tokens, two-factor authentication and CI variables are lost.

cd ~/gitlab
tar -xzf ~/backups/gitlab/gitlab-config_YYYYMMDD_HHMMSS.tar.gz -C /tmp # then copy back into the /etc/gitlab volume
docker cp ~/backups/gitlab/<timestamp>_gitlab_backup.tar gitlab:/var/opt/gitlab/backups/
docker exec gitlab gitlab-ctl stop puma && docker exec gitlab gitlab-ctl stop sidekiq
docker exec -it gitlab gitlab-backup restore BACKUP=<timestamp>
docker compose -f docker-compose.yml restart

Full procedure and precautions in docs/GITLAB_SERVEUR.md in the repository.

Test the backups​

At least once a quarter: restore the latest production dump on pre-production and check that you can sign in and that the main screens display. A backup that has never been restored is not a backup.