Skip to content

Backups

This page documents the Magikal backup workflow.

Backup location

Main backup folder:

/home/magikalbot/backups

What is backed up

Backup Location / Pattern
Postgres app database /home/magikalbot/backups/appdb-YYYY-MM-DD.dump
Backup log /home/magikalbot/backups/magikal-db-dump.log
Bot file backups /home/magikalbot/backups/botfiles
Panel full backup /home/magikalbot/backups/magikal-panel-full-backup-*.tar.gz

Daily Postgres backup job

The daily Postgres backup job is:

/etc/cron.daily/magikal-db-dump

It runs from cron as root.

The backup script dumps the appdb database using the local postgres system user.

It writes to a temporary file first, then only moves the file into the backup folder if pg_dump succeeds and the dump is not empty.

Check latest database backup

Show today's backup:

ls -lh /home/magikalbot/backups/appdb-$(date +%F).dump

Check the backup log:

tail -80 /home/magikalbot/backups/magikal-db-dump.log

Good signs:

backup written
backup complete

Check for failed zero-byte backups

Zero-byte dumps are failed backups.

Check how many exist:

find /home/magikalbot/backups -type f -name "appdb-*.dump" -size 0 | wc -l

Show the newest zero-byte files:

find /home/magikalbot/backups -type f -name "appdb-*.dump" -size 0 -printf "%TY-%Tm-%Td %s %p\n" | sort | tail -20

A good backup should not be 0 bytes.

Check valid non-empty backups

Show recent non-empty database dumps:

find /home/magikalbot/backups -type f -name "appdb-*.dump" -size +1c -printf "%TY-%Tm-%Td %s %p\n" | sort | tail -20

Manual database backup test

Run as root:

su - postgres -c "pg_dump -d appdb -F c -Z 9" > /tmp/magikal-test-postgres.dump
echo $?
ls -lh /tmp/magikal-test-postgres.dump

Good output:

0

The test dump file should be non-zero.

Known backup issue fixed on 19/04/2026

The old daily backup command used the app database user:

pg_dump -h 127.0.0.1 -U app -d appdb -F c -Z 9

That failed because the app user did not have permission for every table.

Observed error:

permission denied for table runtime_kv

Because the shell created the output file before pg_dump failed, the cron job left 0-byte backup files behind.

The fixed backup job now uses the local postgres system user and writes through a temporary file first.

Retention

The current daily database backup job keeps valid daily appdb-*.dump files for 14 days.

Zero-byte files are not automatically deleted yet, because they help show the old failure period.

Before risky work

Before large bot, panel, database, or migration work:

  1. Confirm Git restore points exist.
  2. Confirm the latest database backup is non-zero.
  3. Check the backup log for backup complete.
  4. Do not continue if the latest database dump is 0 bytes.

Do not delete

Do not delete these without checking first:

  • latest valid appdb-YYYY-MM-DD.dump
  • magikal-db-dump.log
  • botfiles/
  • panel .tar.gz backups
  • old 0-byte dumps until the failure window has been reviewed