navigation Navigation


Nextcloud Installation - Ubuntu Server


Nextcloud ist eine leistungsstarke Open-Source-Lösung zur Datenspeicherung und -synchronisation, die Ihnen volle Kontrolle über Ihre Daten bietet. Diese Anleitung zeigt Schritt für Schritt, wie Sie Nextcloud auf einem Ubuntu Server mit Docker installieren, ein SSL-Zertifikat einrichten und eine eigene Domain konfigurieren. Die vorgestellte Methode bietet Sicherheit, Skalierbarkeit und einfache Wartung durch Container-Technologie. Nach Abschluss verfügen Sie über Ihre private Cloud-Lösung mit verschlüsseltem Zugriff über einen benutzerdefinierten Domainnamen.

Inhaltsverzeichnis

    Einführung

    In diesem Artikel gehen wir durch den Prozess der Installation von Nextcloud auf einem eigenen Server (in meinem Fall VPS) inkl. Docker, SSL-Zertifikat und einer Wunschdomain. Mit Wunschdomain ist gemeint, dass ihr eine von euren Domains oder Subdomains verwenden könnt.

    Voraussetzungen

    • Server: Du hast bereits einen aktiven und funktionsfähigen Server inkl. SSH-Zugang
    • Domain: Du hast mindestens eine Domain oder eine Sub-Domain, die du für Nextcloud verwenden möchtest
    • Nginx: Du hast einen Nginx-Server einsatzbereit
    • PHP 8.3 mit FPM: Nextcloud 32 benötigt die PHP-Version 8.3.
    • cURL: Das Tool curl ist installiert

    Die Installation wird nach der offiziellen Anleitung durchgeführt. Dabei wird Docker eingesetzt. Diese Installationsmethode beinhaltet alle Pakete und Konfigurationen, die notwendig sind, um Nextcloud optimal zu betreiben. Eine manuelle Installation ist selbstverständlich auch möglich, allerdings ist der Aufwand deutlich größer. Auch die Wartung kann spürbar aufwendiger sein.

    Installtion - Docker

    Für Installation von Docker gibt es ebenfalls unterschiedliche Wege. Wir installieren Docker auf dem Ubuntu Server mit folgender Anweisung bzw. mit folgendem Script.

    curl -fsSL https://get.docker.com | sudo sh

    Damit wird Docker mit allen notwendigen Paketen installiert.


    Fehlerbehandlung

    Wenn Docker erfolgreich installiert ist, kann man versuchen eine sehr simples Image auszuführen, das außer einer Ausgabe nichts tut.

    docker run hello-world

    Dabei kann man folgende Fehlermeldung erhalten.

    docker: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Head "http://%2Fvar%2Frun%2Fdocker.sock/_ping": dial unix /var/run/docker.sock: connect: permission denied
    
    Run 'docker run --help' for more information

    In diesem Fall müsste man folgende Installation durchführen.

    dockerd-rootless-setuptool.sh install

    Diese Installation kann allerdings einen weiteren Fehler werfen, welcher wie folgt aussehen kann.

    ########## BEGIN ##########
    sudo sh -eux <<EOF
    # Install newuidmap & newgidmap binaries
    apt-get install -y uidmap
    EOF
    ########## END ##########

    In diesem Fall sollte man das tun, was hier vorgeschlagen wird, nämlich das Paket uidmap installieren.

    sudo apt install -y uidmap

    Danach kann man erneut den Befehl dockerd-rootless-setuptool.sh install ausführen. Die Installation sollte nun problemlos laufen und wenn sie fertig ist, bekommt einige Informationen ausgeben.

    Wichtig bei dieser Ausgabe wären die Einträge für .bashrc.

    ...
    
    [INFO] Make sure the following environment variable(s) are set (or add them to ~/.bashrc):
    export PATH=/usr/bin:$PATH
    
    [INFO] Some applications may require the following environment variable too:
    export DOCKER_HOST=unix:///run/user/1000/docker.sock

    Diese Zeilen sollte man in eigene .bashrc einfügen.

    Ubuntu Server - Docker .bashrc Einträge

    Nun sollte Docker lauffähig sein.

    VirtualHost Eintrag (Part 1)

    Damit unser Nginx weiß, auf welche Domain wie zu reagieren ist und (später) wir auch die Möglichkeit Pfade zu SSL-Zertifikaten anzugeben, müssen wir einen VirtualHost Eintrag erstellen.

    Zuerst machen wir einen Eintrag in der /etc/hosts Datei.

    ...
    
    100.200.300.400 cloud.mydomain.com

    Statt der 100.200.300.400 eure Server-IP verwenden und statt mydomain.com eben eure Domain.

    Anschließend erstellen wir eine neue Datei unter /etc/nginx/sites-available/cloud.mydomain.com.

    sudo vi /etc/nginx/sites-available/cloud.mydomain.com

    Wir platzieren dort zunächst ein Minimum an Konfiguration, sodass Certbot die Domain über Port 80 erreichen kann. Dies wird benötigt, um ein SSL-Zertifikat zu erstellen.

    server {
        listen 80;
        listen [::]:80;
        server_name cloud.mydomain.com;
    }

    Das reicht für die Verwendung von Certbot zum Erstellen des Zertifikats aus. Wir speichern die Datei und verlinken sie unter aktivierten Instanzen.

    cd /etc/nginx/sites-enabled/
    sudo ln -s /etc/nginx/sites-avaiable/cloud.mydomain.com .

    Nun starten wir Nginx neu, um die Änderungen wirksam zu machen.

    sudo systemctl restart nginx

    SSL-Zertifikat (Certbot)

    Nun können wir mit Certbot unser SSL-Zertifikat anfordern.

    sudo certbot --nginx -d cloud.mydomain.com

    Certbot wird für uns die Datei /etc/nginx/sites-available/cloud.mydomain.com modifizieren, den Block für Port 80 erweitern und den Block für Port 443 hinzufügen.

    Wenn die Erstellung des Zertifikats erfolgreich war, erhalten wir in der Konsole in etwa folgende Ausgabe.

    Successfully received certificate.
    Certificate is saved at: /etc/letsencrypt/live/cloud.mydomain.com/fullchain.pem
    Key is saved at:         /etc/letsencrypt/live/cloud.mydomain.com/privkey.pem
    This certificate expires on 2025-08-20.
    These files will be updated when the certificate renews.
    Certbot has set up a scheduled task to automatically renew this certificate in the background.
    
    Deploying certificate
    Successfully deployed certificate for cloud.mydomain.com to /etc/nginx/sites-enabled/cloud.mydomain.com
    Your existing certificate has been successfully renewed, and the new certificate has been installed.

    VirtualHost Eintrag (Part 2)

    Wenn wir nun die Datei /etc/nginx/sites-available/cloud.mydomain.com erneut öffnen, werden wir feststellen, dass der Certbot einige Änderungen vorgenommen hat.

    In diesem Schritt ergänzen wir unsererseits ebenfalls die Datei mit ein paar Einstellungen, die für Nextcloud wichtig sind.

    Die End-Version der Datei sollte wie folgt aussehen.

    /etc/nginx/sites-available/cloud.mydomain.com
    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }
    
    server {
        listen 80;
        listen [::]:80;
        server_name cloud.mydomain.com;
    
        location / { return 301 https://$host$request_uri; }
    }
    
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name cloud.mydomain.com;
    
        ssl_certificate     /etc/letsencrypt/live/cloud.mydomain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/cloud.mydomain.com/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    
        client_max_body_size 0;
        proxy_buffering           off;
        proxy_request_buffering   off;
        proxy_read_timeout   86400s;
        proxy_connect_timeout     60s;
        proxy_send_timeout        300s;
    
        add_header Referrer-Policy                   "no-referrer"       always;
        add_header X-Content-Type-Options           "nosniff"           always;
        add_header X-Download-Options                "noopen"            always;
        add_header X-Frame-Options                   "SAMEORIGIN"        always;
        add_header X-Permitted-Cross-Domain-Policies "none"              always;
        add_header X-Robots-Tag                      "noindex, nofollow" always;
        add_header X-XSS-Protection                  "1; mode=block"     always;
    
        fastcgi_hide_header X-Powered-By;
    
        location / {
            proxy_pass         http://127.0.0.1:11000$request_uri;
            proxy_set_header   Host              $host;
            proxy_set_header   X-Real-IP         $remote_addr;
            proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   X-Forwarded-Host  $host;
            proxy_set_header   X-Forwarded-Port  $server_port;
    
            proxy_http_version 1.1;
            proxy_set_header   Upgrade    $http_upgrade;
            proxy_set_header   Connection $connection_upgrade;
    
            proxy_pass_header  Server;
            proxy_pass_header  Content-Type;
            proxy_pass_header  Content-Length;
            proxy_pass_header  Last-Modified;
            proxy_pass_header  ETag;
        }
    
        location ^~ /.well-known {
            proxy_pass         http://127.0.0.1:11000$request_uri;
            proxy_set_header   Host              $host;
            proxy_set_header   X-Real-IP         $remote_addr;
            proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_redirect     off;
        }
    }

    Nach jeder Änderung der Konfiguration von Nginx sollte der Dienst neugestartet werden.

    sudo systemctl restart nginx

    Nextcloud Docker Container

    Nun können wir unseren Docker Container für Nextcloud mit einigen Optionen (Umgebungsvariablen) starten.

    Der Befehl sieht wie folgt aus.

    sudo docker run \
    --init \
    --sig-proxy=false \
    --name nextcloud-aio-mastercontainer \
    --restart always \
    -p 8080:8080 \
    -e APACHE_PORT=11000 \
    -e APACHE_IP_BINDING=127.0.0.1 \
    -e SKIP_DOMAIN_VALIDATION=true \
    -e NEXTCLOUD_DATADIR="/srv/nextcloud/data" \
    -v nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
    -v /var/run/docker.sock:/var/run/docker.sock:ro \
    ghcr.io/nextcloud-releases/all-in-one:latest

    Wichtiger Hinweis

    Dieser Befehl startet den Docker Container im Vordergrundmodus. Das bedeutet, dass der Terminal (Shell-Instanz), in welchem ihr diesen Befehl ausführt, mit diesem Dienst belegt sein wird. Später starten wir den Container im Hintergrundmodus. Während der Konfiguration/Installation ist es allerdings relativ praktisch direkt bestimmte Logs zu sehen.


    Erklärung - Befehl

    Im folgenden platziere ich eine Erklärung des Befehls. Damit tut man sich sicherlich leichter. Wenn man diese längere Anweisung in Einzelteile zerlegt, wird es deutlich klarer, welcher Part wofür zuständig ist.

    sudo docker run Startet einen neuen Docker-Container mit Administratorechten.

    --init Verwendet einen Init-Prozess im Container für bessere Prozessverwaltung.

    --sig-proxy=false Verhindert die Weiterleitung von Signalen an den Container-Hauptprozess.

    --name nextcloud-aio-mastercontainer Gibt dem Container einen eindeutigen Namen.

    --restart always Container startet automatisch neu bei Systemstart oder nach Abstürzen.

    -p 8080:8080 Weiterleitung von Host-Port 8080 auf Container-Port 8080 (Web-Interface Zugang).

    -e APACHE_PORT=11000 Setzt den internen Apache-Port auf 11000.

    -e APACHE_IP_BINDINGS=127.0.0.1 Bindet Apache nur an localhost (aus Gründen der Sicherheit).

    -e NEXTCLOUD_DATADIR="/srv/nextcloud/data" Definiert das Datenverzeichnis für Nextcloud.

    -v nextcloud_aio_mastercontainer:/mnt/docker-aio-config Persistenter Speicher für Konfigurationsdaten.

    -v /var/run/docker.sock:/var/run/docker.sock:ro Schreibgeschützter Zugriff auf Docker-Socket (ermöglicht dem Master-Container, andere Container zu verwalten).

    ghcr.io/nextcloud-releases/all-in-one:latest Das offizielle Nextcloud AIO Image von GitHub Container Registry.

    Damit sollte unser Nextcloud Container laufen.

    Nextcloud Installation

    An diesem Punkt sollte man in der Lage sein, die Installation von Nextcloud im Browser zu starten.

    Wichtiger Hinweis

    Die Installation von Nextcloud an diesem Schritt muss über die IP und den Port erfolgen. Zum Beispiel, 123.456.789.321:8080.

    Ihr bekommt wahrscheinlich die Meldung, dass das SSL-Zertifikat nicht valide ist. Das ist für diesen Schritt in Ordnung und kann einfach bestätigt werden.

    Es sollte sich ein Wizard für die Einrichtung starten.


    Domain Bindung

    So ziemlich im ersten Schritt wird ein Eingabefeld für eine Domain präsentiert. Hier sollte man die Domain eintragen, unter welcher Nextcloud später verfügbar sein soll. In unserem Beispiel wäre es die cloud.mydomain.com. In eurem Fall natürlich eine andere.

    Es kann vorkommen, dass die Domain-Bindung nicht funktioniert. Hier kriegt ihr ein dann ungefähr folgende Fehlermeldung.

    Domain does not point to this server or the reverse proxy is not configured correctly. See the mastercontainer logs for more details. ('sudo docker logs -f nextcloud-aio-mastercontainer')

    Das hängt mit der Domain-Validierung zusammen. Falls ihr diese Fehlermeldung bekommt, wäre die einfachste Lösung den laufenden Container zu stoppen, anschließen zu löschen und eine weitere Option zum Docker-Befehl hinzuzufügen.

    Um den Container zu stoppen, gibt es folgenden Befehl.

    Container stoppen
    sudo docker stop nextcloud-aio-mastercontainer

    Falls ihr einen anderen Namen für euren Container gewählt habt, dann bitte diesen verwenden. Alternativ könnt ihr auch die Container-ID angeben.

    Wie aber schon weiter oben kurz mitgeteilt, wurde mit dem Docker-Befehl oben der Container im Vordergrundmodus gestartet. Für diesen Zweck könnt ihr Strg+C (ggf. mehrmals) verwenden, um die Ausführung des Containers zu unterbrechen. Dennoch solltet ihr sichergehen und den Container mit dem regulären Befehl stoppen.

    Anschließend entfernen wir den Container mit dem folgenden Befehl.

    Container entfernen
    sudo docker rm nextcloud-aio-mastercontainer

    Nun starten wir den Container erneut und fügen dabei folgende Option hinzu: -e SKIP_DOMAIN_VALIDATION=true.

    Container entfernen
    sudo docker run \
        --init \
        --sig-proxy=false \
        --name nextcloud-aio-mastercontainer \
        --restart always \
        -p 8080:8080 \
        -e APACHE_PORT=11000 \
        -e APACHE_IP_BINDING=127.0.0.1 \
        -e SKIP_DOMAIN_VALIDATION=true \
        -e NEXTCLOUD_DATADIR="/srv/nextcloud/data" \
        -v nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
        -v /var/run/docker.sock:/var/run/docker.sock:ro \
        ghcr.io/nextcloud-releases/all-in-one:latest

    Damit umgehen wir, dass der AIO-Container einen speziellen Endpoint auf eurer Domain nicht erreichen kann.

    Damit sollte man die Domain-Bindung machen können.


    Einzelne Container

    Das Wizard führt uns nun weiter zu der Einrichtung der Container. Zuvor kann es sein, eine Option als Frage vorhanden ist, bei der man eine höhere Version von Nextcloud Hub installieren kann. In meinem Fall wurde die Option angeboten die Version 10 zu installieren. Die Option habe ich mitgenommen.

    Die Installation nimmt, je nach Server und Internetverbindung, eine bestimmte Zeit in Anspruch. Hier nicht zu schnell die weiße Fahne ziehen.

    Im abschließenden Schritt werden die einzelnen Container vorbereitet und gestartet. Auch das nimmt eine bestimmte Zeit in Anspruch. Die Container starten nicht in der visuell dargestellten Reihenfolge, sondern in Abhängigkeit voneinander.

    Das Ziel sollte sein, dass alle aufgelisteten Container laufen.

    Containers
    * Apache (Running) (docs)
    * Database (Running)
    * Nextcloud (Running)
    * Notify Push (Running)
    * Redis (Running)
    * Collabora (Running) (docs)
    * Talk (Running) (docs)
    * Imaginary (Running)
    * Whiteboard (Running)
    Your containers are up-to-date.

    Ebenfalls bekommt man eine Ausgabe mit dem Benutzer (in der Regel admin) und dem Admin-Passwort. Das Passwort könnt ihr dann nach der Einrichtung unter Einstellungen ändern.

    Ebenfalls sollte (je nach Version) ein Button oder ein Link da sein, welcher uns zu unserer Nextcloud-Instanz bringt. Dabei wird die URL bzw. Domain angesteuert, welche ihr angebunden habt.

    Docker Container im Hintergrund

    Jetzt ist die Installation von Nextcloud abgeschlossen und wir sollten den Docker-Container im Hintergrund ausführen. Dazu sollten wir den aktuell laufenden Container anhalten, löschen und unser Script mit der Option -d ausführen.

    Container anhalten und löschen
    sudo docker stop nextcloud-aio-mastercontainer
    sudo docker rm nextcloud-aio-mastercontainer

    Und dann den Docker-Befehl mit der Option -d neu starten.

    Container neu starten
    sudo docker run -d \
        --init \
        --sig-proxy=false \
        --name nextcloud-aio-mastercontainer \
        --restart always \
        -p 8080:8080 \
        -e APACHE_PORT=11000 \
        -e APACHE_IP_BINDING=127.0.0.1 \
        -e SKIP_DOMAIN_VALIDATION=true \
        -e NEXTCLOUD_DATADIR="/srv/nextcloud/data" \
        -v nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
        -v /var/run/docker.sock:/var/run/docker.sock:ro \
        ghcr.io/nextcloud-releases/all-in-one:latest

    Damit startet der Container im Hintergrund und ihr könnt euch von eurem Server abmelden.

    Anmeldung und Einrichtung

    Nun sollte Nextcloud unter der gebundenen Domain laufen, also unter https://cloud.mydomain.com. Ihr könnt euch mit dem Benutzer admin und dem vorher angezeigten Passwort anmelden.

    Das Passwort könnt ihr unter Einstellungen ändern. Dazu klickt ihr rechts oben auf das Benutzer-Icon. Dort wählt ihr den Punkt Persönliche Einstellungen. Danach geht ihr zu Sicherheit und dort habt ihr die Möglichkeit das Passwort zu ändern.

    Nextcloud - Passwort ändern


    Repartur (Optional)

    Es kann vorkommen, dass Nextcloud unter Administrationseinstellungen > Verwaltung > Übersicht euch so etwas meldet.

    One or more mimetype migrations are available.
    Occasionally new mimetypes are added to better handle certain file types. 
    Migrating the mimetypes take a long time on larger instances so this is 
    not done automatically during upgrades. 
    Use the command occ maintenance:repair --include-expensive to perform the migrations

    Die Lösung dafür ist die Ausführung eines Befehls. Diesen Befehl müssen wir im Docker Container ausführen.

    sudo docker exec --user www-data nextcloud-aio-nextcloud php occ maintenance:repair --include-expensive

    Anschließend kann man den Status mit folgender Anweisung überprüfen.

    sudo docker exec --user www-data nextcloud-aio-nextcloud php occ status

    Damit sollte die Warnung im Backend von Nextcloud weg sein.

    Ich hoffe, ich habe nichts vergessen. Bitte prüft die Angaben immer zu dem Zeitpunkt entsprechend, wenn ihr es verwendet. Anforderungen und Methoden ändern sich mit der Zeit.