Zum Inhalt springen
Serverküche
Suche

Die Suche wird geladen … (nur in der veröffentlichten Seite verfügbar).

Anwendungen Schwierigkeit: Fortgeschritten

Nextcloud selbst hosten: deine eigene Cloud hinter Traefik

Nextcloud mit Docker hinter Traefik aufsetzen: eigene Cloud für Dateien, Kalender und Kontakte – mit MariaDB, Redis und automatischem HTTPS.

· 10 Min. Lesezeit ·Dauer: ca. 60 Minuten
Inhaltsverzeichnis

Deine Dateien, dein Kalender, deine Kontakte – aber auf deinem Server statt bei einem Cloud-Konzern. Nextcloud ist das Flaggschiff des Selfhostings: eine vollwertige Cloud, die du selbst betreibst. In diesem Rezept setzen wir sie sauber hinter Traefik auf, mit eigener Datenbank, Caching und automatischem HTTPS.

Was bauen wir?

Am Ende läuft Nextcloud 34 hinter deinem Traefik-Proxy, erreichbar unter https://cloud.DEINE_DOMAIN mit gültigem Let’s-Encrypt-Zertifikat. Nextcloud ist deine private Cloud: Dateien synchronisieren (wie bei Dropbox), Kalender und Kontakte über alle Geräte, Fotos, Notizen, Office-Dokumente. Du verbindest den offiziellen Desktop-Sync-Client und die Handy-Apps mit deinem Server – die Daten liegen dabei ausschließlich bei dir.

Wir setzen bewusst auf das klassische nextcloud-Image (nicht auf „Nextcloud All-in-One") plus MariaDB als Datenbank und Redis fürs Caching und File-Locking. Diese Kombination ist stabil, gut dokumentiert und passt exakt in das Traefik-Muster aus der Serverküche.

Warum nicht Nextcloud AIO?

Nextcloud bietet auch ein „All-in-One"-Paket (AIO) an. Das bringt aber sein eigenes TLS und eigene Ports mit und will den Reverse-Proxy-Teil selbst übernehmen – das beißt sich mit einem bestehenden Traefik. Für unser Setup ist das klassische Image die richtige, kontrollierbare Wahl.

Voraussetzungen

  • Ein laufender Traefik-Reverse-Proxy mit dem gemeinsamen proxy-Netzwerk und dem Let’s-Encrypt-Resolver le – wie im Tutorial Reverse Proxy mit Traefik aufgebaut.
  • Eine Subdomain cloud.DEINE_DOMAIN, deren DNS-Record (A/AAAA) auf deine Server-IP zeigt – siehe Domain mit Server verbinden.
  • Ein funktionierendes Backup. Eine Cloud ist der Ort, an dem Datenverlust am meisten wehtut – richte zuerst Backups mit Restic ein.

Wie groß muss der Server sein?

Nextcloud ist genügsamer als sein Ruf: Für den privaten Gebrauch oder eine kleine Familie (1–5 Nutzer) reichen 2 vCPU und 4 GB RAM gut aus – der getestete VPS 1000 passt. Der Flaschenhals ist der Arbeitsspeicher: Bei zu wenig RAM fängt der Server an zu swappen und wird zäh. Redis (bauen wir gleich ein) entlastet spürbar. Für Nextcloud Office/Collabora oder viele parallele Nutzer solltest du eher 8 GB einplanen.
🍳 Empfehlung Anzeige

VPS 1000 G12

4 vCore · 8 GB RAM · 256 GB NVMe

ab 10,36 €/Monat

Für eine private Nextcloud mit ein paar Nutzern reicht der VPS 1000 gut aus.

Zu netcup →

Schritt für Schritt

Schritt 1: DNS-Record anlegen

Lege bei deinem DNS-Anbieter einen Eintrag cloud.DEINE_DOMAIN an, der auf deine Server-IP zeigt (A-Record für IPv4, AAAA für IPv6). Prüfe, dass er aufgelöst wird:

Terminal
dig +short cloud.DEINE_DOMAIN

Du solltest deine Server-IP sehen. Erst wenn der Record steht, kann Traefik später das HTTPS-Zertifikat holen.

Schritt 2: Das proxy-Subnetz ermitteln

Nextcloud sitzt hinter Traefik. Damit Nextclouds Brute-Force-Schutz die echte Besucher-IP erkennt (und nicht die interne Traefik-IP sperrt), müssen wir Traefik als „vertrauenswürdigen Proxy" eintragen. Dazu brauchst du das Subnetz deines proxy-Netzwerks:

Terminal
docker network inspect proxy -f '{{(index .IPAM.Config 0).Subnet}}'

Du bekommst etwas wie 172.18.0.0/16. Merke dir diesen Wert – er kommt gleich als TRUSTED_PROXIES in die Konfiguration.

Schritt 3: Die compose.yaml anlegen

Leg einen Ordner an und wechsle hinein:

Terminal
mkdir -p ~/nextcloud && cd ~/nextcloud

Erstelle die compose.yaml. Ersetze cloud.DEINE_DOMAIN, alle Passwörter und das TRUSTED_PROXIES-Subnetz aus Schritt 2:

YAML
services:
  nc-db:
    image: mariadb:11.4
    container_name: nc-db
    command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
    environment:
      MARIADB_ROOT_PASSWORD: EIN_STARKES_ROOT_PASSWORT
      MARIADB_DATABASE: nextcloud
      MARIADB_USER: nextcloud
      MARIADB_PASSWORD: EIN_STARKES_DB_PASSWORT
    volumes:
      - nc_db:/var/lib/mysql
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 6
    networks: [default]
    restart: unless-stopped

  nc-redis:
    image: redis:8-alpine
    container_name: nc-redis
    command: redis-server --requirepass EIN_STARKES_REDIS_PASSWORT
    networks: [default]
    restart: unless-stopped

  nc-app:
    image: nextcloud:34-apache
    container_name: nc-app
    depends_on:
      nc-db:
        condition: service_healthy
      nc-redis:
        condition: service_started
    environment:
      MYSQL_HOST: nc-db
      MYSQL_DATABASE: nextcloud
      MYSQL_USER: nextcloud
      MYSQL_PASSWORD: EIN_STARKES_DB_PASSWORT
      REDIS_HOST: nc-redis
      REDIS_HOST_PASSWORD: EIN_STARKES_REDIS_PASSWORT
      NEXTCLOUD_TRUSTED_DOMAINS: cloud.DEINE_DOMAIN
      OVERWRITEPROTOCOL: https
      OVERWRITECLIURL: https://cloud.DEINE_DOMAIN
      TRUSTED_PROXIES: 172.18.0.0/16
      PHP_MEMORY_LIMIT: 1024M
      PHP_UPLOAD_LIMIT: 10G
    volumes:
      - nc_html:/var/www/html
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nc.rule=Host(`cloud.DEINE_DOMAIN`)"
      - "traefik.http.routers.nc.entrypoints=websecure"
      - "traefik.http.routers.nc.tls.certresolver=le"
      - "traefik.http.routers.nc.middlewares=nc-dav"
      - "traefik.http.services.nc.loadbalancer.server.port=80"
      # .well-known-Redirect für CalDAV/CardDAV (siehe unten)
      - "traefik.http.middlewares.nc-dav.redirectregex.regex=https://(.*)/.well-known/(?:card|cal)dav"
      - "traefik.http.middlewares.nc-dav.redirectregex.replacement=https://cloud.DEINE_DOMAIN/remote.php/dav/"
      - "traefik.http.middlewares.nc-dav.redirectregex.permanent=true"
    networks: [default, proxy]
    restart: unless-stopped

volumes:
  nc_html:
  nc_db:

networks:
  default:
  proxy:
    external: true

Was hier wichtig ist:

  • Drei Container: nc-app (Nextcloud), nc-db (MariaDB), nc-redis. Nur nc-app hängt im proxy-Netz (für Traefik) und im internen default-Netz. Datenbank und Redis bleiben ausschließlich intern – sie haben kein ports: und sind von außen nicht erreichbar.
  • Zwei Named Volumes: nc_html (Programmcode, config.php, Nutzerdaten) und nc_db (die MariaDB-Daten). Das nc_db-Volume ist Pflicht: Ohne den Eintrag landet die Datenbank in einem anonymen Volume, und ein docker compose down gefolgt von up würde sie unwiederbringlich verlieren.
  • healthcheck + depends_on: service_healthy: Nextcloud startet schneller als die Datenbank initialisiert ist. Ohne diesen Healthcheck scheitert die Erstinstallation an einem „Connection refused". So wartet der App-Container, bis MariaDB wirklich bereit ist.
  • NEXTCLOUD_TRUSTED_DOMAINS: ohne die eigene Domain hier begrüßt dich Nextcloud mit „Zugriff über eine nicht vertrauenswürdige Domäne".
  • OVERWRITEPROTOCOL: https sagt Nextcloud, dass es hinter HTTPS läuft – sonst baut es interne Links als http:// und Logins/Redirects brechen.
  • TRUSTED_PROXIES: das Subnetz aus Schritt 2. Damit erkennt Nextcloud die echte Client-IP; sonst sperrt der Brute-Force-Schutz die Traefik-IP.
  • PHP_MEMORY_LIMIT / PHP_UPLOAD_LIMIT: die Defaults (512 MB) sind für große Uploads zu klein. Hier großzügig gesetzt.
  • loadbalancer.server.port=80: das Apache-Image lauscht im Container auf Port 80.
  • Die nc-dav-Middleware löst ein klassisches Nextcloud-Problem – dazu gleich mehr.

CalDAV/CardDAV: der .well-known-Redirect

Nextcloud möchte Kalender-/Kontakt-Clients über /.well-known/caldav und /.well-known/carddav zu /remote.php/dav/ schicken. Hinter einem Reverse Proxy funktioniert Nextclouds eigener Redirect nicht zuverlässig – das führt später zu einer Warnung im Sicherheits-Check und zu Problemen bei der Kalender-Einrichtung. Die nc-dav-Middleware oben erledigt den Redirect direkt in Traefik. Wichtig: Das Muster muss die volle https://…-URL matchen – redirectregex prüft immer die komplette URL, nicht nur den Pfad. Ein reines Pfad-Muster wie ^/.well-known/… greift deshalb nie.

Schritt 4: Starten und den Erst-Setup durchlaufen

Starte den Stack:

Terminal
docker compose up -d

Beim ersten Start initialisiert MariaDB die Datenbank und Nextcloud entpackt sich – das dauert ein bis zwei Minuten. Verfolge es im Log:

Terminal
docker compose logs -f nc-app

Beim ersten Lauf entpackt das Image Nextcloud ins Volume; du siehst Zeilen wie Initializing nextcloud 34.0.1.2 ... und schließlich Initializing finished, gefolgt vom Apache-Start. Erscheint stattdessen wiederholt restarting, wirf einen Blick in den Abschnitt „Wenn es nicht funktioniert". Mit Strg+C verlässt du die Log-Ansicht wieder (der Container läuft weiter).

Ruf dann https://cloud.DEINE_DOMAIN auf. Traefik holt beim ersten Zugriff das Zertifikat (kann ein paar Sekunden dauern). Weil wir Datenbank und Redis schon per Umgebungsvariablen konfiguriert haben, erkennt Nextcloud das automatisch und fragt nur noch nach einem Administrationskonto:

Der Nextcloud-Erst-Setup erkennt die Autoconfig und fragt nur noch nach Name und Passwort des Administrationskontos
Erst-Setup: Datenbank ist vorkonfiguriert, du legst nur das Admin-Konto an

Vergib einen Admin-Namen und ein starkes Passwort und klick auf Installieren. Nextcloud richtet die Instanz ein – danach landest du auf der Anmeldeseite:

Die Nextcloud-Anmeldeseite unter der eigenen HTTPS-Domain
Die Anmeldeseite unter cloud.DEINE_DOMAIN – mit gültigem HTTPS von Traefik

Nach dem Login begrüßt dich das Dashboard, und unter Dateien findest du deine Cloud mit ein paar Beispieldateien:

Das Nextcloud-Dashboard mit dem Widget „Empfohlene Dateien"
Das Dashboard nach dem ersten Login

Die Dateien-Oberfläche von Nextcloud mit Ordnern und Beispieldateien
Die Dateien-App – das Herzstück deiner eigenen Cloud

Schritt 5: Hintergrund-Jobs (Cron) einrichten

Nextcloud muss regelmäßig Aufgaben erledigen (Aufräumen, Benachrichtigungen, Vorschaubilder). Standardmäßig passiert das per „AJAX" bei jedem Seitenaufruf – das ist unzuverlässig. Der empfohlene Weg ist ein Cron-Sidecar: ein zweiter Container mit demselben Image, der nur cron.php ausführt. Ergänze in der compose.yaml einen Service:

YAML
  nc-cron:
    image: nextcloud:34-apache
    container_name: nc-cron
    entrypoint: /cron.sh
    depends_on:
      nc-db:
        condition: service_healthy
    volumes:
      - nc_html:/var/www/html
    networks: [default]
    restart: unless-stopped

Der Sidecar teilt sich das nc_html-Volume mit der App und führt die Jobs alle fünf Minuten aus. Übernimm die Änderung und stell den Modus in Nextcloud auf „Cron":

Terminal
docker compose up -d
docker exec -u www-data nc-app php occ background:cron

Unter Verwaltung → Grundeinstellungen sollte jetzt „Cron" aktiv sein.

occ – das Kommandozeilen-Werkzeug

occ ist Nextclouds Admin-Werkzeug. Du rufst es immer als Nutzer www-data im App-Container auf: docker exec -u www-data nc-app php occ <befehl>. Zwei nützliche Aufräum-Befehle direkt nach der Installation:

Terminal
docker exec -u www-data nc-app php occ db:add-missing-indices
docker exec -u www-data nc-app php occ config:system:set default_phone_region --value=DE

Schritt 6: Die Clients verbinden

Jetzt der eigentliche Nutzen. Es gibt drei Wege, deine Cloud zu benutzen:

  1. Desktop-Sync-Client (Windows/macOS/Linux): Installiere den „Nextcloud Desktop"- Client, gib als Server-Adresse https://cloud.DEINE_DOMAIN ein, melde dich an und wähle einen lokalen Ordner. Dateien werden wie bei Dropbox synchronisiert. Mit den virtuellen Dateien (Windows/macOS) belegen sie erst dann Platz auf der Platte, wenn du sie öffnest – praktisch, wenn deine Cloud größer ist als die lokale Festplatte.
  2. Handy-App (Android/iOS): die offizielle Nextcloud-App, gleiche Server-Adresse. Ideal für den automatischen Foto-Upload vom Smartphone.
  3. Kalender & Kontakte: In den Systemeinstellungen deines Geräts ein CalDAV-/ CardDAV-Konto mit der Adresse https://cloud.DEINE_DOMAIN anlegen – dank der .well-known-Middleware aus Schritt 3 funktioniert die automatische Erkennung.

Funktionen wie Kalender, Kontakte oder Mail sind eigene Apps, die du unter Verwaltung → Apps mit einem Klick nachinstallierst – Nextcloud ist also erweiterbar, ohne dass du am Server etwas anfassen musst.

Nicht mit dem Admin-Konto arbeiten

Das Administrationskonto aus Schritt 4 ist für die Verwaltung gedacht, nicht für den Alltag. Leg dir unter Verwaltung → Konten ein normales Nutzerkonto an und synchronisiere deine Dateien darüber. So ist dein mächtiges Admin-Konto nicht ständig auf allen Geräten angemeldet – ein einfacher, aber wirksamer Sicherheitsgewinn. Für Familie oder Team legst du hier weitere Konten an; jedes bekommt seinen eigenen, verschlüsselten Bereich.

Wenn es nicht funktioniert

Symptom:Zugriff über eine nicht vertrauenswürdige Domäne" statt der Login-Seite.

Ursache & Lösung: Deine Domain steht nicht in trusted_domains. Prüfe NEXTCLOUD_TRUSTED_DOMAINS in der Compose-Datei. Nachträglich setzen geht per occ: docker exec -u www-data nc-app php occ config:system:set trusted_domains 1 --value=cloud.DEINE_DOMAIN.

Symptom: Der Sicherheits-Check meldet „Your web server is not set up properly to resolve .well-known/caldav".

Ursache & Lösung: Der CalDAV/CardDAV-Redirect greift nicht. Kontrolliere die nc-dav-Middleware-Labels (Schritt 3) und dass der Router sie über ...routers.nc.middlewares=nc-dav einbindet. Das Regex muss die volle https://…-URL matchen – redirectregex prüft die komplette URL, nicht nur den Pfad.

Symptom: Warnung „The ‘Strict-Transport-Security’ HTTP header is not set".

Ursache & Lösung: Der HSTS-Header fehlt. Setz ihn als Traefik-Middleware und häng sie an den Router: traefik.http.middlewares.nc-secure.headers.stsSeconds=15552000. Häng sie zusätzlich zur nc-dav-Middleware an den Router (...routers.nc.middlewares=nc-dav,nc-secure). Der Header muss vom Proxy kommen, nicht von Nextcloud. In Teil 2 richten wir genau diese nc-secure-Middleware vollständig ein (inklusive includeSubdomains).

Symptom: Große Uploads brechen ab oder enden mit einem Timeout / „413".

Ursache & Lösung: Das PHP-Limit ist zu klein. Erhöhe PHP_UPLOAD_LIMIT und PHP_MEMORY_LIMIT (Schritt 3) und starte den Container neu. In seltenen Fällen greifen diese Variablen nicht – dann ein eigenes php.ini-Snippet ins Image mounten.

Symptom: Beim ersten Start bricht die Installation mit „MySQL server has gone away" oder „Connection refused" ab.

Ursache & Lösung: Der App-Container war schneller als die Datenbank. Genau dagegen ist der healthcheck mit depends_on: condition: service_healthy da – prüfe, dass beide in deiner Compose-Datei vorhanden sind, und starte mit docker compose up -d neu.

Wartung & Backups

  • Backups sind bei einer Cloud Pflicht. Ein konsistentes Backup braucht drei Dinge: die Datenbank (MariaDB-Dump), das Datenverzeichnis (deine Dateien) und die Konfiguration (config.php). Versetze Nextcloud vor dem Backup kurz in den Wartungsmodus, damit Datenbank und Dateien zueinander passen:

    Terminal
    docker exec -u www-data nc-app php occ maintenance:mode --on
    docker exec nc-db mariadb-dump -u root -pEIN_STARKES_ROOT_PASSWORT nextcloud > nextcloud-db.sql
    docker exec -u www-data nc-app php occ maintenance:mode --off

    Sichere den Dump zusammen mit dem nc_html-Volume verschlüsselt und off-site mit Restic – das rohe nc_db-Volume musst du dank des Dumps nicht zusätzlich sichern. Im nc_html-Volume stecken sowohl der Programmcode und die config.php als auch – unter data/deine eigentlichen Nutzerdateien. Wächst deine Cloud stark, kannst du dieses data/-Verzeichnis später auf ein eigenes, größeres Volume auslagern; fürs erste reicht ein Volume für alles.

  • Updates: immer nur eine Hauptversion pro Schritt. Von 34 auf 35, nie direkt auf 36. Setz den Image-Tag hoch (nextcloud:35-apache), dann docker compose pull und docker compose up -d. Der Container führt das nötige occ upgrade beim Start automatisch aus. Vorher immer ein Backup anlegen. Den Cron-Sidecar auf dieselbe Version heben.

  • Sicherheit prüfen. Lass nach dem Aufsetzen den offiziellen Nextcloud Security Scan gegen deine Domain laufen (Ziel: Note A) und arbeite die Warnungen aus der Admin-Übersicht ab. Die Übersicht unter Verwaltung → Übersicht führt automatische Prüfungen durch und zeigt genau, was noch fehlt. Halte Nextcloud aktuell – Sicherheitslücken werden zeitnah geschlossen, aber nur, wenn du updatest.

  • Ehrlich zum Aufwand: Eine selbst gehostete Cloud will gepflegt werden. Rechne mit einem Update-Durchgang etwa monatlich und einem regelmäßigen Blick in die Admin-Übersicht. Dafür gehören die Daten dann wirklich dir.

Zuletzt aktualisiert: 20.07.2026

Feedback per E-Mail: feedback@serverkueche.de

Wie geht's weiter?

Das könnte dir auch schmecken