Nextcloud 25 selber hosten

Ahoi,

schon seit Jahren setze ich auf als freie Alternative zu , iCloud und , doch meine Sammlung von 15 Jahren an Fotos zwang bisher jeden Managed Nextcloud Provider in die Knie. Also bleibt mal wieder nur, es in die eigenen Hände zu nehmen 💪

Da ich Nextcloud genau auf meine Bedürfnisse anpassen wollte, habe ich bei 0 begonnen und nicht das vorgefertigte Docker Image von Nextcloud verwendet. Mal davon abgesehen, dass die Beispielkonfiguration nicht mal stabil ist!

Als Basis habe ich ubuntu/apache2 gewählt:

FROM ubuntu/apache2:2.4-22.04_beta

ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Europe/Berlin
RUN apt-get update && apt-get upgrade -y

Dazu teilen wir dem mit, dass wir bitte keine Interaktivität, also Fragen haben wollen und akzeptieren damit die Standardauswahl. Im Anschluss wählen wir unsere Zeitzone, welche aber auch im Nachhinein in der -compose.yml ändern können. Dann bereiten wir die Installation von PHP und seinen Erweiterungen vor und ziehen uns Updates.

Für meinen Anwendungsfall benötige ich folgende Packete

RUN apt-get install -y libtidy-dev apache2 libapache2-mod-php php-curl php-mbstring php-intl php-gmp php-bcmath php-imagick php-xml php-zip php-gd wget openssl php-common php-curl php-json php-xml php-zip php-dom php-xsl php-pgsql php-apcu php-bz2 php-dompdf php-redis ffmpeg curl php-simplexml php-iconv php-ctype libxml2 php-posix php-fileinfo

wget brauchen wir später, um Nextcloud herunterzuladen und ffmpeg wird von einer Nextcloud Erweiterung für die Thumbnail-Erstellung benötigt.

Nach der Empfehlung aus den Docs erhöhen wir das memory_limit von PHP

RUN sed -i 's/memory_limit = 128M/memory_limit = 4096M/g' /etc/php/8.1/apache2/php.ini
RUN sed -i 's/memory_limit = 128M/memory_limit = 4096M/g' /etc/php/8.1/cli/php.ini

Und output_buffering muss unbedingt deaktiviert werden

RUN sed -i 's/output_buffering = 4096/output_buffering = off/g'  /etc/php/8.1/apache2/php.ini

Damit der auch weiß, wo er Nextcloud findet und über welche Domain es zu erreichen ist, erstellen wir eine Datei nextcloud.conf


  DocumentRoot /var/www/html/
  ServerName  cloud.xtracode.ws

  ErrorLog /dev/stderr
  TransferLog /dev/stdout

  
    Require all granted
    AllowOverride All
    Options FollowSymLinks MultiViews

    
      Dav off
    
  

Diese stammt direkt aus den Docs., mit der Anpassung, dass die Logs an STDOUT gesendet werden. Damit kann man nun auch einen logging driver verwenden oder mit docker-compose logs -f die Logs live verfolgen.

Ebenfalls hat mein Server die Kapazität für und APCu, weswegen ich noch die Standardkonfiguration von Nextcloud erweitern musste. Dazu erstelle die Datei custom.config.php

$CONFIG = array (
        'memcache.local' => '\OC\Memcache\APCu',
        'memcache.distributed' => '\OC\Memcache\Redis',
        'redis' => [
             'host' => 'redis',
             'port' => 6379,
        ],
        'memcache.locking' => '\OC\Memcache\Redis',
        'enable_previews' => true,
        'enabledPreviewProviders' =>
        array (
            1 => 'OC\\Preview\\PNG',
            2 => 'OC\\Preview\\JPEG',
            3 => 'OC\\Preview\\GIF',
            4 => 'OC\\Preview\\BMP',
            5 => 'OC\\Preview\\XBitmap',
            6 => 'OC\\Preview\\MP3',
            7 => 'OC\\Preview\\MP4',
            8 => 'OC\\Preview\\TXT',
            9 => 'OC\\Preview\\MarkDown',
            12 => 'OC\\Preview\\Image',
        ),
);

Gerade bei größeren Datenmengen oder sehr vielen Dateien empfiehlt sich Redis fürs File locking einzusetzen. Damit Nextcloud aber auf Redis und APCu (Cache für PHP Laufzeitumgebung), müssen wir diese aktivieren, installiert sind ja beide schon.
custom.ini

; priority=50
extension=redis

apc.enabled=1
apc.enable_cli=1

opcache.save_comments = 1
opcache.revalidate_freq = 60
opcache.interned_strings_buffer = 64

Es sei auf die erste Zeile hinzuweisen. Diese teilt PHP mit, in welcher Reihenfolge die Konfigurationsdateien geladen werden sollen. Ansonsten kann es vorkommen, dass die Redis-Erweiterung vor seiner Abhängigkeit igbinary geladen wird, was zu einem Fehler und der Deaktivierung der Redis-Erweiterung führt.

Nun wollen wir die lokalen Konfigurationsdateien auch in die Dockerumgebung bekommen

COPY ./nextcloud.conf /etc/apache2/sites-available/nextcloud.conf
COPY ./custom.config.php /var/www/html/config/custom.config.php
COPY ./custom.ini /etc/php/8.1/mods-available/custom.ini

Die Konfigurationen müssen nun nur noch aktiviert werden

# Unsere Konfiguration für die PHP-Umgebung cli aktivieren, benötigt für Cronjobs.
RUN phpenmod -s cli custom
# Analog für apache2
RUN phpenmod -s apache2 custom
# Unsere apache2 Konfiguration aktivieren
RUN a2ensite nextcloud.conf
# Standardkonfiguration deaktivieren
RUN a2dissite 000-default

Nextcloud nutzt außerdem eine ausführliche .htaccess welche einige apache2-Erweiterungen benötigt, welche wir auch noch aktivieren müssen

RUN a2enmod rewrite
RUN a2enmod headers
RUN a2enmod env
RUN a2enmod dir
RUN a2enmod mime

Final kommen wir nun auch zu der eigentlichen Installation von Nextcloud unter /var/www/html.

RUN mkdir -pv /var/www/html
WORKDIR /var/www/html
RUN wget https://download.nextcloud.com/server/installer/setup-nextcloud.php -O /var/www/html/setup-nextcloud.php
RUN chown www-data:www-data -R /var/www
RUN runuser -u www-data -- php -v

Damit laden wir den Installer, sichern ihn unter /var/www/html/setup-nextcloud.php und starten zum Schluss einmal PHP, damit könnten wir direkt auf eventuelle Fehler beim Laden unserer Konfiguration reagieren.

Docker Compose

Das ganze lässt sich abschließend in einer docker-compose.yml vereinigen, aber für mich ohne PostgreSQL, Redis oder ElasticSearch. Bei meinen Servern bevorzuge ich geteilte Datenbankserver und Caches zu nutzen und nicht mit jeder docker-compose.yml eine eigenständigen Stack mitzuliefern.
Irgendwann war doch mal Effizienz ein Thema? Aber nun soll man 8 Installationen parallel betreiben o_0

docker-compose.yml

version: '3'

services:
  cloud:
    build: .
    restart: unless-stopped
    mem_limit: 4096m
    mem_reservation: 2048M
    cpus: 4.0
    volumes:
      - /mnt/docker/volumes/nextcloud:/var/www/html
      - /mnt/docker/volumes/nextcloud-tmp:/var/tmp
    networks:
      - proxy
      - core_redis
      - core_postgres

networks:
  proxy:
    external:
      true
  core_redis:
    external:
      true
  core_postgres:
    external:
      true

Je nach Konfiguration des Servers kann es nötig sein, das Tmp-Verzeichnis extern zu mappen. Ansonsten könnte es zu Problemen kommen, falls du über (rclone) riesige Dateien hochlädst, welche die Größe der Tmp-Partition sprengen. Außerdem habe ich drei verschiedene Netzwerke für die Anbindung des Reverse Proxys, PostgreSQL und Redis verknüpft.

Ausführen lässt sich das ganze zum Abschluss so

# Docker Image erstellen
docker-compose build
# Docker Container anhand unserer docker-compose.yml erstellen, starten und eventuelle Reste einer vorherigen Installation entfernen
docker-compose up -d --force-recreate --remove-orphans

NGINX Reverse Proxy

Falls du als Reverse Proxy einsetzt, bitte unbedingt darauf achten, dass folgende Konfiguration enthalten ist oder auf eure Einsatzumgebung angepasst wurde

proxy_buffering off;
client_max_body_size 0;

Konfiguration

Vervollständigt ergibt sich folgende Konfiguration

Dockerfile

FROM ubuntu/apache2:2.4-22.04_beta

ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Europe/Berlin
RUN apt-get update && apt-get upgrade -y && apt-get install -y libtidy-dev apache2 libapache2-mod-php php-curl php-mbstring php-intl php-gmp php-bcmath php-imagick php-xml php-zip php-gd wget openssl php-common php-curl php-json php-xml php-zip php-dom php-xsl php-pgsql php-apcu php-bz2 php-dompdf php-redis ffmpeg curl php-simplexml php-iconv php-ctype libxml2 php-posix php-fileinfo
RUN sed -i 's/memory_limit = 128M/memory_limit = 4096M/g' /etc/php/8.1/apache2/php.ini
RUN sed -i 's/output_buffering = 4096/output_buffering = off/g'  /etc/php/8.1/apache2/php.ini
COPY ./nextcloud.conf /etc/apache2/sites-available/nextcloud.conf
COPY ./custom.config.php /var/www/html/config/custom.config.php
COPY ./custom.ini /etc/php/8.1/mods-available/custom.ini
RUN phpenmod -s cli custom
RUN phpenmod -s apache2 custom
RUN a2ensite nextcloud.conf
RUN a2dissite 000-default
RUN a2enmod rewrite
RUN a2enmod headers
RUN a2enmod env
RUN a2enmod dir
RUN a2enmod mime
RUN mkdir -pv /var/www/html
WORKDIR /var/www/html
RUN wget https://download.nextcloud.com/server/installer/setup-nextcloud.php -O /var/www/html/setup-nextcloud.php
RUN chown www-data:www-data -R /var/www
RUN runuser -u www-data -- php -v

nextcloud.conf


  DocumentRoot /var/www/html/
  ServerName  nextcloud.exmaple.com

  ErrorLog /dev/stderr
  TransferLog /dev/stdout

  
    Require all granted
    AllowOverride All
    Options FollowSymLinks MultiViews

    
      Dav off
    
  

custom.config.php

$CONFIG = array (
        'memcache.local' => '\OC\Memcache\APCu',
        'memcache.distributed' => '\OC\Memcache\Redis',
        'redis' => [
             'host' => 'redis',
             'port' => 6379,
        ],
        'memcache.locking' => '\OC\Memcache\Redis',
        'enable_previews' => true,
        'enabledPreviewProviders' =>
        array (
            1 => 'OC\\Preview\\PNG',
            2 => 'OC\\Preview\\JPEG',
            3 => 'OC\\Preview\\GIF',
            4 => 'OC\\Preview\\BMP',
            5 => 'OC\\Preview\\XBitmap',
            6 => 'OC\\Preview\\MP3',
            7 => 'OC\\Preview\\MP4',
            8 => 'OC\\Preview\\TXT',
            9 => 'OC\\Preview\\MarkDown',
            12 => 'OC\\Preview\\Image',
        ),
);

custom.ini

; priority=50
extension=redis

apc.enabled=1
apc.enable_cli=1

opcache.save_comments = 1
opcache.revalidate_freq = 60
opcache.interned_strings_buffer = 64

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert