Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Cloud / Hosting 16.06.2026 · 11 min Lesezeit

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.

Moderne IT-Grafik zur Anleitung für die native Installation von Nextcloud auf Ubuntu mit LEMP-Stack, Nginx, MariaDB und PHP-FPM, inklusive Server, Terminal, Weboberfläche und wichtiger Konfigurationspfade. KI-generiert

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

  1. Ubuntu 24.04 LTS (64-Bit, Server-Installation; Ubuntu 26.04 LTS funktioniert ebenfalls)
  2. Mindestens 2 GB RAM (4 GB empfohlen für Produktivbetrieb mit mehreren PHP-FPM-Workern)
  3. Mindestens 20 GB Speicher für OS und Nextcloud-Dateien; separater Speicher bzw. Volume für Nutzerdaten
  4. Registrierte Domain mit DNS-A-Eintrag, der auf die Server-IP zeigt (für Let's Encrypt zwingend)
  5. Root- oder sudo-Zugang zum Server; SSH-Key-Authentifizierung empfohlen (siehe SSH-Key-Authentifizierung einrichten)
  6. Internetverbindung während der Installation (apt, wget, Certbot)
  7. 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:

KriteriumNativ (LEMP)Docker AIO
PHP-FPM-TuningDirekt per ININur via AIO-Konfiguration
MariaDB-ZugriffVoll, per mariadb-CLIIm Container isoliert
TLS-ManagementCertbot direktAIO-eigener Proxy
systemd-IntegrationNative Dienste + TimerDocker-Compose-Wrapper
Ressourcen-OverheadKeinerContainer-Runtime
Installationszeit90–120 Min.15–30 Min.
WartbarkeitVollständig transparentAIO-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)

KomponenteMinimumEmpfohlenUbuntu-24.04-Paket
Nextcloud34.x34.0.x (aktuell)manueller Download
PHP8.38.3 oder 8.4php8.3-fpm
MariaDB10.611.4 LTS oder 11.8mariadb-server
Nginx1.181.24+nginx
Redis6.x7.xredis-server
APCu4.0.6aktuellphp8.3-apcu
phpredis2.2.6aktuellphp8.3-redis
Ubuntu22.04 LTS24.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 nginx

Verifizieren: 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;
SQL

Verifizieren: 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-fpm

Verifizieren: 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-server

Verifizieren: 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-data

Verifizieren: 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 -t

Schritt 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 nginx

Verifizieren: 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-TypAdapterconfig.php-SchlüsselZweck
Lokaler CacheAPCumemcache.localIn-Process-Cache pro PHP-FPM-Worker, sehr schnell
Verteilter CacheRedismemcache.distributedSession-Daten über alle Worker hinweg
FilelockingRedismemcache.lockingProzessübergreifende Locks gegen Race-Conditions
Redis-VerbindungUnix-Socketredis.host / port=0Niedriger 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=integer

Der 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:cron

Verifizieren: 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-bigint

Firewall freischalten:

sudo ufw allow 'Nginx Full'
sudo ufw enable

Verifizieren: Ö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

  1. Nextcloud mit Docker einrichten (All-in-One): die eigene Cloud – der schnellere Alternativweg
  2. WordPress nativ auf Ubuntu installieren (LAMP ohne Docker) – analoges Vorgehen für den LAMP-Stack
  3. VPS absichern und härten: UFW, SSH-Keys und Fail2Ban – Pflichtlektüre vor jedem Produktivbetrieb
  4. 3-2-1-Backup-Strategie umsetzen – Backups für Nextcloud-Daten und Datenbank
  5. Nextcloud Admin Manual: Source Installation (offiziell)
  6. Nextcloud Admin Manual: Nginx-Konfiguration (offiziell)
  7. Nextcloud Admin Manual: Caching-Konfiguration (offiziell)