Seafile
Seafile ist eine Alternative zu Nextcloud und Owncloud. Die Lösung ist schlanker und schneller, nicht zuletzt deshalb, weil sie auf viele Features verzichtet und sich vornehmlich auf Synchronisation und Teilen von Dateien konzentriert. Die Community Edition ist Open Source. Hier beschreibe ich, wie ich sie unter Docker und unter Verwendung des Reverse Proxy Caddy bei einem Hoster betreibe.
Installation der Software
Docker
Voraussetzung ist ein Linux-Server auf dem Docker installiert ist. Ich verwende dazu mein Bash-Script:
# Shell-Skript zur Installation von Docker (mit sudo ausführen:
#!/bin/bash
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
apt-get remove $pkg;
done
apt-get update
apt-get install ca-certificates curl
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl start docker
systemctl enable docker
usermod -aG docker "$SUDO_USER"Hier ist das in der Version für Debian-Server. Für Ubuntu muss natürlich die Zeichenkette "debian" durch "ubuntu" ersetzt werden. Dieses Script, ich nenne es dockerinstall.sh, mache ich ausführbar und führe mit sudo, also mit Administrationsrechten aus.
chmod +x dockerinstall.sh
sudo ./dockerinstall.shDanach melde mich einmal kurz ab und wieder an, damit die neuen Berechtigungen greifen und ich ohne Root-Rechte docker ausführen kann.
Caddy
Seafile kann von Hause aus nur HTTP, also eine unverschlüsselte Verbindung. Das ist aber für Filesync und -sharing nicht vertretbar. Manche Clients lassen das auch gar nicht zu. Ich brauche also ein SSL-Zertifikat und muss den Zugang damit absichern. Darum kümmert sich Caddy. Caddy ist ein Reverseproxy. Er ermöglicht die Nutzung von HTTPS und kümmert sich auch selbständig um die Zertifikatsverwaltung via Let's Encrypt. Also muss ich nun zunächst Caddy installieren. Das geht unter Debian und Ubuntu einfach wie folgt:
# 1. Benötigte Pakete für die Key-Verwaltung installieren
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
# 2. Den offiziellen Caddy-GPG-Key hinzufügen
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
# 3. Die Caddy-Paketquelle hinzufügen
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
# 4. Paketliste aktualisieren und Caddy installieren
sudo apt update
sudo apt install caddyInstallation von Seafile mittels Docker Compose
Zunächst erstelle ich einen Ordner für die Compose-Files. Ich mache das üblicherweise im Homeshare also muss ich einfach mit
mkdir seafile
cd seafileeinen Ordner erstellen und öffnen. Dann erstelle ich zunächst das File mit den Umgebungsvariablen mit
nano .envDer Punkt am Anfang des Namens ist wichtig, damit es eine versteckte Datei ist und damit Docker das File auch findet. Es bekommt folgenden Inhalt:
# Datenbank (Generiere hier ein neues, langes Passwort!)
DB_ROOT_PASSWORD=EinmöglichstkomplexesundgeheimesPasswortwiezumBeispiel123456
DB_PASSWORD=dto
# Seafile Admin
SEAFILE_ADMIN_EMAIL=mail@adresse.tld
SEAFILE_ADMIN_PASSWORD=nocheingeheimeslpasswort
# Wichtig: Die echte Domain ohne Protokoll
SEAFILE_SERVER_HOSTNAME=(sub)domain.des.servers
# Zeitzone
TIME_ZONE=Europe/Berlin
# JWT Schlüssel (Neu generieren: openssl rand -base64 32)
JWT_PRIVATE_KEY=Mit openssl rand -base64 32 generieren und hier einfügen!Dann brauche ich noch eine Datei docker-compose.yml mit folgendem Inhalt:
services:
db:
image: mariadb:10.11
container_name: seafile-mysql
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
- MARIADB_AUTO_UPGRADE=1
volumes:
- /opt/seafile/shared/db:/var/lib/mysql
networks:
- seafile-internal
memcached:
image: memcached:1.6
container_name: seafile-memcached
entrypoint: memcached -m 256
networks:
- seafile-internal
seafile:
image: seafileltd/seafile-mc:latest
container_name: seafile
restart: unless-stopped
ports:
- "127.0.0.1:8080:80" # Web-UI (nur lokal für Caddy)
- "127.0.0.1:8082:8082" # Fileserver (nur lokal für Caddy)
environment:
- DB_HOST=db
- DB_ROOT_PASSWD=${DB_ROOT_PASSWORD}
- TIME_ZONE=${TIME_ZONE}
- SEAFILE_ADMIN_EMAIL=${SEAFILE_ADMIN_EMAIL}
- SEAFILE_ADMIN_PASSWORD=${SEAFILE_ADMIN_PASSWORD}
- SEAFILE_SERVER_HOSTNAME=${SEAFILE_SERVER_HOSTNAME}
- SEAFILE_SERVER_LETSENCRYPT=false # Caddy macht SSL, nicht Seafile!
- JWT_PRIVATE_KEY=${JWT_PRIVATE_KEY}
volumes:
- /opt/seafile/shared/seafile-data:/shared
depends_on:
- db
- memcached
networks:
- seafile-internal
networks:
seafile-internal:
driver: bridgeHier braucht nichts angepasst zu werden, weil die Parameter in der .env-Datei stehen.
Konfigurationen
Caddy-Konfiguration
Für Caddy muss ich noch ein Caddyfile schreiben. Ich erstelle (oder falls vorhanden bearbeite) eine Datei namens /etc/caddy/Caddyfile mit folgendem Inhalt:
# Die Domain beim Hoster
sub.domain.tld {
# Logging (optional, aber nützlich)
log {
output file /var/log/caddy/seafile_access.log
}
# Der eigentliche Proxy zur Seafile Web-UI
reverse_proxy 127.0.0.1:8080
# Spezielle Behandlung für den Fileserver (Upload/Download)
handle_path /seafhttp* {
reverse_proxy 127.0.0.1:8082
}
# Sicherheit: HSTS aktivieren
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
}
}Das ist schon alles. Nun starte ich Caddy einmal neu mit
sudo systemctl restart caddyund der Reverseproxy ist am Start.
Konfiguration Seafile
Leider können nicht alle für den Betrieb erforderlichen Parameter über das .env-File oder die Compose-Datei definiert werden. Ich muss auch noch eine Datei mit Einstellungen bearbeiten, die aber erst beim ersten Starten des Seafile-Containers erzeugt wird. Ich starte daher die Container mit
docker compose up -dDabei ist natürlich wichtig, dass ich mich auf der Shell in dem Ordner mit der Datei docker-compose.yml befinde, in meinem Beispiel also im Verzeichnis saefile in meinem Homeshare auf dem Server. Mit der Volume-Definition "- /opt/seafile/shared/seafile-data:/shared" in der Compose-Datei habe ich vorgegeben, dass die Systemdateien im Verzeichnis /opt/seafile erstellt werden. Im Pfad /opt/seafile/shared/seafile-data/seafile/conf befindet sich nun eine Datei namens seahub_settings.py die ich anpassen muss.
sudo nano /opt/seafile/shared/seafile-data/seafile/conf/seahub_settings.pySie bekommt folgenden Inhalt bzw. wird wie folgt ergänzt:
# -*- coding: utf-8 -*-
SECRET_KEY = "wurde automatisch erzeugt; nicht ändern!"
SERVICE_URL = "https://sub.domain.tld"
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'seahub_db',
'USER': 'seafile',
'PASSWORD': 'nichtändern',
'HOST': 'db',
'PORT': '3306',
'OPTIONS': {'charset': 'utf8mb4'},
}
}
CACHES = {
'default': {
'BACKEND': 'django_pylibmc.memcached.PyLibMCCache',
'LOCATION': 'memcached:11211',
},
'locmem': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
},
}
COMPRESS_CACHE_BACKEND = 'locmem'
TIME_ZONE = 'Europe/Berlin'
FILE_SERVER_ROOT = "https://sub.domain.tld/seafhttp"
CSRF_TRUSTED_ORIGINS = ["https://sub.domain.tld"]
# E-Mail Einstellungen
EMAIL_USE_TLS = False
EMAIL_HOST = "mail.domain.tld" # SMTP-Server deines Providers
EMAIL_PORT = 465 # Port für TLS (meist 587)
EMAIL_HOST_USER = "seafile@domain.dlt" # Dein Benutzername/E-Mail
EMAIL_HOST_PASSWORD = "TrIuMp,66,=" # Dein Passwort
EMAIL_FROM_USER = "seafile@domain.tld" # Absender-Adresse
SERVER_EMAIL = "seafile@domain.tld" # Adresse für System-Benachrichtigungen
DEFAULT_FROM_EMAIL = EMAIL_FROM_USER
EMAIL_USE_SSL = TrueDanach kann man sich (hoffentlich) zum ersten Mal auf der Oberfläche mit dem zuvor definierten Account (s.o. SEAFILE_ADMIN_EMAIL und SEAFILE_ADMIN_PASSWORD) anmelden.
Backup
Ohne Datensicherung ist ein Cloudspeicher natürlich nicht sicher zu betreiben. Für Seafile müssen die Datenbankinhalte und die Daten innerhalb des Verzeichnisses /opt/seafile gesichert werden. Die eigentliche Sicherung mache ich mit duplicati aber zunächst brauche ich einen Datenbankdump, damit die Wiederherstellung im Notfall funktioniert. Dazu erstelle ich ein kleines Script im Verzeichnis /opt/ namens seafile-backup.sh. Dieses Script habe ich freundlicherweise von Gemini erstellt bekommen. Ich habe es getestet und für gut befunden.
sudo nano /opt/seafile-backup.shmit folgendem Inhalt:
#!/bin/bash
# --- KONFIGURATION ---
BACKUP_DIR="/opt/seafile/shared/backups" # Verzeichnis auf dem HOST
CONTAINER_NAME="seafile-mysql"
DB_USER="root"
DB_PASS="DEIN_PASSWORT_OHNE_LEERZEICHEN"
KEEP_DAYS=7 # Wie viele Tage sollen die lokalen SQL-Dumps behalten werden?
# Datum für den Dateinamen
DATE=$(date +%Y-%m-%d_%H-%M)
FILENAME="seafile_complete_$DATE.sql"
# Verzeichnis erstellen, falls nicht vorhanden
mkdir -p $BACKUP_DIR
# --- DUMP ERSTELLEN ---
echo "Starte Datenbank-Backup für Seafile..."
docker exec $CONTAINER_NAME mariadb-dump \
-u $DB_USER \
-p$DB_PASS \
--databases ccnet_db seafile_db seahub_db > $BACKUP_DIR/$FILENAME
# Prüfen, ob der Dump erfolgreich war
if [ $? -eq 0 ]; then
echo "Backup erfolgreich: $FILENAME"
# Optional: Erfolgsmeldung per Mail (falls 'mailutils' installiert sind)
# echo "Seafile Backup erfolgreich erstellt am $DATE" | mail -s "Seafile Backup OK" mail@deine-domain.de
else
echo "FEHLER: Backup fehlgeschlagen!" >&2
exit 1
fi
# --- ALTE DUMPS LÖSCHEN ---
# Löscht Dateien, die älter als KEEP_DAYS sind, um Platz zu sparen
find $BACKUP_DIR -name "seafile_complete_*.sql" -mtime +$KEEP_DAYS -exec rm {} \;
echo "Bereinigung abgeschlossen."Dieses Script mache ich natürlich ausführbar mit
sudo chmod +x /opt/seafile-backup.shund teste es mit
sudo /opt/seafile-backup.shWenn dabei kein Fehler auftritt, dann meldet das Script "Backup erfolgreich: seafile_complete_JJJ-MM-TT_hh-mm.sql". Ich kann das Script nun also in die Crontab eintragen, damit es nächtens automatisert ausgeführt wird.
Ich rufe die crontab-Bearbeitung für den Administrationsuser mit
sudo crontab -eauf. Wenn ich bisher keinen Standard-Editor für die Bearbeitung der Crontab angegeben habe, werde ich nun danach gefragt. Hier wähle ich mit Enter den vorgeschlagenen Editor nano aus:
no crontab for andreas - using an empty one
Select an editor. To change later, run 'select-editor'.
1. /bin/nano <---- easiest
2. /usr/bin/vim.basic
3. /usr/bin/vim.tiny
4. /bin/ed
Choose 1-4 [1]: 1An das Ende dieser Datei trage ich dann ein:
0 7 * * * /opt/seafile-backup.shSo werden die Backups immer morgens um 7:00 Uhr durchgeführt und die Benachrichtigungen zu Erfolg oder Misserfolg der Aktion werden an den User root gemailt (wenn Mails auf dem System konfiguriert sind).
Dann richte ich die eigentliche Datensicherung mit duplicati ein. Damit sichere ich einfach den kompletten Ordner /opt/seafile
Exkurs: Sicherung einzelner Dateien/Dokumente
Seafile speichert die Dokumente in Chunks aufgesplittet. Dadurch ist ein Restore nicht für einzelne Dokumente, sondern nur komplett möglich. Wenn man nun aber einzelne Dokumente sichern und wiederherstellen möchte, dann kann man sie zu diesem Zweck zunächst temporär mounten. Dazu gibt es im Container seafile das script seaf-fuse.sh. Das folgende Script - ich nenne es backupfiles.sh - mountet zunächst temporär die Bibliotheken in ein Verzeichnis auf dem Server und synchronisiert die Dokumente mit einem lokalen Verzeichnis. Dabei werden verschlüsselte Verzeichnisse ausgelassen. Außerdem wird so der doppelte Speicher belegt und die Dateien liegen offen auf dem Server. Die Chunks stellen aber natürlich auch keine Verschlüsselung dar.
#!/bin/bash
# 1. Sicherstellen, dass der Mount-Punkt leer/sauber ist
fusermount -u /opt/seafile-fuse 2>/dev/null
# 2. Mount im Container starten
docker exec seafile /opt/seafile/seafile-server-latest/seaf-fuse.sh start /shared/fuse
# 3. Kurz warten, bis das Dateisystem bereit ist
sleep 5
# 4. Der Backup-Befehl (hier rsync)
# Hier werden jetzt alle Dateien im Klartext kopiert
rsync -av --delete /opt/seafile-fuse/ /opt/seafile/filebackup
# 5. Sauber unmounten
docker exec seafile /opt/seafile/seafile-server-latest/seaf-fuse.sh stop
sudo umount -l /opt/seafile-fuse 2>/dev/nullDas Script wird natürlich ausführbar gemacht
chmod +x backupfiles.shund kann dann mit Administrationsrechten ausgeführt werden. Testweise kann man es aufrufen mit
sudo ./backupfiles.shWenn das soweit klappt, kann man das Script mittels Cronjob automatisieren (s.o).
Nutzung von Seafile
Die Weboberfläche von Seafile ist recht selbsterklärend und wird hier nicht weiter erläutert. Für Android, iOS, MacOS, Windows und Linux gibt es Clients. Nähere Informationen dazu siehe: Downloadseite von Seafile und natürlich die App-Shops von Google und Apple.