Wer Nextcloud heute aufsetzt bekommt nicht nur einen simplen Dateispeicher. Mit Features wie integriertem Office, Kalender- und Kontaktsynchronisation (CalDAV/CardDAV), Videochats und KI-Funktionen ist es das Schweizer Taschenmesser für die eigene IT-Infrastruktur. Nun zeige ich euch, wie ihr dies in wenigen Minuten mit Docker realisiert. Traefik dient uns hier als Reverse Proxy und stellt später den Dienst verschlüsselt per TLS bereit.
| Datum | Änderungen |
|---|---|
| 29.03.2020 | Erstellung dieser Anleitung |
| 26.04.2020 | Optimierungen (letztes Kapitel) hinzugefügt. |
| 04.09.2020 | DockerCompose angepasst, damit alles wieder funktioniert. |
| 05.09.2020 | Integration mit Collabora Office hinzugefügt. |
| 19.08.2021 | Fehler mit Datenbank behoben. Danke an Peter. |
| 02.01.2022 | Formatierungsfehler der Docker Compose Datei behoben. |
| 05.01.2022 | Anleitung für Nextcloud 23.0 angepasst. |
| 03.04.2022 | Kleinigkeiten angepasst. |
| 26.07.2022 | getestet mit Nextcloud 24.0.3 |
| 08.09.2022 | Labels für Traefik + CrowdSec angepasst; TRUSTED_PROXIES, OVERWRITEPROTOCOL, OVERWRITECLIURL,OVERWRITEHOST werden nun per Docker Compose festgelegt und nicht später von Hand. |
| 21.09.2022 | Kapitel 6.5 Cron hinzugefügt |
| 18.01.2023 | Links zu CrowdSec hinzugefügt, MariaDB Parameter –log-bin=ROW entfernt, MariaDB Parameter MARIADB_AUTO_UPGRADE=1 hinzugefügt. |
| 29.05.2023 | Update auf neue Traefik Anleitung, Kapitel 2.1 (Traefik IP ermitteln) entfernt |
| 12.07.2023 | MariaDB auf Version 10.6 festgesetzt |
| 10.01.2024 | MariaDB auf Version 10.11 festgesetzt. Danke an @goover |
| 10.01.2024 | Kapitel 6.5 OnlyOffice integrieren hinzugefügt |
| 04.02.2024 | Kapitel 2 um Dockerfile für bz2 erweitert |
| 10.03.2024 | Kapitel 7 – Nextcloud updaten hinzugefügt |
| 12.03.2024 | Kapitel 6.2, 6.3 hinzugefügt. Trusted Proxy in Docker Compose Datei angepasst |
| 06.05.2024 | Kapitel 2.2 angepasst um “latest”, Kapitel 2.1 “DAV” Traefik Labels entfernt. Danke an @burgsth |
| 20.05.2024 | Kapitel 6.4 hinzugefügt |
| 19.09.2024 | Kapitel 6.6 hinzugefügt |
| 15.11.2024 | Link Traefik v3 hinzugefügt, Kapitel 6.5 und 6.6 hinzufügt |
| 15.09.2025 | Docker Image statt Dockerfile als Standard, Kapitel 11 hinzugefügt. Danke an @buggy5151 |
| 01.01.2026 | Kapitel 6.7, 6.8 hinzugefügt |
| 01.04.2026 | Kapitel 2.3 (AppSec) hinzugefügt |
| 16.09.2026 | Komplett überarbeitet: Passwörter in .env; Nextcloud auf Hauptversion 34 und MariaDB 11.4 festgelegt; TRUSTED_PROXIES korrigiert; .well-known-Weiterleitung, Upload-Limits per Umgebungsvariablen und Cron-Container ergänzt; Einstellungen per occ statt config.php; neue Kapitel Update-Regeln, AppAPI mit HaRP, Umstellung bestehender Installationen und Fehlerbehebung. Danke an @bernds, @kru, @snxrcs und alle Kommentatoren. |
Ihr habt Nextcloud bereits nach einer älteren Version dieser Anleitung installiert? Dann springt direkt zu Kapitel 14 – Bestehende Installation umstellen.
0. Grundvoraussetzung
- Docker & Docker Compose v2 (Debian / Ubuntu)
- Traefik ab v3.6 mit CrowdSec installieren und konfigurieren
Als Grundlage meiner Anleitung dient die offizielle Nextcloud Anleitung für Docker.
1. Ordner anlegen
Zuerst legen wir uns passende Ordner-Strukturen an.
mkdir -p /opt/containers/nextcloud/{database,app,daten}
2. Docker Grundlagen
2.1 Proxy Netzwerk IP Adressbereich ermitteln
Damit Nextcloud später weiß, welchen Proxys es vertrauen darf, ermitteln wir nun den korrekten IP Adressbereich unseres Netzwerks “proxy”. Dazu gebt ihr folgendes ein:
docker network inspect proxy -f '{{range .IPAM.Config}}{{.Subnet}}{{end}}'Code-Sprache: JavaScript (javascript)
Bei mir sieht die Ausgabe so aus:
docker network inspect proxy -f '{{range .IPAM.Config}}{{.Subnet}}{{end}}'
172.31.128.0/18Code-Sprache: JavaScript (javascript)
Merkt euch diesen IP Adressbereich für die spätere Konfiguration.
2.2 env Dateien anlegen
Damit wir keine Kennwörter in unserer Docker Compose Datei haben, lagern wir diese nun in eine .env Datei aus. Dazu legt ihr folgende Datei an:
nano /opt/containers/nextcloud/.env
Inhalt:
# Eure Nextcloud-Domain (ohne https://)
NEXTCLOUD_DOMAIN=nextcloud.euredomain.de
# Subnetz des Docker-Netzwerks "proxy" (siehe Kapitel 2.1)
PROXY_SUBNET=172.31.128.0/18
# Passwörter (nur A-Z, a-z, 0-9)
MYSQL_ROOT_PASSWORD=HIER_PASSWORT_1
MYSQL_PASSWORD=HIER_PASSWORT_2
REDIS_PASSWORD=HIER_PASSWORT_3Code-Sprache: PHP (php)
Eure Nextcloud Domain passt ihr nach euren Wünschen an. Die Kennwörter kennt ihr selbst festlegen oder euch mit folgendem Befehl sichere Kennwörter generieren lassen:
for i in 1 2 3; do dd if=/dev/urandom bs=1024 count=1 2>/dev/null | tr -dc 'A-Za-z0-9' | cut -c1-32; doneCode-Sprache: JavaScript (javascript)
Anschließend ändern wir noch die Zugriffsrechte auf die Datei:
chmod 600 /opt/containers/nextcloud/.env
2.3 Docker Compose anlegen
Nun legen wir die eigentliche Docker Datei an. Hierfür habe ich mir die offizielle Nextcloud Compose genommen und diese abgeändert für Traefik. Bei der öffiziellen Seite könnt ihr auch immer die aktuelle Version ermitteln. Dies solltet ihr tun, da wir hier das Image auf Version 34 festsetzen.
nano /opt/containers/nextcloud/docker-compose.yml
Inhalt
services:
nextcloud-db:
image: mariadb:11.4
container_name: nextcloud-db
restart: unless-stopped
command: --transaction-isolation=READ-COMMITTED
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_INITDB_SKIP_TZINFO: "1"
MARIADB_AUTO_UPGRADE: "1"
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- ./database:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
networks:
- default
nextcloud-redis:
image: redis:7-alpine
container_name: nextcloud-redis
restart: unless-stopped
command: redis-server --requirepass ${REDIS_PASSWORD}
networks:
- default
nextcloud-app:
image: nextcloud:34
container_name: nextcloud-app
restart: unless-stopped
depends_on:
nextcloud-db:
condition: service_healthy
nextcloud-redis:
condition: service_started
environment:
# Datenbank und Redis
MYSQL_HOST: nextcloud-db
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
REDIS_HOST: nextcloud-redis
REDIS_HOST_PASSWORD: ${REDIS_PASSWORD}
# Reverse Proxy (Traefik)
TRUSTED_PROXIES: ${PROXY_SUBNET}
APACHE_DISABLE_REWRITE_IP: "1"
OVERWRITEPROTOCOL: https
OVERWRITEHOST: ${NEXTCLOUD_DOMAIN}
OVERWRITECLIURL: https://${NEXTCLOUD_DOMAIN}
# PHP und Apache
PHP_MEMORY_LIMIT: 1024M
PHP_UPLOAD_LIMIT: 16G
PHP_OPCACHE_MEMORY_CONSUMPTION: "256"
APACHE_BODY_LIMIT: "0"
volumes:
- ./app:/var/www/html
- ./daten:/var/www/html/data
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.nextcloud.rule=Host(`${NEXTCLOUD_DOMAIN}`)"
- "traefik.http.routers.nextcloud.entrypoints=websecure"
- "traefik.http.routers.nextcloud.tls.certresolver=http_resolver"
- "traefik.http.routers.nextcloud.middlewares=nextcloud-dav,default@file"
- "traefik.http.middlewares.nextcloud-dav.redirectregex.regex=^https://(.*)/.well-known/(?:card|cal)dav"
- "traefik.http.middlewares.nextcloud-dav.redirectregex.replacement=https://$${1}/remote.php/dav"
- "traefik.http.middlewares.nextcloud-dav.redirectregex.permanent=true"
- "traefik.http.services.nextcloud.loadbalancer.server.port=80"
networks:
- proxy
- default
nextcloud-cron:
image: nextcloud:34
container_name: nextcloud-cron
restart: unless-stopped
entrypoint: /cron.sh
depends_on:
- nextcloud-app
environment:
PHP_MEMORY_LIMIT: 1024M
volumes:
- ./app:/var/www/html
- ./daten:/var/www/html/data
networks:
- default
networks:
proxy:
external: trueCode-Sprache: PHP (php)
Hier müsst ihr nichts mehr anpassen, da ihr bereits alle Anpassungen in der .env Datei gemacht hat.
Was hat sich zu früher geändert?
- Wir verwenden jetzt eine feste Version von Nextcloud statt “latest”, da so bei einem Update sichergestellt ist, dass ihr innerhalb der Hauptversion bleibt. Ein Update von 30 auf 34 ist nämlich so nicht möglich und dies wird durch diesen Schritt sichergestllt.
- Wir haben überall Healthchecks, damit Nextcloud erst startet, wenn die Datenbank verfügbar ist
- Das PHP Uploadlimit wurde auf 16 GB erhöht und bei Apache komplett aufgehoben.
- Ein eigener Container für die Nextcloud Hintergrundjobs
2.4 Dockerfile erstellen (optional)
Wenn ihr das Nextcloud Image erweitern wollt, dann müsst ihr diese Schritte noch tun. Grundsätzlich ist das aber nicht notwendig.
Zuerst passt ihr folgendes an:
vorher:
nextcloud-app:
#build: .
image: nextcloud:34
nachher:
nextcloud-app:
build: .
#image: nextcloud:latestCode-Sprache: CSS (css)
Nun erstellen wir uns ein Dockerfile. Dies hat den Grund, dass wir so die Erweiterung bz2 zusätzlich installieren können. Dazu gebt ihr folgendes ein:
nano /opt/containers/nextcloud/Dockerfile
Inhalt:
FROM nextcloud:34
RUN apt-get update && apt-get install -y libbz2-dev && rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-install bz2Code-Sprache: JavaScript (javascript)
Nun lassen wir uns das Image bauen. Dazu gebt ihr folgendes ein:
cd /opt/containers/nextcloud
docker compose build --no-cache
3. AppSec Whitelist (Optional)
Falls ihr CrowdSec AppSec aktiviert habt, müsst ihr noch eine Whitelist erstellen, damit sich Nextcloud später überhaupt korrekt starten lässt. Es kann sein, dass zudem noch weitere Freigaben für den korrekten Betrieb benötigt werden. Zuerst legen wir uns eine Whitelist an:
cat << 'EOF' > /opt/containers/traefik-crowdsec-stack/data/crowdsec/config/appsec-rules/nextcloud-whitelist.yaml
name: custom/nextcloud-whitelist
seclang_rules:
# Whitelist für Nextcloud Firstrunwizard (DELETE)
- "SecRule REQUEST_URI \"@beginsWith /apps/firstrunwizard/\" \"id:13001,phase:1,pass,nolog,noauditlog,ctl:ruleRemoveById=911100,msg:'Whitelist Nextcloud firstrunwizard Methods'\""
- "SecRule REQUEST_URI \"@beginsWith /apps/firstrunwizard/\" \"id:13002,phase:2,pass,nolog,noauditlog,ctl:ruleRemoveById=949110,ctl:ruleRemoveById=980170,msg:'Whitelist Nextcloud firstrunwizard Anomaly'\""
# Whitelist für Nextcloud Text App (PUT) - Session-ID dynamisch abgefangen
- "SecRule REQUEST_URI \"@beginsWith /apps/text/session/\" \"id:13003,phase:1,pass,nolog,noauditlog,ctl:ruleRemoveById=911100,msg:'Whitelist Nextcloud text session Methods'\""
- "SecRule REQUEST_URI \"@beginsWith /apps/text/session/\" \"id:13004,phase:2,pass,nolog,noauditlog,ctl:ruleRemoveById=949110,ctl:ruleRemoveById=980170,msg:'Whitelist Nextcloud text session Anomaly'\""
# Whitelist für Nextcloud Heartbeat / User Status (PUT)
- "SecRule REQUEST_URI \"@beginsWith /ocs/v2.php/apps/user_status/api/v1/heartbeat\" \"id:13005,phase:1,pass,nolog,noauditlog,ctl:ruleRemoveById=911100,msg:'Whitelist Nextcloud heartbeat Methods'\""
- "SecRule REQUEST_URI \"@beginsWith /ocs/v2.php/apps/user_status/api/v1/heartbeat\" \"id:13006,phase:2,pass,nolog,noauditlog,ctl:ruleRemoveById=949110,ctl:ruleRemoveById=980170,msg:'Whitelist Nextcloud heartbeat Anomaly'\""
EOFCode-Sprache: PHP (php)
Nun müssen wir noch eine Anpasung vornehmen, damit die Whitelist auch genutzt wird:
nano /opt/containers/traefik-crowdsec-stack/data/crowdsec/config/appsec-configs/mrks-config.yaml
Dort fügt ihr einfach “- custom/nextcloud-whitelist” hinzu:
name: custom/mrks-config
default_remediation: ban
inband_rules:
- custom/nextcloud-whitelist
- crowdsecurity/base-config
- crowdsecurity/vpatch-*
- crowdsecurity/generic-*
- crowdsecurity/crs
- crowdsecurity/experimental-*
outofband_rules:
- crowdsecurity/appsec-generic-test
Nun starten wir Traefik neu, damit die Änderungen übernommen werden:
cd /opt/containers/traefik-crowdsec-stack
docker compose up -d --force-recreate
4. Nextcloud Server starten
Den Server startet ihr wie gewohnt mit folgendem Befehl:
docker compose -f /opt/containers/nextcloud/docker-compose.yml up -d
5. Nextcloud einrichten
Nextcloud sollte die Datenbank Verbindung nun automatisch erkennen und euch direkt zur Erstellung des Admin Kontos führen:

Jetzt solltet ihr folgendes sehen. Gebt hier nun folgendes ein:
Administrator-Konto anlegen
- Benutzername: Wie euer Nextcloud Admin heißen soll
- Passwort: Wählt ein Passwort
Wenn ihr anschließend auf “Installieren” klickt, dauert es ca. 30 Sekunden, bis die Webseite neu lädt und ihr folgendes angezeigt bekommt. Hier könnt ihr auf “Überspringen” klicken oder alle “Empfohlen Apps” direkt mit installieren lassen.

Anschließend werdet ihr von diesem Startbildschirm begrüßt.

6. occ komfortabel nutzen (optional)
occ ist ein Kommandozeilentool von Nextcloud. Es ermöglicht euch verschiedene Parameter anzupassen. Da Nextcloud in einem Docker Container läuft, ist der Befehl immer etwas länger, zum Beispiel so:
docker exec -u www-data nextcloud-app php occ status
Damit der Befehl “kürzer” ist, legen wir uns ein kleines Skript an (Danke @bernds) für den Tipp:
nano /usr/local/bin/occ
Inhalt:
#!/bin/bash
# occ-Befehle im Nextcloud-Container als www-data ausführen
if [ -t 0 ]; then
TTY="-it"
else
TTY="-i"
fi
exec docker exec $TTY -u www-data nextcloud-app php occ "$@"Code-Sprache: PHP (php)
Anschließend machen wir die Datei noch ausführbar:
chmod +x /usr/local/bin/occ
Jetzt reicht es, wenn ihr nur noch occ eingebt um Befehle auszuführen:
occ status
7. Optimierungen
Wenn ihr oben rechts auf eueren “Buchstaben”. Dann wählt ihr “Einstellungen” -> “Übersicht” aus. Nun solltet ihr feststellen, dass Nextcloud noch “Optimierungsbedarf” sieht. Dies wollen wir nun tun.

Wir werden hier alle occ Befehle entsprechend mittels des Skripts in Kapitel 6 ausführen. Wenn ihr dies nicht wollt, so müsst ihr folgendes vor den Befehl schreiben:
docker exec -u www-data nextcloud-app php occ <Befehl>
statt
occ <Befehl>Code-Sprache: HTML, XML (xml)
7.1 Alle Warnungen in der Konsole anzeigen lassen
Damit ihr einen schnelleren Überblick über die Warnungen bekommt, könnt ihr euch diesen auch direkt in der Konsole anzeigen lassen:
occ setupcheck
7.2 Standardtelefonregion festlegen
Damit die Telefonnummern korrekt erkannt werden, gebt ihr für Deutschland folgendes ein:
occ config:system:set default_phone_region --value="DE"Code-Sprache: JavaScript (javascript)
Für Österreich “AT” und für die Schweiz “CH”.
7.3 Der Server hat keine konfigurierte Startzeit für das Wartungsfenster
Nextcloud führt aufwendige Hintergrundaufgaben bevorzugt in einem vierstündigen Wartungsfenster aus. Ihr legt nur fest, wann es beginnt. Wichtig ist, dass der Wert in UTC angegeben wird. “1” bedeutet also, dass es 2:00 Uhr (Winterzeit) oder 3:00 Uhr (Sommerzeit) sind.
occ config:system:set maintenance_window_start --type=integer --value=1Code-Sprache: JavaScript (javascript)
7.4 ihr werdet regelmäßig auf eurem Server durch Crowdsec gebannt
In diesem Fall solltet ihr diese Anleitung ausführen und eine Nextcloud Whitelist hinzufügen.
7.5 fehlende optionale Indizes erkannt
Ich bekomme noch folgende Fehlermeldung, dass “Einige fehlende optionale Indizes wurden erkannt. Gelegentlich werden neue Indizes hinzugefügt (von Nextcloud oder installierten Anwendungen), um die Datenbankleistung zu verbessern” fehlen. Dies könnt ihr so beheben:
occ db:add-missing-indicesCode-Sprache: CSS (css)
7.6 One or more mimetype migrations are available
Dies behebt ihr mit folgendem Befehl:
occ maintenance:repair --include-expensiveCode-Sprache: CSS (css)
7.7 Falsches Zeilenformat in Ihrer Datenbank gefunden
Die genaue Meldung
Falsches Zeilenformat in Ihrer Datenbank gefunden. ROW_FORMAT=Dynamic bietet die beste Datenbankleistung für Nextcloud. Bitte aktualisieren Sie das Zeilenformat in der folgenden Liste..Code-Sprache: PHP (php)
Um das Problem zu lösen erstellen wir uns ein Upgrade Skript:
nano /opt/containers/nextcloud/upgrade-db.sh
Inhalt:
#!/bin/bash
set -euo pipefail
DB_CONTAINER="nextcloud-db"
DB_NAME="nextcloud"
# ALTER-Befehle für alle Tabellen erzeugen, die noch nicht DYNAMIC sind
SQL=$(docker exec -i "$DB_CONTAINER" sh -c 'mariadb -u root -p"$MYSQL_ROOT_PASSWORD" -sN' <<EOF
SELECT CONCAT('ALTER TABLE \`', table_name, '\` ROW_FORMAT=DYNAMIC;')
FROM information_schema.tables
WHERE table_schema = '${DB_NAME}' AND engine = 'InnoDB' AND row_format <> 'Dynamic';
EOF
)
if [ -z "$SQL" ]; then
echo "Alle Tabellen haben bereits ROW_FORMAT=DYNAMIC."
exit 0
fi
echo "Folgende Befehle werden ausgeführt:"
echo "$SQL"
# Befehle ausführen
echo "$SQL" | docker exec -i "$DB_CONTAINER" sh -c "mariadb -u root -p\"\$MYSQL_ROOT_PASSWORD\" $DB_NAME"
echo "Fertig."Code-Sprache: PHP (php)
Das Skript nutzt das Root-Passwort, das bereits als Umgebungsvariable im Datenbank-Container hinterlegt ist. Ihr müsst also kein Passwort eintragen und es taucht auch nicht in der Prozessliste des Hosts auf. Wenn ihr den Nextcloud oder DB Containername geändert habt, so müsst ihr dies noch anpassen.
Anschließend machen wir das Skript noch ausführbar:
chmod +x /opt/containers/nextcloud/upgrade-db.sh
Jetzt fahren wir die Nextcloud Container herunter und starten nur die Datenbank.
cd /opt/containers/nextcloud
docker compose down
docker compose up -d nextcloud-db
Wichtig: Macht vor dem Ausführen des Skripts ein Backup der Datenbank
Nun starten wir unser Skript:
/opt/containers/nextcloud/upgrade-db.sh
Nachdem das Skript fertig ist, können wir Nextcloud starten:
cd /opt/containers/nextcloud
docker compose up -d
7.8 Cron Job benötigt mehr RAM
Falls eine Meldung folgender Art bei euch steht:
Cron job used more than 300 MB of ram after executing job
dann könnt ihr einfach den RAM erhöhen. Dazu öffnet ihr die Docker Compose Datei:
nano /opt/containers/nextcloud/docker-compose.yml
Wir haben das PHP_MEMORY_LIMIT bereits bei der aktuellen Konfiguration erhöht: PHP_MEMORY_LIMIT: 1024M
Sollte dies bei euch noch nicht der Fall sein, so fügt / ändert diesen Wert noch in eurer Docker Compose. Ihr müsst den Wert bei den nextcloud Container sowie nextcloud-cron Container ändern.
Anschließend muss der gesamte Container neu gestartet werden.
cd /opt/containers/nextcloud
docker compose up -d --force-recreate
8. Große Dateien hochladen
8.1 Parameter in der Docker Compose anpassen
Wir haben die Docker Compose bereits so gändert, dass Dateien bis 16 GB hochgeladen werden können. Dies könnt ihr folgendermaßen überprüfen:
docker exec nextcloud-app php -i | grep -E "upload_max_filesize|post_max_size|memory_limit"Code-Sprache: JavaScript (javascript)
Die Ausgabe sollte folgendes sein:
docker exec nextcloud-app php -i | grep -E "upload_max_filesize|post_max_size|memory_limit"
max_memory_limit => -1 => -1
memory_limit => 1024M => 1024M
post_max_size => 16G => 16G
upload_max_filesize => 16G => 16GCode-Sprache: PHP (php)
Sollte dies nicht der Fall sein, so kopiert / passt folgende Werte in der Docker Compose an:
PHP_MEMORY_LIMIT: 1024M
PHP_UPLOAD_LIMIT: 16G
PHP_OPCACHE_MEMORY_CONSUMPTION: "256"
APACHE_BODY_LIMIT: "0"Code-Sprache: JavaScript (javascript)
8.2 Traefik Timeout verhindern
Traefik bricht Anfragen ab, wenn die Übertragung zu lange dauert (Danke an @kru für den Hinweis). Standardmäßig ist der Wert auf 60 Sekunden eingestellt. Dies kann bei langsamen / großen Uploads zu Fehlern führen wie:
BadRequest
Erwartete Dateigröße von 10485760 Bytes, aber 8306688 Bytes gelesen …
Um diesen Wert zu ändern, öffnet folgende Datei:
nano /opt/containers/traefik-crowdsec-stack/data/traefik/traefik.yml
Fügt dort folgendes an der korrekten Stelle hinzu:
transport:
respondingTimeouts:
readTimeout: 30m
so sieht der gesamte Block bei mir aus:
entryPoints:
ping:
address: ':88'
web:
address: ':80'
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ':443'
http3: {}
http:
middlewares:
- crowdsec@file
- default@file
transport:
respondingTimeouts:
readTimeout: 30m
Code-Sprache: JavaScript (javascript)
Anschließend startet ihr Traefik neu:
docker compose -f /opt/containers/traefik-crowdsec-stack/docker-compose.yml restart traefik
9. Nextcloud mittels CrowdSec absichern
Nun könnt ihr Nextcloud innerhalb weniger Minuten noch zusätzlich mittels CrowdSec absichern. Eine Anleitung dazu findet ihr hier.
10. Collabora Office integrieren
Ich habe hier eine Anleitung geschrieben, wie ihr in wenigen Minuten Collabora Office mittels Docker installiert und in Nextcloud integrieren könnt. Collabora Office ermöglicht euch ein “komplettes online Office” innerhalb von Nextcloud.

11. OnlyOffice integireren
Neben Collabora Office könnt ihr auch innerhalb weniger Minuten OnlyOffice mittels Docker installieren und integrieren. Es hat einen ähnlichen Funktionsumfang wie Collabora Office.

12. AppAPI einrichten (optional)
AppAPI ermöglicht externe Apps (ExApps), die in eigenen Docker-Containern laufen. Dazu gehören z. B. viele KI-Funktionen. Solche Apps braucht nicht jeder. Wenn ihr keine ExApps nutzen wollt, überspringt dieses Kapitel.
Für die Verbindung zwischen Nextcloud und den ExApps nutzt Nextcloud seit Version 32 HaRP. Der frühere Docker Socket Proxy (DSP) ist veraltet und soll mit Nextcloud 35 entfernt werden.
12.1 AppAPI installieren
Zuerst erzeugt ihr euch ein sicheres Kennwort:
dd if=/dev/urandom bs=1024 count=1 2>/dev/null | tr -dc 'A-Za-z0-9' | cut -c1-32Code-Sprache: JavaScript (javascript)
Fügt dann folgende Zeile in eure .env Datei ein zusammen mit eurem Kennwort:
nano /opt/containers/nextcloud/.env
Inhalt:
HARP_SHARED_KEY=HIER_PASSWORT_einfügen
Nun müssen wir den Container noch der Docker Compose hinzufügen:
nano /opt/containers/nextcloud/docker-compose.yml
Fügt dort folgendes hinzu:
nextcloud-harp:
image: ghcr.io/nextcloud/nextcloud-appapi-harp:release
container_name: nextcloud-harp
hostname: nextcloud-harp
restart: unless-stopped
environment:
HP_SHARED_KEY: ${HARP_SHARED_KEY}
NC_INSTANCE_URL: https://${NEXTCLOUD_DOMAIN}
HP_TRUSTED_PROXY_IPS: ${PROXY_SUBNET}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./harp-certs:/certs
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.nextcloud-exapps.rule=Host(`${NEXTCLOUD_DOMAIN}`) && PathPrefix(`/exapps/`)"
- "traefik.http.routers.nextcloud-exapps.entrypoints=websecure"
- "traefik.http.routers.nextcloud-exapps.tls.certresolver=http_resolver"
- "traefik.http.routers.nextcloud-exapps.middlewares=default@file"
- "traefik.http.services.nextcloud-exapps.loadbalancer.server.port=8780"
networks:
- proxy
- defaultCode-Sprache: PHP (php)
Anschließend starte ihr Nextcloud neu:
cd /opt/containers/nextcloud
docker compose up -d
12.2 Daemon registrieren
Dazu geht ihr in die Administrationseinstellungen:

Wählt nun “AppAPI” aus:

Klickt nun auf “Daemon registrieren”:

Gebt nun folgendes ein:

Parameter zum Kopieren
| Feld | Wert |
|---|---|
| Daemon Konfigurationsvorlage | HaRP Proxy (Docker) |
| HaRP-Host | nextcloud-harp:8780 |
| Geteilter HaRP-Schlüssel | euer HARP_SHARED_KEY aus der .env |
| Nextcloud-URL | https://nextcloud.euredomain.de |
| Als Standard-Daemon festlegen | aktiviert |
| HaRP aktivieren | aktiviert |
| FRP-Serveradresse | nextcloud-harp:8782 |
| Docker-Socket-Proxy-Port | 24000 (Standardwert, nicht ändern) |
| Docker-Netzwerk | nextcloud_default |
| Compute-Gerät | CPU (bzw. eure GPU, falls vorhanden) |
Das Netzwerk könnt ihr mit folgendem Befehl ermitteln:
docker network ls | grep nextcloud
So sieht meine Ausgabe aus:
docker network ls | grep nextcloud
dddaabdc69eb nextcloud_default bridge local
Anschließend könnt ihr die Verbindung überprüfen. Jetzt solltet ihr folgende Meldung erhalten:

Wenn das funktioniert hat, klickt auf die “3 Punkte” und wählt “Bereitstellung testen” aus:

Wenn der Test erfolgreich war, solltet ihr folgendes sehen. Bei mir hat dies mehrere Minuten gedauert.

13. Nextcloud updaten
13.1 Die wichtigste Regel
Nextcloud kann keine Hauptversionen überspringen. Von 33 geht es nur auf 34, von 34 nur auf 35 und so weiter. Wer z. B. von 32 direkt auf 34 springt, landet in einer Neustart-Schleife.
Welche Version bei euch läuft, seht ihr mit:
occ status
Das Update über die Weboberfläche („Updater“) ist bei Docker nicht vorgesehen. Updates erfolgen immer über ein neues Image.
13.2 Kleine Updates (innerhalb einer Hauptversion)
Solange in der docker-compose.yml nextcloud:34 steht, bekommt ihr mit folgenden Befehlen die neueste 34er-Version:
cd /opt/containers/nextcloud
docker compose pull
docker compose up -d
Beim Start erkennt der Container die neue Version und führt das Upgrade automatisch aus. Den Fortschritt seht ihr mit:
docker compose logs -f nextcloud-app
13.3 Update auf die nächste Hauptversion
Erstellt ein Backup. Prüft, ob alle eure Apps die neue Version schon unterstützen. Das seht ihr unter „Verwaltungseinstellungen“ → „Übersicht“. Ändert die Versionsnummer in der docker-compose.yml bei beiden Containern um genau eins:
nano /opt/containers/nextcloud/docker-compose.yml
Anpassungen:
vorher:
nextcloud-app:
image: nextcloud:34
nextcloud-cron:
image: nextcloud:34
nachher:
nextcloud-app:
image: nextcloud:35
nextcloud-cron:
image: nextcloud:35Code-Sprache: CSS (css)
Image laden und Container neu starten:
cd /opt/containers/nextcloud
docker compose pull
docker compose up -d
docker compose logs -f nextcloud-app
Nach dem Upgrade die üblichen Nacharbeiten erledigen:
occ app:update --all
occ db:add-missing-indices
occ maintenance:repair --include-expensive
occ setupcheckCode-Sprache: CSS (css)
13.4 Update mit eigenem Dockerfile
Wenn ihr das Image in Kapitel 2.4 erweitert habt, passt ihr die Versionsnummer in der ersten Zeile des Dockerfile an (z. B. FROM nextcloud:35) und baut das Image neu:
cd /opt/containers/nextcloud
docker compose build --pull
docker compose up -d
Für kleine Updates innerhalb einer Hauptversion reichen die letzten beiden Befehle.
13.5 MariaDB aktualisieren
Die Datenbank aktualisiert ihr unabhängig von Nextcloud. Erstellt vorher ein Backup, ändert die Version (z. B. mariadb:11.4 → neuere LTS-Version, sofern Nextcloud diese unterstützt) und startet neu. Dank MARIADB_AUTO_UPGRADE passt MariaDB die Datenbankdateien beim Start automatisch an:
cd /opt/containers/nextcloud
docker compose pull nextcloud-db
docker compose up -d
14. Bestehende Installation umstellen
Ihr habt Nextcloud nach einer älteren Version dieser Anleitung installiert? So stellt ihr auf den neuen Aufbau um, ohne Daten zu verlieren. Die Ordnerstruktur (database, app, daten) bleibt gleich.
14.1 Backup erstellen
Erstellt ein vollständiges Backup, indem ihr die Container beendet und das gesamte Verzeichnis kopiert bzw. die Datenbank und Konfiguration.
14.2 Installierte Version ermitteln
Gebt folgenden Befehl ein
docker exec -u www-data nextcloud-app php occ status
Merkt euch die Hauptversion. Bei mir zum Beispiel folgendes:
docker exec -u www-data nextcloud-app php occ status
- installed: true
- version: 34.0.4.1
- versionstring: 34.0.4Code-Sprache: CSS (css)
Die Hauptversion ist: 34.0.4
14.3 .env anlegen
Legt die .env wie in Kapitel 2.2 an, erzeugt aber keine neuen Passwörter. Übernehmt stattdessen die Passwörter aus eurer alten docker-compose.yml. Die Datenbank-Passwörter werden nur beim allerersten Start gesetzt. Mit neuen Passwörtern könnte sich Nextcloud nicht mehr mit der Datenbank verbinden.
Enthält eines eurer alten Passwörter ein $, setzt ihr den Wert in der .env in einfache Anführungszeichen, z. B. MYSQL_PASSWORD='abc$def'.
14.4 Neue docker-compose.yml anlegen
Übernehmt die Datei aus Kapitel 2.3 mit zwei Anpassungen:
- Nextcloud-Version: Tragt bei
nextcloud-appundnextcloud-croneure aktuelle Hauptversion aus Schritt 14.2 ein (z. B.nextcloud:34). Niemals eine niedrigere Version als die installierte, denn ein Downgrade ist nicht möglich. Auf neuere Versionen aktualisiert ihr anschließend wie in Kapitel 13. - MariaDB-Version: Behaltet zunächst eure bisherige Version (z. B.
mariadb:10.11). Die Datenbank aktualisiert ihr später separat nach Kapitel 13.5.
Falls ihr AppAPI mit nextcloud-appapi-dsp nutzt, lasst diesen Container vorerst in der Datei und stellt danach wie in Kapitel 12 um.
14.5 Host-Crontab entfernen
Der alte Cron-Eintrag auf dem Host wird durch den nextcloud-cron-Container ersetzt:
crontab -e
Löscht dort die Zeile:
*/5 * * * * docker exec -u www-data nextcloud-app php cron.php
14.6 Stack neu starten
Gebt folgendes ein:
cd /opt/containers/nextcloud
docker compose up -d --remove-orphans
docker compose logs -f nextcloud-app
14.7 Nacharbeiten
Richtet den occ-Befehl aus Kapitel 6 ein und führt dann aus:
occ background:cron
occ setupcheckCode-Sprache: CSS (css)
Die Einträge php_value upload_max_filesize und php_value post_max_size in der .user.ini braucht ihr nicht mehr, die Werte kommen jetzt aus der docker-compose.yml. Die Einträge default_phone_region und maintenance_window_start in eurer config.php bleiben einfach bestehen.

Danke, das ist wirklich eine übersichtliche Anleitung. Ich komme jedoch beim Starten des Containers nicht weiter, da die gleiche Fehlermeldung, wie bei Bert im Log auftritt:
/usr/local/bin/docker-entrypoint.sh: line 340: exec: –: not found
Hat jemand eine Lösung?
Hallo,
Vielen Dank. Es hat alles geklappt. Ich habe noch eine Frage. Ich habe zu wenig Speicher vergeben….kann man das erweitern für Nextcloud Daten?
Hallo, Herzlichen dank für die Tolle Anleitung.
Bei der Installation muss die mariadb berücksichtigt werden, da die neuesten versionen im moment nicht mehr kompatibel ist. Ich habe “mariadb:10.3.22” genommen.
Ein problem habe ich, und weiss aber nicht an was es liegt.
. Kennst du das?
Ich kann mich mit der Nexcloud app und software für den PC mit dem Server nicht verbinden. Er hängt immer beim Beim Kontrollzugriff übern Browser siehe bild:
Sonnst hat wirklich alles super geklappt. Herzlichen Dank 🙂
Hallo
Habe ein Problem
Error while trying to create admin user: Failed to connect to the database: An exception occurred in driver: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known
Hallo Christian,
vielen Dank für deine Anleitungen. Bei Mailcow und Portainer haben die auch wunderbar funktioniert. Nur Nextcloud will jetzt nicht 🙁 Ich erhalte immer einen Error 404 wenn ich versuche die Seite für den Setup zu öffnen. Irgendwelche Ideen?
Gruß Basti
Hallo Christian,
erstmal danke für deine super Anleitungen.
Ich bin jedoch über einige Syntax Probleme gestolpert. Es fehlen teilweise doppelte Striche.
So z.B. “docker exec – user www-data nextcloud_nextcloud-app_1 php occ db:convert-filecache-bigint”
Korrekterweise müsste es jedoch “docker exec –-user www-data …” heißen.
Das gleiche Problem hatte ich auch in der docker-compose im command Teil von MariaDB.
Gruß
Thomas
Hallo Christian,
hast Du evtl. eine Idee wie man mit diesem Setup unter Nextcloud 19 collabora online mit dem eingebauten CODE-Server ans laufen bekommt?
Viele Grüße
Enrico
Hi Cristian,
1000 Dank für die super Anleitung!
Die erste die ich gefunden habe die auf Anhieb funktioniert und auch noch eine A+ Bewertung im scan schafft.
Grüße
Enrico
Hey Christian,
vielen Dank für die Beschreibung. Ich bin noch etwas am experimentieren mit NC, Docker und Co.. Würde daher gerne wissen, warum du dich für den Weg mit traefik entschieden hast und nicht für einen Weg mit letsencrypt / nginx-proxy, wie z. B. hier:
https://rtfm.co.ua/en/nextcloud-running-in-docker-compose-on-debian-with-lets-encrypt-ssl/
Dank & Gruß!
Pascal
Hallo,
danke für dieses tolle Tutorial. Ich habe Nextcloud damit endlich zum laufen gebracht.
Ich hätte noch eine Frage: Kann man irgendwie noch onlyoffice daneben installieren?
Also das Nextcloud auf ‘meine.ip.com/nextcloud/’ und onlyoffice auf ‘meine.ip.com/office/’ ist? Unterschiedliche Subdomains funktionieren in meinen Anwendungsfall leider nicht. Mit ‘rule=Host(`meine.ip.com`) && Path(`/nextcloud/`)’ hatte ich kein Glück.