Chapter 8 · 8.2
Backing up databases and Docker volumes properly
A running database is constantly writing to its files. If you copy those files halfway through, your backup may be broken. That is why you make a dump first: a clean copy of the database in a single file.
Where is your data?
| What | Where |
|---|---|
Your compose files, Caddyfile, .env and folders such as vw-data | /srv/diensten |
Docker volumes, such as uptime-kuma and n8n-data | /var/lib/docker/volumes/diensten_<naam>/_data |
| Database dumps | /var/backups/db |
| Server settings | /etc |
Docker puts the name of your folder in front of the volume name: in /srv/diensten, uptime-kuma therefore becomes diensten_uptime-kuma. You can see the real names with sudo docker volume ls.
The preparation script
Put this in /usr/local/sbin/voor-backup.sh (chmod 700). It is started by the backup script from Backups with restic to another location.
#!/bin/sh
set -e
mkdir -p /var/backups/db
chmod 700 /var/backups/db
cd /srv/diensten
# WordPress-database (MariaDB) als dump
docker compose exec -T wp-db sh -c \
'mariadb-dump --single-transaction -u"$MARIADB_USER" -p"$MARIADB_PASSWORD" "$MARIADB_DATABASE"' \
> /var/backups/db/wordpress.sql
If you don't use WordPress, leave that part out. If you have a database outside Docker, it works the same way with mariadb-dump --single-transaction or pg_dump.
Apps with an SQLite database
Vaultwarden, Uptime Kuma and n8n store their data in an SQLite file in their volume or folder by default. The simplest and safest approach is to stop them briefly during the backup. The backup script from Backups with restic to another location does this with docker compose stop and then docker compose start. It usually only takes a moment, and at night nobody notices. If you don't want any interruption, follow the app's own backup instructions, such as those in the Vaultwarden wiki.
Skip the database folder itself (here diensten_wp-db): that's what the dump is for.
Restoring an app
- Stop the app:
sudo docker compose stop vaultwarden. - Restore the folder:
sudo restic restore latest --target /tmp/terug --include /srv/diensten/vw-data(using the variables from Backups with restic to another location). - Replace the folder with the restored version and start the app again.
- To restore a database, import the dump, for example
docker compose exec -T wp-db sh -c 'mariadb -u"$MARIADB_USER" -p"$MARIADB_PASSWORD" "$MARIADB_DATABASE"' < wordpress.sql.
