Tutorials  /  Ubuntu

Nextcloud auf Ubuntu 24.04 mit nginx installieren

LLudwig · August 2026 ·8 Min. Lesezeit ·Ubuntu, Tutorial

Nextcloud lässt sich als Snap oder Container in wenigen Minuten starten, eine Installation aus dem offiziellen ZIP-Archiv gibt dir dafür volle Kontrolle über PHP-Tuning, Cache-Backend und TLS-Konfiguration. Diese Anleitung führt dich durch ein komplettes Setup auf Ubuntu 24.04 LTS mit nginx, PHP 8.3-FPM, MariaDB 10.11 und Redis. Am Ende läuft eine Instanz, die den Einrichtungscheck von Nextcloud ohne offene Warnungen besteht.

Warum Nextcloud hinter nginx und PHP-FPM betreiben?

Nextcloud hinter nginx und PHP-FPM zu betreiben trennt die Auslieferung statischer Dateien von der PHP-Ausführung: nginx liefert Assets direkt vom Dateisystem aus, während ein eigener FPM-Pool die Zahl paralleler PHP-Prozesse und deren Speicherlimit unabhängig vom Webserver begrenzt.

Das ist bei Nextcloud relevant, weil Sync-Clients viele parallele WebDAV-Verbindungen öffnen. Mit Apache und mod_php belegt jede dieser Verbindungen einen kompletten PHP-Interpreter. Mit nginx belegt sie nur einen leichtgewichtigen Worker, und nur die tatsächlichen PHP-Aufrufe landen im FPM-Pool.

graph LR
    A["Browser oder Desktop-Client"] --> B["nginx :443"]
    B -->|"statische Assets"| C["/var/www/nextcloud"]
    B -->|"FastCGI"| D["php8.3-fpm.sock"]
    D --> E["MariaDB: Metadaten"]
    D --> F["Redis: Locking und Cache"]
    D --> G["/var/nextcloud-data"]

Voraussetzungen

  • Ein Server mit Ubuntu 24.04 LTS, mindestens 2 vCPU und 4 GB RAM. Eine skalierbare Cloud-VM mit Ubuntu-Image erfüllt das direkt nach dem Provisioning.
  • Ein Benutzerkonto mit sudo-Rechten.
  • Eine Domain, deren A-Record (und optional AAAA-Record) auf die öffentliche IP des Servers zeigt. Im Folgenden steht dafür der Platzhalter <deine-domain>.
  • Offene Ports 80 und 443 in Firewall und Security-Group.

Ubuntu 24.04 liefert PHP 8.3 und MariaDB 10.11 aus den Standard-Paketquellen. Beide Versionen sind von Nextcloud 31 offiziell unterstützt, ein externes PPA ist nicht nötig.

Pakete installieren

Installiere Webserver, Datenbank, PHP-FPM und alle von Nextcloud benötigten Erweiterungen in einem Durchgang:

Konsole
$ sudo apt update && sudo apt upgrade -y
$ sudo apt install -y nginx mariadb-server redis-server unzip \
    php8.3-fpm php8.3-mysql php8.3-gd php8.3-curl php8.3-mbstring \
    php8.3-intl php8.3-xml php8.3-zip php8.3-bcmath php8.3-gmp \
    php-imagick php-apcu php-redis libmagickcore-6.q16-6-extra

Das Paket libmagickcore-6.q16-6-extra liefert die SVG-Unterstützung für Imagick nach. Ohne dieses Paket meldet der Einrichtungscheck später eine Warnung zur Modul-Konfiguration.

Datenbank anlegen

Sichere zuerst die MariaDB-Installation. Der Assistent setzt unter anderem den Unix-Socket-Login für root und entfernt anonyme Konten:

Konsole
$ sudo mariadb-secure-installation

Lege danach Datenbank und Benutzer an. Der Zeichensatz utf8mb4 ist Pflicht, sonst scheitern Dateinamen mit Emoji oder seltenen Zeichen:

sql
CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY '<db-passwort>';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost';
FLUSH PRIVILEGES;

Die Anweisungen gibst du in der MariaDB-Shell ein, die du mit sudo mariadb öffnest. Ersetze <db-passwort> durch ein zufällig erzeugtes Passwort, etwa aus openssl rand -base64 24.

VM

Passende Infrastruktur bei centron

Zum Mitmachen braucht es keine eigene Hardware: ccloud³ VMs mit vollem Root-Zugriff, stundengenau abgerechnet und in Sekunden startklar. Cloud-Server mieten →

PHP-FPM konfigurieren

Die Standardwerte von PHP reichen für Nextcloud nicht aus. Lege eine eigene INI-Datei an, statt php.ini direkt zu bearbeiten, damit Paket-Updates deine Werte nicht überschreiben:

ini
; /etc/php/8.3/fpm/conf.d/99-nextcloud.ini
memory_limit = 512M
upload_max_filesize = 512M
post_max_size = 512M
max_execution_time = 300
max_input_time = 300
output_buffering = 0
opcache.enable = 1
opcache.enable_cli = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 32
opcache.max_accelerated_files = 10000
opcache.revalidate_freq = 60
opcache.save_comments = 1
apc.enable_cli = 1

Das occ-Kommando läuft über den CLI-SAPI, der eine eigene Konfiguration nutzt. Verlinke die Datei deshalb auch dorthin, sonst bricht occ mit APCu-Fehlern ab:

Konsole
$ sudo ln -s /etc/php/8.3/fpm/conf.d/99-nextcloud.ini /etc/php/8.3/cli/conf.d/99-nextcloud.ini
$ sudo systemctl restart php8.3-fpm

Nextcloud herunterladen und entpacken

Lade das aktuelle Release der Serie 31 und prüfe die Prüfsumme, bevor du entpackst:

Konsole
$ cd /tmp
$ curl -LO https://download.nextcloud.com/server/releases/latest-31.zip
$ curl -LO https://download.nextcloud.com/server/releases/latest-31.zip.sha256
$ sha256sum -c latest-31.zip.sha256
latest-31.zip: OK

Entpacke das Archiv nach /var/www und lege das Datenverzeichnis außerhalb des Webroots an. So kann kein Fehler in der nginx-Konfiguration Benutzerdateien öffentlich machen:

Konsole
$ sudo unzip -q latest-31.zip -d /var/www
$ sudo mkdir -p /var/nextcloud-data
$ sudo chown -R www-data:www-data /var/www/nextcloud /var/nextcloud-data
$ sudo chmod 750 /var/nextcloud-data

nginx-vHost einrichten

Lege zuerst eine Snippet-Datei mit den Security-Headern an. nginx vererbt add_header nicht in Location-Blöcke, die eigene Header setzen, deshalb bindest du das Snippet an mehreren Stellen ein:

nginx
# /etc/nginx/snippets/nextcloud-headers.conf
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" 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;

Die eigentliche Serverkonfiguration:

nginx
# /etc/nginx/sites-available/nextcloud.conf
upstream php-handler {
    server unix:/run/php/php8.3-fpm.sock;
}
map $arg_v $asset_immutable {
    ""      "";
    default ", immutable";
}
server {
    listen 80;
    listen [::]:80;
    server_name <deine-domain>;
    root /var/www/nextcloud;
    index index.php index.html;
    client_max_body_size 512M;
    client_body_timeout 300s;
    fastcgi_buffers 64 4K;
    include snippets/nextcloud-headers.conf;
    gzip on;
    gzip_vary on;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_types application/javascript text/css text/plain application/json image/svg+xml;
    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }
    location ^~ /.well-known {
        location = /.well-known/carddav { return 301 /remote.php/dav/; }
        location = /.well-known/caldav  { return 301 /remote.php/dav/; }
        location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
        return 301 /index.php$request_uri;
    }
    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)              { return 404; }
    location ~ \.php(?:$|/) {
        rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+) /index.php$request_uri;
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        set $path_info $fastcgi_path_info;
        try_files $fastcgi_script_name =404;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $path_info;
        fastcgi_param front_controller_active true;
        fastcgi_pass php-handler;
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;
        fastcgi_max_temp_file_size 0;
    }
    location ~ \.(?:css|js|mjs|svg|gif|ico|jpg|png|webp|wasm|map|ogg|flac)$ {
        try_files $uri /index.php$request_uri;
        include snippets/nextcloud-headers.conf;
        add_header Cache-Control "public, max-age=15778463$asset_immutable";
        access_log off;
    }
    location ~ \.woff2?$ {
        try_files $uri /index.php$request_uri;
        include snippets/nextcloud-headers.conf;
        expires 7d;
        access_log off;
    }
    location /remote { return 301 /remote.php$request_uri; }
    location / { try_files $uri $uri/ /index.php$request_uri; }
}

Aktiviere den vHost, entferne die Default-Seite und prüfe die Syntax:

Konsole
$ sudo ln -s /etc/nginx/sites-available/nextcloud.conf /etc/nginx/sites-enabled/
$ sudo rm -f /etc/nginx/sites-enabled/default
$ sudo nginx -t
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo systemctl reload nginx

TLS-Zertifikat mit Certbot ausstellen

Certbot trägt Listener auf Port 443, Zertifikatspfade und einen HTTP-Redirect selbst in den vHost ein:

Konsole
$ sudo apt install -y certbot python3-certbot-nginx
$ sudo certbot --nginx -d <deine-domain> --redirect --agree-tos -m <deine-mailadresse>

Ergänze anschließend den HSTS-Header im Snippet /etc/nginx/snippets/nextcloud-headers.conf, damit der Sicherheitscheck von Nextcloud grün wird:

nginx
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;

Setze HSTS erst, wenn das Zertifikat tatsächlich ausgestellt ist. Ein HSTS-Header ohne funktionierendes TLS sperrt Browser für die Dauer von max-age von deiner Domain aus.

Was macht occ maintenance:install?

Der Befehl occ maintenance:install führt die komplette Erstinstallation ohne Weboberfläche aus: Er legt das Datenbankschema an, erzeugt das Administratorkonto, schreibt /var/www/nextcloud/config/config.php und setzt die Berechtigungen des Datenverzeichnisses.

Konsole
$ sudo -u www-data php /var/www/nextcloud/occ maintenance:install \
    --database mysql \
    --database-name nextcloud \
    --database-user nextcloud \
    --database-pass '<db-passwort>' \
    --admin-user admin \
    --admin-pass '<admin-passwort>' \
    --data-dir /var/nextcloud-data
Nextcloud was successfully installed

Danach trägst du die Domain als vertrauenswürdig ein und setzt die öffentliche URL. Ohne diese beiden Werte antwortet Nextcloud mit der Meldung über eine nicht vertrauenswürdige Domain:

Konsole
$ sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 1 --value=<deine-domain>
$ sudo -u www-data php /var/www/nextcloud/occ config:system:set overwrite.cli.url --value=https://<deine-domain>
$ sudo -u www-data php /var/www/nextcloud/occ config:system:set overwriteprotocol --value=https

Redis und Cron einrichten

Redis übernimmt das Transactional File Locking. Ohne dieses Backend nutzt Nextcloud die Datenbank für Sperren, was bei parallelen Sync-Clients messbar bremst. Aktiviere den Unix-Socket in /etc/redis/redis.conf:

Konsole
$ sudo sed -i 's|^# unixsocket /run/redis/redis-server.sock|unixsocket /run/redis/redis-server.sock|' /etc/redis/redis.conf
$ sudo sed -i 's|^# unixsocketperm 700|unixsocketperm 770|' /etc/redis/redis.conf
$ sudo usermod -aG redis www-data
$ sudo systemctl restart redis-server php8.3-fpm

Ergänze in /var/www/nextcloud/config/config.php innerhalb des $CONFIG-Arrays:

php
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'memcache.distributed' => '\\OC\\Memcache\\Redis',
  'memcache.locking' => '\\OC\\Memcache\\Redis',
  'redis' => [
    'host' => '/run/redis/redis-server.sock',
    'port' => 0,
  ],
  'default_phone_region' => 'DE',

Hintergrundjobs laufen im Standard über AJAX und damit nur, wenn jemand die Oberfläche geöffnet hat. Stelle auf einen echten Cron-Job um:

Konsole
$ sudo crontab -u www-data -e

Trage dort eine Zeile ein und wechsle den Modus:

Konsole
*/5 * * * * php -f /var/www/nextcloud/cron.php
$ sudo -u www-data php /var/www/nextcloud/occ background:job:mode cron
Set mode for background jobs to 'cron'

Installation verifizieren

Prüfe zuerst den Status über die Kommandozeile:

Konsole
$ sudo -u www-data php /var/www/nextcloud/occ status
  - installed: true
  - version: 31.0.6.1
  - versionstring: 31.0.6
  - maintenance: false
  - needsDbUpgrade: false
  - productname: Nextcloud

Dann von außen über HTTPS. status.php liefert dieselben Werte als JSON und ist der schnellste Health-Check für Monitoring:

Konsole
$ curl -s https://<deine-domain>/status.php
{"installed":true,"maintenance":false,"needsDbUpgrade":false,"version":"31.0.6.1","versionstring":"31.0.6","edition":"","productname":"Nextcloud","extendedSupport":false}

Melde dich anschließend als admin an und öffne Verwaltungseinstellungen → Übersicht. Der Einrichtungscheck sollte keine Warnungen mehr anzeigen. Prüfe zusätzlich, ob der 4-Byte-Support aktiv ist:

Konsole
$ sudo -u www-data php /var/www/nextcloud/occ config:system:get mysql.utf8mb4
true

Troubleshooting

502 Bad Gateway nach dem ersten Aufruf. nginx erreicht den FPM-Socket nicht. Prüfe den tatsächlichen Pfad und gleiche ihn mit dem upstream-Block ab:

Konsole
$ ls -l /run/php/
srw-rw---- 1 www-data www-data 0 Aug 17 09:12 php8.3-fpm.sock
$ sudo tail -n 20 /var/log/nginx/error.log

Warnung zu fehlenden Datenbank-Indizes. Nach größeren Updates fehlen gelegentlich Indizes. Beide Befehle sind im laufenden Betrieb sicher, können bei großen Tabellen aber einige Minuten dauern:

Konsole
$ sudo -u www-data php /var/www/nextcloud/occ db:add-missing-indices
$ sudo -u www-data php /var/www/nextcloud/occ db:add-missing-columns

Uploads brechen bei etwa 100 MB ab. Dann greift noch ein alter Wert. client_max_body_size in nginx sowie upload_max_filesize und post_max_size in PHP müssen übereinstimmen, und nach der PHP-Änderung braucht es einen Neustart von php8.3-fpm, kein Reload.

Fazit

Die Instanz läuft jetzt mit nginx, PHP 8.3-FPM, MariaDB und Redis als Locking-Backend, abgesichert über ein Let's-Encrypt-Zertifikat mit automatischer Erneuerung. Sinnvolle nächste Schritte sind ein Backup von Datenbank, config.php und /var/nextcloud-data sowie das Aktivieren der Zwei-Faktor-Authentifizierung für Administratorkonten. Vor jedem Nextcloud-Update gehört ein Snapshot des Servers dazu: Ein abgebrochener Updater-Lauf lässt die Instanz im Wartungsmodus zurück.

Weiterlesen

Jetzt 200 € Guthaben sichern

Testen Sie Ihr Setup auf ccloud³

Registrieren Sie sich in der ccloud³ und erhalten Sie 200 € Startguthaben für Ihr Projekt – z. B. für eine PostgreSQL-VM mit automatischen Backups.

Ludwig Technische Redaktion

Schreibt bei centron über Linux-Administration, Container und Datenbanken – mit Fokus auf Anleitungen, die im Betrieb tatsächlich funktionieren.

Kategorie Ubuntu
Teilen
Noch offene Fragen?

Our team will help you with your specific setup - in German or English, by people who run the platform themselves.

War dieses Tutorial hilfreich?

Your answer is stored anonymously and helps us improve our tutorials.

Kommentare

No comments yet - be the first to ask a question about this tutorial.

Sign in to comment

Comments are open to centron customers. Sign in to your account to ask a question about this tutorial.

Weiterlesen

Das könnte Sie auch interessieren

Jetzt kostenlos anfangen

Melden Sie sich an und erhalten Sie in den ersten 60 Tagen ein Guthaben von 200 € bei centron.

Dieses Werbeangebot gilt nur für neue Konten. Angebot ausschließlich für Gewerbetreibende.

Jetzt loslegen Sales kontaktieren