Backup & Restore

Creating a Backup

Run the built-in backup command:

docker compose exec gitblixt bin/gitblixt eval "Gitblixt.Release.backup()"

This creates a timestamped .tar.gz in /data/backups containing:

  • A full pg_dump of the database
  • All bare git repositories (/data/repos)
  • Uploads (/data/uploads)
  • SSL certificates (/data/ssl)

Since data is stored on the host via bind mounts, backups are also available directly in your data/backups/ directory.

Automating Backups

Add a cron job on your host:

    # Backup every day at 2am, keep 30 days
0 2 * * * cd /path/to/gitblixt && docker compose exec -T gitblixt \
  bin/gitblixt eval "Gitblixt.Release.backup()" && \
  find data/backups -name "*.tar.gz" -mtime +30 -delete

Restoring from an Unencrypted Backup

Use this flow when backup encryption is not enabled (see below).

1. Stop GitBlixt:

docker compose down

2. Extract your backup archive into the data directory:

tar -xzf data/backups/gitblixt-backup-2024-01-15.tar.gz -C data/

3. Start everything:

docker compose up -d

The app will run migrations and start serving traffic.

Encrypted Backups

Enable encryption under Admin → Backups → Encryption. GitBlixt generates a keypair and shows you the private key once — save it immediately (e.g. in 1Password). The server keeps only the public key, so it can encrypt new backups but can never decrypt its own backups. A stolen server therefore cannot reveal any past backup.

Once enabled, every backup (manual and scheduled) produces two encrypted objects:

  • gitblixt-backup-TIMESTAMP.tar.gz.enc — database, repos, and uploads
  • gitblixt-backup-TIMESTAMP.key.enc — the server's secret_key_base, required to decrypt the encrypted-at-rest columns

You need both objects plus the private key to restore. Download both from the Backups page (each completed backup has a main download and a "Key file" download).

Restoring an encrypted backup on a fresh host

1. Put the private key on the new host (paste it from 1Password):

nano /tmp/backup-private.pem

2. Run the restore (it decrypts both objects, restores the database, and unpacks repos/uploads):

docker compose run --rm gitblixt bin/gitblixt eval \
  'Gitblixt.Release.restore("/data/backups/gitblixt-backup-TIMESTAMP.tar.gz.enc", "/data/backups/gitblixt-backup-TIMESTAMP.key.enc", "/tmp/backup-private.pem")'

3. Remove the private key from the host:

shred -u /tmp/backup-private.pem

4. Start everything:

docker compose up -d

The restore writes secret_key_base into your config directory only if it isn't already provided via GITBLIXT_SECRET_KEY_BASE/SECRET_KEY_BASE, so the encrypted-at-rest secrets (app env vars, CI variables, mirror credentials) stay decryptable on the new host.