AppFlowy mit Docker installieren: Open-Source-Notion-Alternative mit KI-Workspace selbst hosten
AppFlowy ist eine Open-Source-Alternative zu Notion. Die Anleitung zeigt, wie Sie AppFlowy Cloud 0.19 mit Docker Compose und Garage als S3-Speicher betreiben und bestehende MinIO-Installationen umziehen.
Geprüft am 04.10.2026 · für appflowy_cloud 0.19.0, garage 2.4.1
Mit KI erstellt – redaktionelle Prüfung ausstehend
WerbelinksMit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

AppFlowy ist eine Open-Source-Alternative zu Notion für Wikis, Projekt-Boards und Datenbankansichten (AGPL-3.0). AppFlowy Cloud läuft als Docker-Compose-Stack mit PostgreSQL, Redis, GoTrue für die Anmeldung, einem S3-Speicher für Dateien und nginx. Das offizielle Compose nutzt MinIO, dessen Image minio/minio auf Docker Hub nicht mehr verfügbar ist. Diese Anleitung installiert AppFlowy Cloud 0.19 mit Garage als S3-Speicher und zeigt den Umzug bestehender MinIO-Installationen.
Voraussetzungen
- Docker Engine 24 oder neuer mit Compose-Plugin (
docker compose), siehe Docker und Docker Compose auf Linux installieren. - Linux-Server, x86-64 oder ARM64, mit
gitundopenssl. - 2 CPU-Kerne und 4 GB RAM. Im Test lief der Stack ohne KI-Dienst auf 2 Kernen und 3 GB RAM mit unter 1 GB Belegung; größere Teams planen 4 Kerne und 8 GB ein.
- Mindestens 50 GB freier Speicher.
- Für HTTPS eine Domain mit Zertifikat.
Schritt 1: Projektordner anlegen und Repository-Dateien holen
Klonen Sie das offizielle Repository in einen eigenen Ordner. Es enthält die Compose-Datei, die Vorlage deploy.env und die nginx-Konfiguration:
sudo mkdir -p /opt/appflowy
sudo chown $USER: /opt/appflowy
cd /opt/appflowy
git clone https://github.com/AppFlowy-IO/AppFlowy-Cloud.git .Der Ordnername ergibt den Projektnamen, daher heißen Volumes und Netz später appflowy_….
Verifizieren: ls /opt/appflowy/ zeigt unter anderem docker-compose.yml, deploy.env und nginx/.
Schritt 2: Umgebungsvariablen konfigurieren (.env)
Passwörter, Secrets, Domain und die S3-Anbindung stehen in der .env. Erzeugen Sie zuerst die Zufallswerte, die Sie gleich eintragen:
openssl rand -hex 32 # JWT-Secret, rpc_secret, Garage-Secret
echo "GK$(openssl rand -hex 16)" # Garage-Zugangsschlüssel
cp deploy.env .env
nano .envÄndern Sie diese Werte; die Vorlage enthält öffentlich bekannte Standardwerte wie hello456 und minioadmin. Eine spätere Änderung des JWT-Secrets meldet alle Nutzer ab.
FQDN=appflowy.example.com # localhost für einen Test
SCHEME=https # http für einen Test
WS_SCHEME=wss # ws bei http
POSTGRES_PASSWORD=SICHERES_DB_PASSWORT
GOTRUE_JWT_SECRET=MINDESTENS_32_ZUFAELLIGE_ZEICHEN
GOTRUE_ADMIN_EMAIL=admin@example.com
GOTRUE_ADMIN_PASSWORD=SICHERES_ADMIN_PASSWORT
GOTRUE_MAILER_AUTOCONFIRM=true # ohne SMTP true lassen
# S3: Garage statt MinIO
MINIO_HOST=garage
MINIO_PORT=3900
AWS_ACCESS_KEY=GK... # wie GARAGE_ACCESS_KEY
AWS_SECRET=... # wie GARAGE_SECRET_KEY
APPFLOWY_S3_CREATE_BUCKET=false
APPFLOWY_S3_REGION=garage # in der Vorlage auskommentiert
# Versionen (Stand Oktober 2026)
APPFLOWY_CLOUD_VERSION=0.19.0
GOTRUE_VERSION=0.18.11
APPFLOWY_WORKER_VERSION=0.19.0
APPFLOWY_SEARCH_VERSION=0.19.0
APPFLOWY_WEB_VERSION=0.19.4
APPFLOWY_ADMIN_FRONTEND_VERSION=0.18.2
# neu am Dateiende
GARAGE_ACCESS_KEY=GK...
GARAGE_SECRET_KEY=...APPFLOWY_S3_MINIO_URL setzt sich aus MINIO_HOST und MINIO_PORT zusammen. APPFLOWY_S3_USE_MINIO=true bleibt stehen: Der Schalter bedeutet nur „eigener S3-Endpunkt im Path-Style statt AWS“. Garage-Schlüssel beginnen mit GK; für GoTrue und Admin-Frontend gibt es kein 0.19-Image.
Garage als S3-Speicher einrichten
Garage ist ein schlanker, gepflegter S3-Server. Mit --single-node --default-bucket legt er beim ersten Start Layout, Schlüssel und Bucket selbst an (Grundlagen: S3-Speicher selbst hosten mit Garage). Legen Sie garage.toml an:
metadata_dir = "/var/lib/garage/meta"
data_dir = "/var/lib/garage/data"
db_engine = "sqlite"
replication_factor = 1
rpc_bind_addr = "[::]:3901"
rpc_public_addr = "127.0.0.1:3901"
rpc_secret = "ERGEBNIS_VON_openssl_rand_-hex_32"
[s3_api]
s3_region = "garage"
api_bind_addr = "[::]:3900"Compose liest docker-compose.override.yml automatisch zusätzlich; die offizielle Datei bleibt unverändert:
services:
minio:
profiles: ["minio"] # nur noch auf Anforderung
ai:
profiles: ["ai"] # optional, Schritt 7
garage:
image: dxflrs/garage:v2.4.1
restart: unless-stopped
command: ["/garage", "server", "--single-node", "--default-bucket"]
environment:
- GARAGE_DEFAULT_ACCESS_KEY=${GARAGE_ACCESS_KEY}
- GARAGE_DEFAULT_SECRET_KEY=${GARAGE_SECRET_KEY}
- GARAGE_DEFAULT_BUCKET=${APPFLOWY_S3_BUCKET}
volumes:
- ./garage.toml:/etc/garage.toml:ro
- garage_meta:/var/lib/garage/meta
- garage_data:/var/lib/garage/data
healthcheck:
test: ["CMD", "/garage", "status"]
interval: 10s
timeout: 5s
retries: 6
appflowy_cloud:
depends_on:
garage:
condition: service_healthy
volumes:
garage_meta:
garage_data:nginx leitet /minio-api/ (signierte S3-Adressen) noch an MinIO. Umstellen:
sed -i -e 's#http://minio:9000#http://garage:3900#' \
-e 's#"minio:9000"#"garage:3900"#' nginx/nginx.conf
grep -n 'garage' nginx/nginx.confVerifizieren: grep -nE "hello456|minioadmin" .env liefert nichts, docker compose config --services nennt garage, aber weder minio noch ai.
Schritt 3: SSL-Zertifikat vorbereiten (für HTTPS)
Ersetzen Sie die Platzhalter nginx/ssl/certificate.crt und private_key.key durch Ihr Zertifikat. Für einen Test genügt ein selbstsigniertes:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout nginx/ssl/private_key.key \
-out nginx/ssl/certificate.crt \
-subj "/CN=localhost"Produktiv eignet sich Let's Encrypt oder ein Reverse Proxy, siehe Traefik als Docker-Reverse-Proxy mit automatischem HTTPS einrichten.
Verifizieren: openssl x509 -in nginx/ssl/certificate.crt -noout -subject -enddate zeigt Ihren Hostnamen und ein Ablaufdatum in der Zukunft.
Schritt 4: Docker Compose Stack starten
Starten Sie den Stack. Beim ersten Start lädt Docker alle Images:
cd /opt/appflowy
docker compose up -dPostgres und Garage starten zuerst, dann GoTrue, dann AppFlowy Cloud mit den Datenbankmigrationen. Im Test antwortete /api/health nach etwa 30 Sekunden; vorher liefert nginx 502. docker compose ps zeigt zehn Dienste, davon postgres, garage, gotrue, appflowy_cloud und appflowy_search als healthy.
docker compose ps
docker compose exec garage /garage bucket list # Alias appflowyVerifizieren: curl -s -o /dev/null -w "%{http_code}\n" http://localhost/api/health liefert 200. Das Log enthält Setting up S3 bucket (bucket=appflowy, region=garage, ... endpoint=http://garage:3900/ ...):
docker compose logs appflowy_cloud | grep -E "Setting up S3|Skipping bucket|version:0.19"Bei Problemen: docker compose logs garage gotrue --tail 30.
Schritt 5: Erster Login im Browser
Öffnen Sie http://localhost bzw. https://appflowy.example.com. Die Web-App leitet zur Anmeldung, wo Sie Konten registrieren. Die Verwaltung unter /console öffnen Sie mit GOTRUE_ADMIN_EMAIL und GOTRUE_ADMIN_PASSWORD.
Mit GOTRUE_MAILER_AUTOCONFIRM=true ist ein Konto sofort bestätigt. Test ohne Browser:
curl -s -X POST http://localhost/gotrue/signup \
-H "Content-Type: application/json" \
-d '{"email":"anna@example.com","password":"LangesPasswort123"}' | head -c 120; echo
# Erwartet: JSON mit "access_token" und dem BenutzerobjektEine zweite Registrierung derselben Adresse liefert User already registered, ein falsches Passwort an /gotrue/token?grant_type=password Invalid login credentials. Neue Konten erhalten den Workspace „My Workspace“.
Verifizieren: curl -I http://localhost/ liefert 302 zur Anmeldung, curl -s -o /dev/null -w "%{http_code}\n" http://localhost/console liefert 200. Laden Sie in einem Dokument eine Datei hoch: docker compose exec garage /garage bucket info appflowy zeigt danach Objects: 1. Im Test lag die Datei als <workspace-id>/<ordner-id>/<datei-id> im Bucket und war auch nach einem Neustart unverändert abrufbar.
Schritt 6: Desktop-App mit dem eigenen Server verbinden
Installieren Sie die Desktop-App ab v0.14.6 von appflowy.com, öffnen Sie auf dem Anmeldebildschirm die Cloud-Einstellungen, wählen Sie „AppFlowy Cloud (Self-hosted)“, tragen Sie die Server-URL ein (z. B. https://appflowy.example.com) und starten Sie die App neu. Ein zusätzlicher Proxy vor nginx muss WebSocket-Upgrades (/ws) weiterleiten.
Verifizieren: Nach der Anmeldung erscheint der Workspace, und ein im Browser angelegtes Dokument taucht nach wenigen Sekunden in der App auf.
Schritt 7: KI-Funktionen aktivieren (optional)
Die KI-Funktionen laufen über den Dienst ai und die OpenAI-API. Ohne Key ist er nutzlos, daher startet er nur über das Profil ai. Tragen Sie in die .env ein:
AI_OPENAI_API_KEY=sk-...
APPFLOWY_AI_VERSION=0.17.7Das Modell steht in der Compose-Datei (gpt-4.1-mini). Start:
docker compose --profile ai up -d aiDauerhaft aktivieren Sie es mit COMPOSE_PROFILES=ai in der .env.
Verifizieren: docker compose --profile ai ps ai zeigt nach etwa einer Minute healthy, und docker compose logs ai --tail 20 enthält start server on 0.0.0.0:5001.
Schritt 8: Updates durchführen und Daten sichern
Für ein Update erhöhen Sie die Versionsvariablen und aktualisieren das Repository; die geänderte nginx.conf parkt git stash dabei. Vorher sichern:
cd /opt/appflowy
# 1. Datenbank sichern
docker compose exec -T postgres pg_dumpall -U postgres > backup_$(date +%Y%m%d).sql
# 2. Garage-Volumes sichern (Garage vorher kurz stoppen)
docker compose stop garage
docker run --rm -v appflowy_garage_meta:/meta -v appflowy_garage_data:/data \
-v "$PWD":/backup alpine tar czf /backup/garage_$(date +%Y%m%d).tar.gz /meta /data
docker compose start garage
# 3. Images aktualisieren und Stack neu starten
git stash && git pull && git stash pop
docker compose pull
docker compose up -dZur Sicherung gehören Datenbank, beide Garage-Volumes zusammen sowie .env, garage.toml und die Override-Datei. Den Suchindex baut AppFlowy neu auf. Automatisierung: MySQL & PostgreSQL Backup automatisieren mit cron.
Umstieg von 0.18 auf 0.19
Die Desktop-App ab v0.14.6 braucht AppFlowy Cloud ab 0.19.0. Aktualisieren Sie daher zuerst den Server (Versionen wie in Schritt 2, docker compose pull, up -d; die Migrationen laufen beim Start), danach die Apps.
Von MinIO auf Garage umziehen
Bestehende Installationen laufen weiter, solange das MinIO-Image lokal liegt; docker compose pull scheitert aber mit pull access denied for minio/minio. Legen Sie garage.toml, die Override-Datei und die GARAGE_*-Zeilen wie in Schritt 2 an, die übrigen S3-Werte bleiben vorerst auf MinIO. Dann schreibende Dienste stoppen und beide Speicher starten:
docker compose stop appflowy_cloud appflowy_worker appflowy_search
docker compose pull garage
docker compose --profile minio up -d minio garage
docker compose --profile minio ps minio garage # beide healthyFehlt das MinIO-Image, ergänzen Sie unter minio: vorübergehend image: pgsty/minio:RELEASE.2026-08-04T00-00-00Z (gepflegter Fork). rclone kopiert dann den Bucket und vergleicht beide Seiten:
RC="docker run --rm --network appflowy_default
-e RCLONE_CONFIG_MINIO_TYPE=s3 -e RCLONE_CONFIG_MINIO_PROVIDER=Minio
-e RCLONE_CONFIG_MINIO_ENDPOINT=http://minio:9000
-e RCLONE_CONFIG_MINIO_ACCESS_KEY_ID=ALTER_AWS_ACCESS_KEY
-e RCLONE_CONFIG_MINIO_SECRET_ACCESS_KEY=ALTES_AWS_SECRET
-e RCLONE_CONFIG_GARAGE_TYPE=s3 -e RCLONE_CONFIG_GARAGE_PROVIDER=Other
-e RCLONE_CONFIG_GARAGE_ENDPOINT=http://garage:3900
-e RCLONE_CONFIG_GARAGE_REGION=garage -e RCLONE_CONFIG_GARAGE_FORCE_PATH_STYLE=true
-e RCLONE_CONFIG_GARAGE_ACCESS_KEY_ID=GK...
-e RCLONE_CONFIG_GARAGE_SECRET_ACCESS_KEY=... rclone/rclone:1.75.1"
$RC sync minio:appflowy garage:appflowy -v
$RC check minio:appflowy garage:appflowyStellen Sie danach die S3-Werte der .env wie in Schritt 2 auf Garage um, führen Sie den sed-Befehl für nginx aus und starten Sie neu:
docker compose --profile minio stop minio
docker compose up -d
docker compose exec garage /garage bucket info appflowy | grep -E "Size|Objects"Bis alles einige Tage stabil läuft, bleibt appflowy_minio_data Ihr Rückweg. Danach entfernen Sie es mit docker compose --profile minio rm -f minio und docker volume rm appflowy_minio_data.
Verifizieren: rclone check meldet 0 differences found und die Zahl der übereinstimmenden Dateien. Danach ist appflowy_cloud healthy und alte Anhänge öffnen sich. Im Test waren zwei vorher hochgeladene Dateien unverändert abrufbar, ein neuer Upload landete in Garage, das Log blieb fehlerfrei.
Stack-Übersicht
Tags laut Schritt 2; ohne Variablen gilt latest. Zu sichern sind postgres_data, garage_meta und garage_data.
| Dienst | Image | Rolle | Port |
|---|---|---|---|
| nginx | nginx | Reverse Proxy, TLS | 80, 443 |
| postgres | pgvector/pgvector:pg16 | Datenbank, Vektorspeicher | intern 5432 |
| redis | redis | Cache, Pub/Sub | intern 6379 |
| garage | dxflrs/garage:v2.4.1 | S3-Speicher für Dateien | intern 3900 |
| gotrue | appflowyinc/gotrue:0.18.11 | Anmeldung, JWT | intern 9999 |
| appflowy_cloud | appflowyinc/appflowy_cloud:0.19.0 | Backend | intern 8000 |
| admin_frontend | appflowyinc/admin_frontend:0.18.2 | Admin-UI (/console) | intern 3000 |
| appflowy_worker | appflowyinc/appflowy_worker:0.19.0 | Hintergrundjobs | keiner |
| appflowy_search | appflowyinc/appflowy_search:0.19.0 | Volltextsuche | intern 4002 |
| appflowy_web | appflowyinc/appflowy_web:0.19.4 | Web-Frontend | intern 80 |
| ai (Profil ai) | appflowyinc/appflowy_ai:0.17.7 | KI-Dienst | intern 5001 |
Troubleshooting / Typische Fehler
pull access denied for minio/minio: Das MinIO-Image ist auf Docker Hub nicht mehr verfügbar. Lösung: Garage wie in Schritt 2, Umzug wie in Schritt 8.- Login schlägt fehl, JWT-Fehler in den Logs:
GOTRUE_JWT_SECRETwurde nach dem ersten Start geändert. Lösung:docker compose up -d --force-recreate, danach melden sich alle Nutzer neu an. - appflowy_cloud startet nicht, Fehler zum Bucket: Zugangsdaten in
AWS_ACCESS_KEY/AWS_SECRETundGARAGE_*weichen voneinander ab, oder der Schlüssel beginnt nicht mitGK. Kontrolle:docker compose exec garage /garage key list. - Neue Garage-Schlüssel greifen nicht:
GARAGE_DEFAULT_*gilt nur beim ersten Start. Spätere Schlüssel legen Sie mitgarage key importundgarage bucket allowan. /minio-api/liefert 403 „Garage does not support anonymous access yet“: Normal bei Aufrufen ohne Signatur.- 502 Bad Gateway direkt nach dem Start: Der Stack fährt noch hoch.
Häufige Fragen
Kann ich AppFlowy ohne Internetzugang (air-gapped) betreiben?
Ja. Images per docker save/docker load übertragen; nur die KI-Funktionen brauchen Internet.
Wie verbinde ich die Desktop-App mit meinem Server?
Über die Cloud-Einstellungen und „AppFlowy Cloud (Self-hosted)“, siehe Schritt 6.
Ist ARM64 (Raspberry Pi, Apple Silicon, Oracle Ampere) unterstützt?
Ja. AppFlowy- und Garage-Images gibt es für amd64 und arm64. Ein Raspberry Pi mit 4 GB RAM reicht für kleine Teams ohne KI-Dienst knapp.
Was passiert, wenn ich GOTRUE_JWT_SECRET nach dem ersten Start ändere?
Alle Sitzungen werden ungültig, jeder Nutzer meldet sich neu an.
Wie führe ich Updates durch?
Wie in Schritt 8. Über neue Versionen informieren Werkzeuge aus Docker-Container automatisch aktualisieren: Diun, WUD und Renovate.
Was passiert, wenn GOTRUE_MAILER_AUTOCONFIRM=false ohne SMTP gesetzt ist?
Neue Konten bleiben unbestätigt und können sich nicht anmelden. SMTP eintragen oder den Wert auf true setzen.
Kann ich AppFlowy hinter Traefik oder Caddy betreiben?
Ja. Setzen Sie NGINX_PORT=127.0.0.1:8080, entfernen Sie Port 443 und lassen Sie den Proxy HTTPS und WebSocket-Upgrades übernehmen.
Warum Garage und nicht RustFS oder SeaweedFS?
Garage braucht im Test unter 50 MB RAM, wird gepflegt und legt Bucket und Schlüssel selbst an. Andere S3-Speicher mit Path-Style-Zugriff binden Sie über dieselben Variablen an. Vergleich: S3-Speicher selbst hosten mit Garage.
Fazit
AppFlowy Cloud 0.19 ersetzt Notion für Teams, die ihre Daten selbst halten wollen. Mit Garage statt MinIO bleibt der Stack installierbar, die Änderung umfasst nur eine Override-Datei, eine kleine Konfiguration und zwei nginx-Zeilen. Bestandsinstallationen ziehen mit rclone in wenigen Minuten um. Entscheidend bleiben eigene Secrets, feste Versionen und Sicherungen von Datenbank, Garage-Volumes und .env.
Weiterführende Anleitungen und Quellen
- S3-Speicher selbst hosten: Garage, RustFS und SeaweedFS als MinIO-Alternative
- Docker und Docker Compose auf Linux installieren: die Self-Hosting-Grundlage
- Traefik als Docker-Reverse-Proxy mit automatischem HTTPS einrichten
- MySQL & PostgreSQL Backup automatisieren mit cron
- Docker-Container automatisch aktualisieren: Diun, WUD und Renovate im Vergleich
- SiYuan mit Docker installieren: Privacy-first Wissensmanagement
Offizielle Quellen: AppFlowy-Cloud auf GitHub (docker-compose.yml, deploy.env), Garage Quick Start und rclone S3-Dokumentation.


