Nextcloud nativ auf Ubuntu installieren: LEMP-Stack mit Nginx, MariaDB und PHP-FPM
Nextcloud 34 als vollwertige private Cloud direkt auf Ubuntu 24.04 installieren – ohne Docker, mit Nginx, MariaDB 11.4, PHP-FPM 8.3 und Redis für maximale Kontrolle und Performance. Schritt für Schritt bis zur TLS-gesicherten, produktionsreifen Instanz.

Nextcloud ist die meistgenutzte Open-Source-Plattform für private Cloud-Speicherung, Kalender, Kontakte und Kollaboration. Während Nextclouds eigenes All-in-One-Docker-Image einen schnellen Einstieg bietet, wählen erfahrene Admins und KMU-Betreiber häufig den nativen Weg: direkte Installation auf dem Server ohne Container-Layer. Du erhältst so vollen Zugriff auf PHP-INI, MariaDB-Tuning und Nginx-Konfiguration, einfacheres systemd-Management und bessere Performance auf dedizierten oder virtuellen Servern. Diese Anleitung führt dich Schritt für Schritt durch eine produktionsreife Nextcloud-34-Installation auf Ubuntu 24.04 LTS mit dem LEMP-Stack (Linux, Nginx, MariaDB, PHP-FPM) inklusive Redis-Caching und Let's-Encrypt-TLS – in etwa 90 bis 120 Minuten.
Voraussetzungen
- Ubuntu 24.04 LTS (64-Bit, Server-Installation; Ubuntu 26.04 LTS funktioniert ebenfalls)
- Mindestens 2 GB RAM (4 GB empfohlen für Produktivbetrieb mit mehreren PHP-FPM-Workern)
- Mindestens 20 GB Speicher für OS und Nextcloud-Dateien; separater Speicher bzw. Volume für Nutzerdaten
- Registrierte Domain mit DNS-A-Eintrag, der auf die Server-IP zeigt (für Let's Encrypt zwingend)
- Root- oder sudo-Zugang zum Server; SSH-Key-Authentifizierung empfohlen (siehe SSH-Key-Authentifizierung einrichten)
- Internetverbindung während der Installation (apt, wget, Certbot)
- Grundkenntnisse in der Linux-Kommandozeile;
systemd-Grundlagen hilfreich
Nativ vs. Docker-AIO: Wann lohnt sich welcher Weg?
Nextclouds All-in-One-Docker-Image ist ideal für schnelle Testinstallationen oder wenn du keinen direkten Serverzugriff hast. Für den Produktivbetrieb auf einem dedizierten oder gemieteten VPS sprechen handfeste Argumente für den nativen Weg:
| Kriterium | Nativ (LEMP) | Docker AIO |
|---|---|---|
| PHP-FPM-Tuning | Direkt per INI | Nur via AIO-Konfiguration |
| MariaDB-Zugriff | Voll, per mariadb-CLI | Im Container isoliert |
| TLS-Management | Certbot direkt | AIO-eigener Proxy |
| systemd-Integration | Native Dienste + Timer | Docker-Compose-Wrapper |
| Ressourcen-Overhead | Keiner | Container-Runtime |
| Installationszeit | 90–120 Min. | 15–30 Min. |
| Wartbarkeit | Vollständig transparent | AIO-Abstraktionsschicht |
Für reine Homelab-Tests oder wenn Docker bereits läuft, kann auch die Nextcloud-AIO-Docker-Anleitung der schnellere Weg sein. Wer volle Kontrolle will, liest weiter.
Stack-Komponenten und empfohlene Versionen (Stand Juni 2026)
| Komponente | Minimum | Empfohlen | Ubuntu-24.04-Paket |
|---|---|---|---|
| Nextcloud | 34.x | 34.0.x (aktuell) | manueller Download |
| PHP | 8.3 | 8.3 oder 8.4 | php8.3-fpm |
| MariaDB | 10.6 | 11.4 LTS oder 11.8 | mariadb-server |
| Nginx | 1.18 | 1.24+ | nginx |
| Redis | 6.x | 7.x | redis-server |
| APCu | 4.0.6 | aktuell | php8.3-apcu |
| phpredis | 2.2.6 | aktuell | php8.3-redis |
| Ubuntu | 22.04 LTS | 24.04 LTS | – |
Schritt 1: System vorbereiten und Pakete installieren
Aktualisiere das System und installiere alle benötigten Pakete in einem einzigen Durchgang. Die PHP-Extensions decken sowohl die Pflicht-Extensions (pdo_mysql, mbstring, xml, curl, gd, zip) als auch empfohlene Extensions (intl, apcu, redis, imagick, bz2, sodium) ab, damit der Nextcloud-Admin-Bereich keine Warnungen anzeigt.
sudo apt update && sudo apt upgrade -y
sudo apt install -y \
nginx \
php8.3-fpm php8.3-mysql php8.3-mbstring php8.3-xml php8.3-curl \
php8.3-gd php8.3-zip php8.3-bcmath php8.3-intl php8.3-gmp \
php8.3-apcu php8.3-redis php8.3-imagick php8.3-bz2 php8.3-sodium \
php8.3-exif \
mariadb-server mariadb-client \
redis-server \
certbot python3-certbot-nginx \
wget unzip ufw
sudo systemctl enable --now mariadb redis-server php8.3-fpm nginxVerifizieren: systemctl status php8.3-fpm mariadb redis-server nginx – alle vier Dienste sollten active (running) zeigen.
Schritt 2: MariaDB absichern und Datenbank anlegen
Der interaktive Sicherungsassistent entfernt anonyme Nutzer und deaktiviert Remote-Root-Login. Danach legst du eine dedizierte Datenbank mit dem Pflicht-Zeichensatz utf8mb4 und der Collation utf8mb4_unicode_ci an – Nextcloud verweigert bei falscher Collation die Installation.
sudo mysql_secure_installation
sudo mariadb <<SQL
CREATE DATABASE nextcloud DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'nc_user'@'localhost' IDENTIFIED BY 'STARKES_DB_PASSWORT';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nc_user'@'localhost';
FLUSH PRIVILEGES;
SQLVerifizieren: sudo mariadb -e "SHOW DATABASES;" – die Datenbank nextcloud erscheint in der Liste.
Schritt 3: PHP-FPM optimieren
Erstelle eine Nextcloud-spezifische INI-Datei. Wichtig: opcache.save_comments=1 ist keine Kür, sondern Pflicht – Nextcloud nutzt PHP-Docblock-Annotationen für sein Dependency-Injection-System. Ohne diese Einstellung startet die Anwendung nicht korrekt.
sudo tee /etc/php/8.3/fpm/conf.d/99-nextcloud.ini <<'EOF'
memory_limit = 512M
upload_max_filesize = 16G
post_max_size = 16G
max_execution_time = 3600
max_input_time = 3600
output_buffering = 0
date.timezone = Europe/Berlin
opcache.enable = 1
opcache.enable_cli = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 10000
opcache.revalidate_freq = 1
opcache.save_comments = 1
apc.enable_cli = 1
EOF
# Symlink fuer CLI (occ-Befehle nutzen ebenfalls diese Einstellungen)
sudo ln -sf /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-fpmVerifizieren: php8.3 -r "echo ini_get('memory_limit');" – Ausgabe sollte 512M zeigen.
Schritt 4: Redis über Unix-Socket konfigurieren
Redis über einen Unix-Socket einzubinden reduziert die Latenz gegenüber TCP (127.0.0.1:6379) messbar, weil kein Netzwerk-Stack beteiligt ist. Der Benutzer www-data muss der Gruppe redis angehören, um den Socket zu erreichen.
sudo bash -c 'cat >> /etc/redis/redis.conf' <<'EOF'
unixsocket /run/redis/redis-server.sock
unixsocketperm 770
requirepass STARKES_REDIS_PASSWORT
EOF
sudo usermod -aG redis www-data
sudo systemctl restart redis-serverVerifizieren: ls -la /run/redis/ – der Socket redis-server.sock mit Berechtigungen srwxrwx--- sollte sichtbar sein.
Schritt 5: Nextcloud herunterladen und entpacken
Lade immer latest.zip zusammen mit der SHA256-Prüfsumme herunter und verifiziere die Integrität vor dem Entpacken. Das Data-Verzeichnis muss außerhalb des Nginx-Webroot liegen – andernfalls wären Nutzerdateien direkt über HTTP abrufbar.
cd /tmp
wget https://download.nextcloud.com/server/releases/latest.zip
wget https://download.nextcloud.com/server/releases/latest.zip.sha256
sha256sum -c latest.zip.sha256
unzip -q latest.zip
sudo mv nextcloud /var/www/nextcloud
sudo chown -R www-data:www-data /var/www/nextcloud
# Data-Verzeichnis AUSSERHALB des Webroot
sudo mkdir -p /var/nextcloud-data
sudo chown -R www-data:www-data /var/nextcloud-data
sudo chmod 750 /var/nextcloud-dataVerifizieren: sha256sum -c latest.zip.sha256 muss mit latest.zip: OK abschließen. Danach: ls /var/www/nextcloud/ zeigt index.php, occ und weitere Dateien.
Schritt 6: Nginx-Konfiguration anlegen
Die Nginx-Konfiguration sperrt alle sensitiven Verzeichnisse wie /config, /data oder /lib explizit mit return 404, setzt alle Security-Header und stellt sicher, dass client_max_body_size mit dem PHP-Limit übereinstimmt. Ersetze cloud.example.com überall durch deine echte Domain.
sudo tee /etc/nginx/sites-available/nextcloud.conf <<'NGINX'
upstream php-handler {
server unix:/run/php/php8.3-fpm.sock;
}
server {
listen 80;
listen [::]:80;
server_name cloud.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name cloud.example.com;
ssl_certificate /etc/letsencrypt/live/cloud.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
root /var/www/nextcloud;
index index.php index.html;
client_max_body_size 16G;
fastcgi_buffers 64 4K;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
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;
location ~ /\. { deny all; }
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
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; }
location /.well-known/pki-validation { try_files $uri $uri/ =404; }
location / {
rewrite ^ /index.php;
}
location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|oc[ms]-provider/.+)\.php(?:$|/) {
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 modHeadersAvailable true;
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|woff2?|svg|gif|map|png|html|ttf|ico|jpg|jpeg|webp)$ {
try_files $uri /index.php$request_uri;
expires 6M;
access_log off;
}
}
NGINX
sudo ln -s /etc/nginx/sites-available/nextcloud.conf \
/etc/nginx/sites-enabled/
sudo nginx -tSchritt 7: TLS-Zertifikat mit Let's Encrypt beziehen
Certbot bezieht und erneuert das Zertifikat vollautomatisch. Der systemd-Timer certbot.timer kümmert sich um die Erneuerung – kein Handlungsbedarf danach.
sudo certbot --nginx -d cloud.example.com \
--non-interactive --agree-tos \
--redirect -m admin@example.com
sudo nginx -t && sudo systemctl reload nginxVerifizieren: curl -I https://cloud.example.com – HTTP-Statuscode 200 oder 302, der Strict-Transport-Security-Header ist gesetzt.
Schritt 8: Nextcloud per CLI installieren
Die Installation über occ maintenance:install ist der robusteste Weg: kein Browser-Timeout, keine halbfertigen Installationen durch Verbindungsabbrüche. Ersetze alle Platzhalterwerte durch deine eigenen.
cd /var/www/nextcloud
sudo -u www-data php occ maintenance:install \
--database='mysql' \
--database-name='nextcloud' \
--database-user='nc_user' \
--database-pass='STARKES_DB_PASSWORT' \
--admin-user='admin' \
--admin-pass='STARKES_ADMIN_PASSWORT' \
--admin-email='admin@example.com' \
--data-dir='/var/nextcloud-data'Verifizieren: Die Ausgabe endet mit Nextcloud was successfully installed. Außerdem existiert jetzt /var/www/nextcloud/config/config.php.
Schritt 9: config.php nach der Installation anpassen
Direkt nach der Installation ist nur localhost als vertrauenswürdige Domain eingetragen – Zugriffe über die echte Domain schlagen solange fehl. Außerdem konfigurierst du hier den zweistufigen Cache (APCu lokal, Redis für Locking und verteilten Cache) sowie das Wartungsfenster.
Caching-Strategie im Überblick
| Cache-Typ | Adapter | config.php-Schlüssel | Zweck |
|---|---|---|---|
| Lokaler Cache | APCu | memcache.local | In-Process-Cache pro PHP-FPM-Worker, sehr schnell |
| Verteilter Cache | Redis | memcache.distributed | Session-Daten über alle Worker hinweg |
| Filelocking | Redis | memcache.locking | Prozessübergreifende Locks gegen Race-Conditions |
| Redis-Verbindung | Unix-Socket | redis.host / port=0 | Niedriger IPC-Overhead statt TCP |
Setze alle Werte bequem über occ config:system:set:
sudo -u www-data php occ config:system:set trusted_domains 0 --value='cloud.example.com'
sudo -u www-data php occ config:system:set overwrite.cli.url --value='https://cloud.example.com'
sudo -u www-data php occ config:system:set default_phone_region --value='DE'
sudo -u www-data php occ config:system:set memcache.local --value='\OC\Memcache\APCu'
sudo -u www-data php occ config:system:set memcache.locking --value='\OC\Memcache\Redis'
sudo -u www-data php occ config:system:set memcache.distributed --value='\OC\Memcache\Redis'
sudo -u www-data php occ config:system:set redis host --value='/run/redis/redis-server.sock'
sudo -u www-data php occ config:system:set redis port --value=0 --type=integer
sudo -u www-data php occ config:system:set redis password --value='STARKES_REDIS_PASSWORT'
sudo -u www-data php occ config:system:set redis timeout --value=1.5 --type=float
sudo -u www-data php occ config:system:set maintenance_window_start --value=1 --type=integerDer Wert maintenance_window_start=1 legt fest, dass aufwändige Hintergrundaufgaben zwischen 01:00 und 05:00 Uhr UTC ablaufen – schont den Server tagsüber.
Schritt 10: Systemd-Timer für Hintergrundaufgaben
Ein systemd-Timer ist robuster als crontab oder Webcron, weil er unabhängig vom Webserver läuft und Ausführungszeiten im Journal protokolliert. Erstelle Service- und Timer-Unit:
sudo tee /etc/systemd/system/nextcloudcron.service <<'EOF'
[Unit]
Description=Nextcloud cron.php
After=network.target
[Service]
User=www-data
ExecStart=/usr/bin/php -f /var/www/nextcloud/cron.php
KillMode=process
EOF
sudo tee /etc/systemd/system/nextcloudcron.timer <<'EOF'
[Unit]
Description=Nextcloud cron.php alle 5 Minuten
[Timer]
OnBootSec=5min
OnUnitActiveSec=5min
Unit=nextcloudcron.service
[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now nextcloudcron.timer
# Nextcloud auf systemd-Cron umstellen
sudo -u www-data php /var/www/nextcloud/occ background:cronVerifizieren: systemctl list-timers nextcloudcron.timer – der Timer ist aktiv und zeigt die nächste geplante Ausführung.
Schritt 11: Datenbank-Indizes, Reparatur und Firewall
Diese drei occ-Befehle müssen nach jeder Neuinstallation ausgeführt werden. Besonders db:convert-filecache-bigint ist wichtig: Ohne 64-Bit-IDs im File-Cache drohen bei großen Instanzen Integer-Overflows.
sudo -u www-data php /var/www/nextcloud/occ db:add-missing-indices
sudo -u www-data php /var/www/nextcloud/occ maintenance:repair --include-expensive
sudo -u www-data php /var/www/nextcloud/occ db:convert-filecache-bigintFirewall freischalten:
sudo ufw allow 'Nginx Full'
sudo ufw enableVerifizieren: Öffne https://cloud.example.com im Browser – der Nextcloud-Login erscheint. Nach dem Einloggen unter Einstellungen → Verwaltung → Überblick sollten keine roten Warnungen erscheinen.
Troubleshooting / Typische Fehler
Fehler 413 „Request Entity Too Large" bei Uploads
Nginx und PHP müssen dieselben Limits haben. Prüfe client_max_body_size in der Nginx-Konfiguration und upload_max_filesize sowie post_max_size in der PHP-INI. Beide müssen auf 16G gesetzt sein. Nach Änderung: sudo systemctl reload nginx php8.3-fpm.
Zugriff mit der eigenen Domain schlägt fehl
Nach der Installation ist nur localhost als Trusted Domain eingetragen. Lösung: sudo -u www-data php occ config:system:set trusted_domains 0 --value='cloud.example.com' (wie in Schritt 9 beschrieben).
Nextcloud startet nicht – kryptische DI-Fehler
Ursache fast immer: opcache.save_comments=0 oder die INI-Datei wurde nicht für die CLI-PHP-Version verlinkt. Prüfe mit php8.3 -r "echo ini_get('opcache.save_comments');" – muss 1 liefern.
Redis-Verbindungsfehler in den Nextcloud-Logs
Häufigste Ursachen: (a) www-data ist nicht in der Gruppe redis (prüfen mit groups www-data), (b) Pfad des Unix-Sockets in config.php stimmt nicht mit dem in redis.conf überein, (c) falsches Redis-Passwort. Nach Gruppenänderung Nginx und PHP-FPM neu starten.
PHP-FPM Socket nicht gefunden nach PHP-Versionsupgrade
Nach einem Upgrade von PHP 8.3 auf 8.4 lautet der Socket-Pfad /run/php/php8.4-fpm.sock. Aktualisiere den upstream-Block in der Nginx-Konfiguration entsprechend und führe sudo nginx -t && sudo systemctl reload nginx aus.
Falsche Dateirechte nach Extraktion
Wenn unzip als Root ausgeführt wird und chown vergessen wird, schlägt die gesamte Installation mit Berechtigungsfehlern fehl. Lösung: sudo chown -R www-data:www-data /var/www/nextcloud /var/nextcloud-data.
Häufige Fragen
Warum APCu für memcache.local und nicht Redis?
APCu ist ein In-Process-Cache direkt im PHP-FPM-Worker – der Zugriff erfolgt ohne jeden IPC-Roundtrip. Redis als memcache.local wäre auf einem Einzelserver langsamer, weil jeder Aufruf eine Verbindung über den Unix-Socket benötigt. Das richtige Zusammenspiel: APCu für .local, Redis für .locking und .distributed.
Wie aktualisiere ich Nextcloud auf eine neue Version?
Entweder über den integrierten Web-Updater (Admin → Überblick → Update) oder per CLI: sudo -u www-data php occ maintenance:mode --on, dann den Updater starten oder Dateien manuell tauschen, danach sudo -u www-data php occ upgrade und abschließend maintenance:mode --off. Vorher immer ein Backup von /var/www/nextcloud, /var/nextcloud-data und einen mysqldump anlegen.
Wie überprüfe ich die Konfigurationsqualität?
Rufe scan.nextcloud.com mit deiner Domain auf – dort werden Sicherheitsheader, TLS-Konfiguration und HSTS bewertet. Zusätzlich zeigt Einstellungen → Verwaltung → Überblick alle fehlenden PHP-Extensions, falsche Cron-Einstellungen und Cache-Probleme.
Kann ich PostgreSQL statt MariaDB verwenden?
Ja, Nextcloud unterstützt PostgreSQL 14 bis 18 offiziell. Im occ maintenance:install-Befehl verwendest du dann --database='pgsql' statt 'mysql' und installierst php8.3-pgsql statt php8.3-mysql. MariaDB 11.4 ist im Ubuntu-Umfeld aber verbreiteter und in Community-Anleitungen besser dokumentiert.
Wie richte ich regelmäßige Backups ein?
Eine bewährte Strategie: mysqldump nextcloud täglich per Cronjob, rsync von /var/nextcloud-data auf einen Offsite-Speicher und Restic für versionierte Backups. Die ausführliche 3-2-1-Backup-Anleitung beschreibt das Vorgehen detailliert.
Fazit
Eine native Nextcloud-Installation auf dem LEMP-Stack ist aufwändiger als das Docker-AIO-Image, zahlt sich aber auf dedizierten und gemieteten Servern aus: volle Kontrolle über jeden Stack-Layer, direkter Systemzugriff, kein Container-Overhead und eine saubere systemd-Integration. Der beschriebene Weg mit Nginx, MariaDB 11.4, PHP 8.3-FPM, Redis über Unix-Socket und APCu liefert eine produktionsreife Instanz, die sich mit Standard-Linux-Bordmitteln administrieren lässt. Der zweistufige Cache (APCu lokal, Redis für Locking) und der systemd-Timer für Hintergrundaufgaben sind dabei keine optionalen Extras, sondern Voraussetzungen für stabilen Betrieb unter Last.
Weiterführende Anleitungen und Quellen
- Nextcloud mit Docker einrichten (All-in-One): die eigene Cloud – der schnellere Alternativweg
- WordPress nativ auf Ubuntu installieren (LAMP ohne Docker) – analoges Vorgehen für den LAMP-Stack
- VPS absichern und härten: UFW, SSH-Keys und Fail2Ban – Pflichtlektüre vor jedem Produktivbetrieb
- 3-2-1-Backup-Strategie umsetzen – Backups für Nextcloud-Daten und Datenbank
- Nextcloud Admin Manual: Source Installation (offiziell)
- Nextcloud Admin Manual: Nginx-Konfiguration (offiziell)
- Nextcloud Admin Manual: Caching-Konfiguration (offiziell)