kogutdocs

When kogut itself is down

Backups and restore

Back up the database offsite and restore it on another machine.

Use kogut backup to copy the live database. Do not copy kogut.db with cp while kogut runs. Keep the backup at another provider.

What to back up

  • The kogut backup file: accounts, the objects made in the panel, incidents, and all history.
  • kogut.toml, or the file that KOGUT_CONFIG names.
  • The values kogut.toml reads with ${NAME}, from the environment or $CREDENTIALS_DIRECTORY, and server variables such as KOGUT_URL. See Secrets.
  • The logo file in the data directory, if [brand] logo names a file rather than a URL.

The rest of the data directory needs no backup: kogut.lock, setup-token, the kogut.db-wal and kogut.db-shm files, and the kogut.db.pre-NNNN.bak copies made before migrations. Agents keep their own settings on each host, such as /etc/kogut/agent.env for an install-script agent.

Create a backup

systemd

For an install-script deployment, run:

sudo env KOGUT_DATA=/var/lib/kogut kogut backup /var/backups/kogut.db

Docker

docker exec kogut /usr/local/bin/kogut backup /data/backup.db
docker cp kogut:/data/backup.db ./kogut-backup.db

The command writes a compact SQLite file and replaces the destination only when the copy is complete. It leaves out visitor salts, so visitors already counted on the day of a restore can be counted again. See the backup command.

Schedule offsite copies

  1. Configure your transfer tool. The example uses an rclone remote named r2 and a bucket named acme-kogut. Limit its credentials to that bucket.
  2. Save the service and timer below, with your own transfer command.
/etc/systemd/system/kogut-backup.service
[Unit]
Description=Back up the kogut database

[Service]
Type=oneshot
Environment=KOGUT_DATA=/var/lib/kogut
ExecStart=/usr/local/bin/kogut backup /var/backups/kogut/kogut.db
ExecStartPost=/usr/bin/rclone copyto /var/backups/kogut/kogut.db r2:acme-kogut/kogut.db
/etc/systemd/system/kogut-backup.timer
[Unit]
Description=Back up the kogut database every night

[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true

[Install]
WantedBy=timers.target
  1. Create the destination directory and enable the timer:
sudo mkdir -p /var/backups/kogut
sudo systemctl daemon-reload
sudo systemctl enable --now kogut-backup.timer
  1. Turn on object versioning or keep dated copies, so a bad backup cannot replace every good one. Add a heartbeat to catch missed backup jobs.

To lose less than one backup interval, run Litestream beside kogut to stream changes offsite.

Restore the database

  1. Install kogut on the destination and stop it. For systemd, run sudo systemctl stop kogut. For Docker, run docker stop kogut.

  2. Restore to the install-script data directory:

    sudo env KOGUT_DATA=/var/lib/kogut kogut restore /var/backups/kogut.db

    Add --force to replace an existing database. Restore refuses to run while the server holds the data directory’s lock.

    For Docker, restore to the server’s volume:

    docker run --rm -v kogut-data:/data -v "$PWD":/backup:ro \
    ghcr.io/piotrkowski/kogut:0.1 restore /backup/kogut-backup.db --force
  3. For an install-script deployment, return the restored files to the service’s dynamic user before starting kogut:

    sudo chown -R --reference=/var/lib/private/kogut /var/lib/private/kogut
  4. Restore kogut.toml, the values and credentials it reads, and the logo file, if any. Start kogut and update DNS if the address changed. Older databases migrate on startup, and agents send their buffered data when they reconnect.

Restore accepts a database from the current or an older schema version, not a newer one. See the restore command. Practise a restore on a separate machine before you need it.