DEV Community

Ruben Voß
Ruben Voß

Posted on

Automatische Backups von PostgreSQL via Cronjob

Kontext

Um die Daten deiner Kunden zu sichern müssen diese Regelmäßig auf einem Server abgespeichert werden. Dieser muss unbeeinträchtigt sein, falls die Infrastruktur auf der deine Datenbank läuft kaputtgeht. Also am besten bei einem Anderen Provider, oder in einer anderen Gegend. Ich zeige dir hier wie du das über einen Cronjob einrichten kannst, der von deiner Datenbank im Docker-Container ein Backup erstellt.

Befehl Testen

Dein Container braucht einen Namen, damit du in ihm einen Shell-Befehl auslösen kannst. In docker-compose.yml sieht das so aus:

  postgres:
    container_name: postgres
Enter fullscreen mode Exit fullscreen mode

Jetzt kannst du mit docker exec -it In deinem Container einen Befehl auslösen. Probiere es mal aus:

docker exec -it mein_container_name pg_dumpall -U mein_datenbank_nutzer
Enter fullscreen mode Exit fullscreen mode

Mit diesem Befehl sollte sich nun dein Bildschirm mit dem PostgreSQL dump füllen. Wie aber kannst du das ganze nun Speichern?
Durch Piping bringst du den Output vom pg_dumpall Befehl in eine Datei.

# mit gzip kannst du deine Datei komprimieren.
# mit $(date +%Y%m%d-%H%M%S) kriegt deine Datei einen einzigartigen Namen.
# mit dem \ Backslash kannst du deinen Befehl in mehrere Zeilen aufteilen
docker exec -it mein_container_name pg_dumpall -U mein_datenbank_nutzer \
| gzip -9c > db_backup_$(date +%Y%m%d-%H%M%S).sql.gz
Enter fullscreen mode Exit fullscreen mode

Nun kannst du selbst dein Backup erstellen. Aber wie geht das ganze automatisch? Dazu kommen wir jetzt.

Crontab bearbeiten

Regelmäßige Befehle werden auf deinem System in der Crontab eingestellt. Die crontab deines Nutzers kannst du mit crontab -e bearbeiten.
Auf https://crontab.guru/ kannst du dir anschauen, was die Zeichen am Anfang deines cronjobs bedeuten. Wir können unser Backup zum Beispiel immer nachts um 03.22 Uhr ausführen:

22 3 * * * docker exec -it postgres pg_dumpall -U ruben | gzip -9c > /backup/location/db-$(date +%Y%m%d-%H%M%S).sql.gz
Enter fullscreen mode Exit fullscreen mode

Um deine Crontab zu Testen aber am besten am Anfang jede Minute:

* * * * * /shell/befehl
Enter fullscreen mode Exit fullscreen mode

/backup/location/ ersetzt du durch einen vorübergehenden Speicherort auf deinem Server für die Backups. Z.B. home-Verzeichnis.

Jetzt musst du nur noch mit scp dein Backup zu einem anderen Server bringen. Das kannst du zum beispiel eine Stunde später tun...

22 4 * * * scp /backup/location/db-$(date +%Y%m%d)*.sql.gz mein_user@mein_server:/backup/location/
Enter fullscreen mode Exit fullscreen mode

Und dein ursprüngliches Backup auf deinem Server Löschen damit dein Speicher nicht überfüllt wird...

22 5 * * * rm /backup/location/db-$(date +%Y%m%d)*.sql.gz
Enter fullscreen mode Exit fullscreen mode

Das sind aber ganz schön viele cronjobs... Was wenn deine Datenbanksicherung länger dauert als eine Stunde? dann wird dein Backup nicht auf den Backupserver kopiert. D.h. es war quasi fehlerhaft.
Also das ganze lieber als bash-skript aufsetzen.

touch backup.sh
chmox +x backup.sh
vi backup.sh
Enter fullscreen mode Exit fullscreen mode

So könnte dein backup.sh aussehen:

#!/bin/bash
DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_FILE=/home/user/db-$DATE.sql.gz
/usr/bin/docker exec -it postgres pg_dumpall -U ruben | gzip -9c > $BACKUP_FILE
echo "Backup $BACKUP_FILE erstellt" >> /home/user/backup.log
scp $BACKUP_FILE mein_user@mein_server:/backup/location/
rm $BACKUP_FILE
Enter fullscreen mode Exit fullscreen mode

Und bei deiner Crontab fügst du es einfach so hinzu:

22 3 * * * /backup/script/location/backup.sh
Enter fullscreen mode Exit fullscreen mode

Happy Coden!
Dein Ruben

Mein Blog

Top comments (0)