Seafile Backup per Skript

Die OpenSource Cloud Storage Lösung Seafile eignet sich gut, auf einem Raspberry Pi installiert zu werden, sofern nicht zu viele User darauf zugreifen. Ansonsten geht dem System bald die Luft aus. Ist Seafile eingerichtet, merkt man schnell, dass es ordentlich funktioniert. Also kommen gleich die ersten Daten in die neue Wolke, um sie überall nutzen zu können. So ein System läuft in der Regel im 24/7 Modus und wird daher nicht gerade wenig belastet. Was passiert jedoch bei einem Systemausfall? Richtig! Im schlimmsten Fall sind die Daten weg. Daran denken wohl eher wenige und kümmern sich nicht um ein Backup/Restore Konzept. Das sollte jedoch bei keiner Serverlösung fehlen. Backups sind tatsächlich nicht nur etwas für Weicheier. Generell empfehlenswert, ist ein Backup des kompletten Systems. Wie das funktioniert habe ich hier beschrieben: Klick

Für den täglichen Betrieb gibt es mehrere Möglichkeiten eines Backups. Letztendlich basieren alle auf einem selbst geschriebenen Skript, welches durch einen Cron Job ausgeführt wird. Ich habe mich für ein tägliches Fullbackup entschieden, von dem max. drei Versionen vorgehalten werden sollen, damit der Backupspeicher Nicht aus allen Nähten platzt. Ein Differentielles Backup, um nur das Delta wegzuschreiben, ist natürlich auch möglich. Hier wird der Restoreprozess jedoch etwas aufwendiger. Wer Seafile mit einer SQLite Datenbank betreibt (so ist der Standard), muss vor einem Backup Seafile erstmal beenden, um einen sauberen Stand zu sichern. Beim Einsatz einer MySQL Datenbank kann das Backup auch im laufenden Betrieb ausgeführt werden. Für das Stoppen und Starten von Seafile empfiehlt sich unter Systemd einen Dienst anzulegen. Die Datei für den Dienst wird nach „/etc/systemd/system/“ gespeichert. Sollte die Seafile Instanz nicht mit dem User „seafile“ laufen, muss die Variable „User“ in der Datei angepasst werden. Wird Seafile hinter einem nginx oder Apache Webserver betrieben, muss Seahub mit dem Parameter „-fastcgi“ gestartet werden. Kommt MySQL statt SQLite zum Einsatz, muss dafür gesorgt werden, dass Seafile erst nach MySQL gestartet wird. In die Datei „seafile.service“ kommt folgender Inhalt.

sudo nano /etc/systemd/system/seafile.service
[Unit]
Description=seafile
After=network.target
# Beispielt, wenn MySQL zum Einsatz kommt
#After=network.target mysqld.service

[Service]
Type=oneshot
RemainAfterExit=yes 
User=seafile
ExecStart=/home/seafile/seafile-server-latest/seafile.sh start
# Beispiel, wenn kein Apache oder nginx Webserver eingesetzt wird
# Pfade müssen ggf. an eigene Installation angepasst werden
ExecStart=/home/seafile/seafile-server-latest/seahub.sh start
ExecStart=/home/seafile/seafile-server-latest/seahub.sh start-fastcgi
ExecStop=/home/seafile/seafile-server-latest/seafile.sh stop
ExecStop=/home/seafile/seafile-server-latest/seahub.sh stop

[Install]
WantedBy=multi-user.target

Sobald der Dienst angelegt ist, muss die Konfiguration neu eingelesen werden.

sudo systemctl daemon-reload

Jetzt kann Seafile per Dienst automatisch gestartet werden.

sudo systemctl start seafile.service

Damit der Dienst beim Systemstart auch ausgeführt wird, muss er noch aktiviert werden.

sudo systemctl enable seafile.service

Wer Seafile bisher per Cronjob gestartet hat, benötigt diesen nicht mehr. Jetzt geht es weiter mit dem eigentlichen Backup der Seafile Daten. Dazu wird ein Medium (Festplatte, USB Stick, Share) benötigt. Ein Laufwerk muss dauerhaft gemountet werden. Um herauszufinden unter welcher Bezeichnung der Stick verfügbar ist, folgenden Befehl ausführen.

sudo fdisk -l

Das Ergebnis sollte ungefähr so aussehen:

Disk /dev/mmcblk0: 31.9 GB, 31914983424 bytes
4 heads, 16 sectors/track, 973968 cylinders, total 62333952 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00035a41
Device Boot Start End Blocks Id System
/dev/mmcblk0p1 8192 122879 57344 c W95 FAT32 (LBA)
/dev/mmcblk0p2 122880 62333951 31105536 83 Linux

Disk /dev/sda: 7748 MB, 7748222976 bytes
247 heads, 9 sectors/track, 6807 cylinders, total 15133248 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xc3072e18

Device Boot Start End Blocks Id System
/dev/sda1 2048 15132671 7565312 83 Linux

In diesem Fall ist das Device als „/dev/sda1“ bekannt. Als Dateisystem bietet sich hier ext4 an. Der Stick sollte ja eigentlich auch niemals ein Windows System zu Gesicht bekommen. Um den Stick zu mounten, sind ein Verzeichnis und ein Eintrag in der fstab erforderlich.

sudo mkdir /mnt/backup
sudo nano /etc/fstab

In der fstab wird die Zeile angehängt:

/dev/sda1 /mnt/backup ext4 rw 0 0

Ab sofort wird der Stick bei jedem Systemstart automatisch gemountet und kann über „/mnt/backup/“ angesprochen werden. Damit der Stick ohne Neustart zur Verfügung steht, kann ein weiterer Befehl ausgeführt werden.

sudo mount /dev/sda1 /mnt/backup

Falls mehrere Dienste in das Backup aufgenommen werden sollen, bietet es sich an, entsprechende Unterverzeichnisse anzulegen, um eine bessere Sortierung zu haben.

sudo mkdir -p /mnt/backup/seafile/database

Schon gibt es ein Ziel für das zukünftige Backup. Fehlt nur noch ein Skript. Dieses kann z.B. unter „/usr/local/bin“ abgelegt werden.

Als Inhalt wird folgendes eingefügt:

sudo nano /usr/local/bin/daily_backup.sh
#!/bin/bash
#
backup_dir='/mnt/backup'
# looking for 3 days old database backups and delete them
find $backup_dir/seafile/database -maxdepth 1 -mtime +3 -type f -delete

# stop seafile
systemctl stop seafile.service

# create a full backup of complete seafile files
rsync -avz --delete --exclude 'ccnet.sock' /home/seafile/ $backup_dir/seafile/files/

# create sqlite database backup. Remove this lines, if you use mysql
sqlite3 /home/seafile/ccnet/GroupMgr/groupmgr.db .dump > $backup_dir/seafile/database/groupmgr.db.bak.`date +"%Y%m%d"`
sqlite3 /home/seafile/ccnet/PeerMgr/usermgr.db .dump > $backup_dir/seafile/database/usermgr.db.bak.`date +"%Y%m%d"`
sqlite3 /home/seafile/seafile-data/seafile.db .dump > $backup_dir/seafile/database/seafile.db.bak.`date +"%Y%m%d"`
sqlite3 /home/seafile/seahub.db .dump > $backup_dir/seafile/database/seahub.db.bak.`date +"%Y%m%d"`

# start seafile
systemctl start seafile.service

Der Pfad „/home/seafile“ muss ggf. noch an die eigene Konfiguration angepasst werden. Wer Seafile mit MySQL statt SQLite betreibt, kann noch folgende Befehle hinzufügen, um ein Datenbank Backup anzulegen.

mysqldump -h localhost -u CCNET_DATABASEUSER -pYOURPASSWORD CCNET_DATABASE_NAME > $backup_dir/seafile/database/ccnet-sqlbkp_`date +"%Y%m%d"`.sql
mysqldump -h localhost -u SEAFILE_DATABASEUSER -pYOURPASSWORD SEAFILE_DATABASE_NAME > $backup_dir/seafile/database/seafile-sqlbkp_`date +"%Y%m%d"`.sql
mysqldump -h localhost -u SEAHUB_DATABASEUSER -pYOURPASSWORD SEAHUB_DATABASE_NAME > $backup_dir/seafile/database/seahub-sqlbkp_`date +"%Y%m%d"`.sql

Das Skript muss noch ausführbar gemacht werden.

chmod +x /usr/local/bin/daily_backup.sh

Für einen ersten Test kann das Skript auch direkt gestartet werden, um zu sehen, ob das Seafile Backup funktioniert.

sudo sh /usr/local/bin/daily_backup.sh

Wenn alles erfolgreich war, liegt unter „/mnt/backup/seafile“ eine neue tar Datei mit dem aktuellen Datum. Als letzter Schritt kommt jetzt die tägliche Ausführung des Skripts. Dazu wird ein Cronjob angelegt, der mit root Rechten ausgeführt wird.

sudo crontab -e

Hier wird unten stehende Zeile eingefügt. Die Zeiten können nach Belieben angepasst werden.

# execute maintenance script at 01:00 am
 00 1 * * * sh /usr/local/bin/daily_backup.sh > /tmp/daily_backup.log 2>&1

Bei der Ausführung wird auch gleich ein Logfile mitgeschrieben, sollte etwas nicht funktionieren. Dieses Skript kann jetzt natürlich nach Belieben erweitert werden, um weitere Daten zu sichern, oder das System aufzuräumen.