Dieses Tutorial ist VALID.

Bitte lies Dir den Disclaimer durch, bevor Du eine Anleitung umsetzt...

Haftungsausschluss / Disclaimer

Nextcloud Docker Image erstellen

Warum bauen wir ein eigenes Image für Nextcloud?

Nextcloud ist eine Cloud-Server Anwendung, mit der wir Dateien zwischen unseren Systemen synchronisieren können. Natürlich dürfen wir auch Freigaben anlegen und Links verschicken, damit unsere Freunde oder Kollegen Zugriff auf hochgeladene Dateien bekommen.

Nextcloud ist eine sehr pfiffige Alternative zu beispielsweise Dropbox, Google Drive und ähnlichen Diensten. Weil wir die Daten auf unserem eigenen Server hosten haben wir etwas mehr Privatsphäre. Wir sind der Herr unserer Daten!

Für Nextcloud erstellen wir ein eigenes Image, dass wir dann im nächsten Kapitel in einem Container starten. Packen wir’s an :)

Update 03.10.’19

Das Tutorial hab ich auf Version 17.0.0 von Nextlcoud angepasst und dabei den „msmtp-Install“-Block oben in den persistenten Teil des Dockerfiles gezogen…

Verzeichnisse anlegen und Config-Dateien laden

Wie legen unterhalb von „/root/docker“ ein Verzeichnis „nextcloud-php73-apache“ an, in dem wir die Config-Dateien und das „Dockerfile“ herunterladen bzw. erstellen. Das „Dockerfile“ ist die Steuerdatei, in der Instruktionen stehen, wie das Image „gebaut“ werden soll.

Die meisten Docker Images gibt es in verschiedenen Ausführungen. Beispielsweise mit php 7.1, 7.2 oder 7.3. Oder dem Webserver apache oder fpm. Damit wir auf den ersten Blick sehen, welches Image wir bauen möchten, gebe ich diese Bezeichnungen mit in den Verzeichnisnamen. Sollte einmal php 7.4 herauskommen, legen wir dafür ein neues Verzeichnis an und sind in der Lage, zwei Images parallel zu erstellen, bis wir sicher sind, dass die neue php 7.4 Version auch vernünftig funktioniert…

Achtung: die „wget“ Befehlszeilen sind sehr lang und erstrecken sich hier über mehrere Zeilen. Diese sind aber bitte komplett per Copy/Paste kopieren und im Terminal jeweils in einer einzigen Kommandozeile auszuführen…

Im Unterverzeichnis „config“ sammeln wir ein paar Config-Dateien für Serverdienste, die im Nextcloud Container laufen werden.

Die „entrypoint.sh“ und „cron.sh“ Dateien müssen wir noch „ausführbar“ machen, also „+x“ für „executable“. Da dies die einzigen beiden „.sh“-Dateien sind, stellen wir einfach alle „.sh“-Datein mit „*.sh“ auf +x…

mkdir -p ~/docker/nextcloud-php73-apache/config

$ wget -q -P ~/docker/nextcloud-php73-apache/config https://raw.githubusercontent.com/nextcloud/docker/master/17.0/apache/config/apache-pretty-urls.config.php https://raw.githubusercontent.com/nextcloud/docker/master/17.0/apache/config/apcu.config.php https://raw.githubusercontent.com/nextcloud/docker/master/17.0/apache/config/apps.config.php https://raw.githubusercontent.com/nextcloud/docker/master/17.0/apache/config/autoconfig.php https://raw.githubusercontent.com/nextcloud/docker/master/17.0/apache/config/redis.config.php https://raw.githubusercontent.com/nextcloud/docker/master/17.0/apache/config/smtp.config.php

$ wget -q -P ~/docker/nextcloud-php73-apache https://raw.githubusercontent.com/nextcloud/docker/master/17.0/apache/cron.sh https://raw.githubusercontent.com/nextcloud/docker/master/17.0/apache/entrypoint.sh https://raw.githubusercontent.com/nextcloud/docker/master/17.0/apache/upgrade.exclude

chmod +x ~/docker/nextcloud-php73-apache/*.sh

Dies waren die Vorbereitungen. Jetzt erstellen wir das „Dockerfile“, die Steuerdatei für den Zusammenbau des Images.

Nicht erschrecken: Das Ding ist ziemlich umfangreich und „erschlägt“ einen gerne, wenn man es zum ersten Mal sieht. Zerlegt in seine Einzelbestandteile ist das Konstrukt aber verdammt logisch und nimmt dem Ganzen seinen Schrecken…

Und bis auf einige wenige Änderungen ist diese Datei auch 1:1 vom originalen Dockerfile übernommen worden.

nano ~/docker/nextcloud-php73-apache/Dockerfile
### NEXTCLOUD DOCKERFILE
###
##START
FROM php:7.3-apache-buster

# entrypoint.sh and cron.sh dependencies - persistant!
RUN set -ex; \
    \
    apt-get update; \
    apt-get install -y --no-install-recommends \
        rsync \
        bzip2 \
        busybox-static \
### msmtp Installation
        msmtp \
        msmtp-mta \
        bsd-mailx \
        mailutils \
    ; \
    rm -rf /var/lib/apt/lists/*; \
    \
    mkdir -p /var/spool/cron/crontabs; \
    echo '*/15 * * * * php -f /var/www/html/cron.php' > /var/spool/cron/crontabs/www-data

# install the PHP extensions we need
# see https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html
RUN set -ex; \
    \
    savedAptMark="$(apt-mark showmanual)"; \
    \
    apt-get update; \
    apt-get install -y --no-install-recommends \
        libcurl4-openssl-dev \
        libevent-dev \
        libfreetype6-dev \
        libicu-dev \
        libjpeg-dev \
        libldap2-dev \
        libmcrypt-dev \
        libmemcached-dev \
        libpng-dev \
        libpq-dev \
        libxml2-dev \
        libmagickwand-dev \
        libzip-dev \
        libwebp-dev \
    ; \
    \
    debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
    docker-php-ext-configure gd --with-freetype-dir=/usr --with-png-dir=/usr --with-jpeg-dir=/usr --with-webp-dir=/usr; \
    docker-php-ext-configure ldap --with-libdir="lib/$debMultiarch"; \
    docker-php-ext-install -j "$(nproc)" \
        exif \
        gd \
        intl \
        ldap \
        opcache \
        pcntl \
        pdo_mysql \
        pdo_pgsql \
        zip \
    ; \
    \
# pecl will claim success even if one install fails, so we need to perform each install separately
    pecl install APCu; \
    pecl install memcached; \
    pecl install redis; \
    pecl install imagick; \
    \
    docker-php-ext-enable \
        apcu \
        memcached \
        redis \
        imagick \
    ; \
    \
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
    apt-mark auto '.*' > /dev/null; \
    apt-mark manual $savedAptMark; \
    ldd "$(php -r 'echo ini_get("extension_dir");')"/*.so \
        | awk '/=>/ { print $3 }' \
        | sort -u \
        | xargs -r dpkg-query -S \
        | cut -d: -f1 \
        | sort -u \
        | xargs -rt apt-mark manual; \
    \
    apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
    rm -rf /var/lib/apt/lists/*

# set recommended PHP.ini settings
# see https://docs.nextcloud.com/server/12/admin_manual/configuration_server/server_tuning.html#enable-php-opcache
RUN { \
        echo 'opcache.enable=1'; \
        echo 'opcache.interned_strings_buffer=8'; \
        echo 'opcache.max_accelerated_files=50000'; \
        echo 'opcache.memory_consumption=128'; \
        echo 'opcache.save_comments=1'; \
        echo 'opcache.revalidate_freq=1'; \
    } > /usr/local/etc/php/conf.d/opcache-recommended.ini
#
## File Upload auf 4G und Memory-Limits auf 1024M hochschieben. PHP Execution Timeout auf 60m (3600s)
RUN     { \
        echo 'file_uploads = On'; \
        echo 'upload_max_filesize = 4G'; \
        echo 'post_max_size = 4G'; \
        echo 'memory_limit = 1024M'; \
        echo 'max_execution_time = 3600'; \
        echo 'default_socket_timeout = 3600'; \
        } > /usr/local/etc/php/conf.d/upload-limits.ini; \
    \
    echo 'apc.enable_cli=1' >> /usr/local/etc/php/conf.d/docker-php-ext-apcu.ini; \
    \
    mkdir /var/www/data; \
    chown -R www-data:root /var/www; \
    chmod -R g=u /var/www

VOLUME /var/www/html

RUN a2enmod rewrite remoteip headers;\
    {\
        echo RemoteIPHeader X-Real-IP ;\
        echo RemoteIPTrustedProxy 10.0.0.0/8 ;\
        echo RemoteIPTrustedProxy 172.16.0.0/12 ;\
        echo RemoteIPTrustedProxy 192.168.0.0/16 ;\
    } > /etc/apache2/conf-available/remoteip.conf;\
    a2enconf remoteip

ENV NEXTCLOUD_VERSION 17.0.0

RUN set -ex; \
    fetchDeps=" \
        gnupg \
        dirmngr \
    "; \
    apt-get update; \
    apt-get install -y --no-install-recommends $fetchDeps; \
    \
    curl -fsSL -o nextcloud.tar.bz2 \
        "https://download.nextcloud.com/server/releases/nextcloud-${NEXTCLOUD_VERSION}.tar.bz2"; \
    curl -fsSL -o nextcloud.tar.bz2.asc \
        "https://download.nextcloud.com/server/releases/nextcloud-${NEXTCLOUD_VERSION}.tar.bz2.asc"; \
    export GNUPGHOME="$(mktemp -d)"; \
# gpg key from https://nextcloud.com/nextcloud.asc
    gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \
    gpg --batch --verify nextcloud.tar.bz2.asc nextcloud.tar.bz2; \
    tar -xjf nextcloud.tar.bz2 -C /usr/src/; \
    gpgconf --kill all; \
    rm -r "$GNUPGHOME" nextcloud.tar.bz2.asc nextcloud.tar.bz2; \
    rm -rf /usr/src/nextcloud/updater; \
    mkdir -p /usr/src/nextcloud/data; \
    mkdir -p /usr/src/nextcloud/custom_apps; \
    chmod +x /usr/src/nextcloud/occ; \
    \
    apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $fetchDeps; \
    rm -rf /var/lib/apt/lists/*

### msmtp CONFIG Block
## "sendmail"-Pfad auf "ssmtp" umbiegen
RUN    { \
        echo 'sendmail_path = /usr/bin/msmtp -t -C /etc/msmtprc'; \
    } > /usr/local/etc/php/conf.d/sendmail.ini
## msmtp und SMTP-Postfach konfigurieren
RUN { \
        echo '# Set defaults.'; \
        echo 'defaults'; \
        echo 'logfile /var/log/msmtp.log'; \
        echo '# Enable or disable TLS/SSL encryption.'; \
        echo 'tls on'; \
        echo 'tls_starttls on'; \
        echo 'tls_certcheck off'; \
        echo '# Setup mail to send emails via SMTP'; \
        echo 'account mail'; \
        echo 'host mein.mailserver.de'; \
        echo 'port 587'; \
        echo 'auth login'; \
        echo 'user mail@mein.mailserver.de'; \
        echo 'from mail@mein.mailserver.de'; \
        echo 'password supergeheimesmailpasswort'; \
        echo '# Set a default account'; \
        echo 'account default : mail'; \
} > /etc/msmtprc \
&& chmod 600 /etc/msmtprc && chown www-data:www-data /etc/msmtprc

COPY *.sh upgrade.exclude /
COPY config/* /usr/src/nextcloud/config/

ENTRYPOINT ["/entrypoint.sh"]
CMD ["apache2-foreground"]
##EOF

Puh, was für ein Brummer ^^

Schauen wir uns die Blöcke mal genauer an:

Zeile 4: Das Grundlegende Image, auf dem unser Nextcloud-Image aufbaut, ist das „php:7.3-apache-buster“. Also ein Debian-10 Image mit Apache und PHP in Version 7.3. Dieses Image wird zuerst geladen. Alle folgenden Instruktionen im Dockerfile erweitern dieses Image dann um die jeweiligen Funktionen und Programme, bis am Schluss unser fertig modifiziertes Nextcloud Image dabei heraus kommt.

Zeilen 6-13: Es werden „rsync“, „bzip2“ und „busybox-static“ nachinstalliert.

Zeilen 15-20: Hier installieren wir msmtp mit seinen Hilfsprogrammen, damit wir später direkt aus Nextcloud heraus Mails verschicken können. Anschließend, um Platz zu sparen, wird die apt-Liste gelöscht.

Zeilen 22+23: Oh, das hab ich bis jetzt übersehen… Was für eine clevere Lösung, dem Image einen Cron-Automatismus einzupflanzen!
Ich teste das gerade parallel mit dem WordPress Image… Wenn das funktioniert, werde ich diese Funktion dort auch benutzen. Der Grund dafür ist, dass bei diesen komplexen Anwendungen auch Hintergrundprozesse ausgeführt werden müssen. Wie zum Beispiel das „Leeren des Papierkorbs“. Da kümmert sich ein Script darum, das aber irgendwie „angestoßen“ werden muss. Und das ist bei Nextcloud offenbar das selbe Problem wie bei WordPress: Sind nur wenige, vereinzelte Zugriffe von außen auf die Anwendung, ist dieses Verfahren sehr unzuverlässig. Darum löst man das Dilemma hier über einen Cronjob, der automatisch alle 15 Minuten intern über das „Betriebssystem“ des Containers mittels php dieses Cron-Script aufruft und damit die Verarbeitung anstößt. Wie gesagt, sehr pfiffig. Da muss man auch erst drauf kommen…
Nachtrag: Nein, ist sie nicht :/

Zeilen 25-47: Hier werden Bibliotheken für diverse Hilfsprogramme nachgeladen. Anhand des Namens kannst Du schön erkennen, wofür die jeweils gut sind.

Zeilen 49-62: Jetzt werden eine Reihe von PHP-Erweiterungen geladen und installiert.

Zeilen 64-75: Über pecl (php extension community library) werden noch vier Ergänzungen zur PHP-Umgebung installiert. Die sind für Caching und Bild-Manipulation zuständig.
Änderung gegenüber Original: Hier habe ich die Versionsnummern entfernt. Es wird also immer die aktuellste Version gezogen.

Zeilen 77-89: Die nicht mehr benötigten Hilfsprogramme werden, um Platz zu sparen, wieder entfernt. Diese waren nur zur Installation der PHP-Module nötig.

Zeilen 91-100: Das „opcache“ Modul wird konfiguriert.

Zeilen 102-110: Diese Ergänzung fügen wir jetzt ein: Wir erhöhen die Limits für die maximale Dateigröße auf 4 GB, das Memory Limit auf 1 GB und die maximale Ausführungszeit (große Dateien brauchen auch länger zum Hochladen!) auf eine Stunde (3600 Sekunden).

Zeile 112: Das „APC User Cache“ Modul wird aktiviert.

Zeilen 114-116: Das Verzeichnis „/var/www/data“ wird angelegt und vorbereitet.

Zeile 118: Das Volume „/var/www/html“ wird der Docker-Engine zur Verarbeitung übergeben.

Zeilen 120-127: Die Apache Module „rewrite“, „remoteip“ und „headers“ werden aktiviert. Das „headers“ Modul fügen wir hinzu, das ist normalerweise aus. Brauchen wir aber, weil wir später mit Traefik zusätzliche Header hinzufügen möchten.
Das „remoteip“ Modul tauscht die IP von unserem Reverse-Proxy gegen die „echte“ IP des Besuchers aus. Dazu werden unsere eigenen Docker- und lokalen Netzwerke deklariert und in einer Config-Datei gespeichert. Anschließend wird das Modul neu konfiguriert.

Zeile 129: Die Version von Nextcloud, die anschließend geladen soll, wird hier eingestellt. Sollte es eine neuere Version von Nextcloud geben, müssen wir die Versionsnummer an dieser Stelle anpassen und dann das Image erneut bauen.

Zeilen 131-156: Nextcloud wird jetzt aus den offiziellen Quellen heruntergeladen und in unser Image entpackt. Anschließend werden die Installationsdateien und nicht mehr benötigte Hilfsprogramme entfernt.

Zeilen 158-183: Für das von uns eingefügte Setup von „msmtp“ (Mailversand) erzeugen wir eine Config-Datei dafür. Diese Zeilen musst Du an Deine Installation anpassen:
Zeile 174: Der Hostname von Deinem Mailserver, auf dem Du das Mailkonto für den Versand angelegt hast.
Zeilen 177+178: Hier gehört zwei Mal die volle E-Mail Adresse von Deinem Mailkonto eingetragen.
Zeile 179: Das Passwort des Mailaccounts, damit die Mails auch verschickt werden können. Die Anweisung ‚password‘ bleibt stehen, Du ersetzt nur „supergeheimesmailpasswort“ durch Dein eigenes Mail Passwort…

Zeilen 185-189: Das Image wird noch um ein paar Dateien ergänzt, die wir ganz am Anfang per „wget“ heruntergeladen haben. Der Entrypoint wird gesetzt und zum Abschluss kommt der Befehl, der Apache hochlaufen lässt, wenn wir den Container starten.

Image bauen

Damit ist das „Dockerfile“ fertig und wir starten den „Bauprozess“:

„docker build“ weist Docker an, aus einem Dockerfile heraus ein Image zu bauen. „-t“ ist der „Tag“, also die Bezeichnung von dem Image. Hier nenne ich das Image wie auch das Verzeichnis nach der Anwendung, der php-Version und dem verwendeten Webserver. Ein Doppelpunkt grenzt den Namen von der Versionsnummer ab. Wie wir im Dockerfile gesehen haben, ist dies hier die Version 17.0.0 von Nextcloud. Als Parameter wird im Anschluss der Ordner übergeben, in dem sich das Dockerfile befindet.

docker build -t nextcloud-php73-apache:17.0.0 ~/docker/nextcloud-php73-apache

Was jetzt kommt mutet an wie die Bildschirmausgabe im Kommandobunker von einem Kriegsfilm: Wilde verkettete Befehle, Zeilensprünge, „wirre“ Kommandos, die abgearbeitet werden…

Das alles ist beim ersten Mal sehr erschreckend, aber völlig normal. Hier laufen nun die „build“-Prozesse der Reihe nach durch. Hin und wieder erkennen wir sogar einen der Befehle aus dem Dockerfile.

Das Ganze dauert runde sechs Minuten, wobei das stark vom verwendeten Server abhängt. Am Schluss schreibt uns Docker die erlösenden Zeilen:

Successfully built acdf946bd7d2
Successfully tagged nextcloud-php73-apache:17.0.0

Glückwunsch! Das Image ist jetzt fertig!

Wir taggen das Image jetzt noch einmal und geben Docker quasi eine „Weiterleitung“ mit dem „:latest“ Tag, das wir mit der gerade gebauten Version 17.0.0 verknüpfen:

docker tag nextcloud-php73-apache:17.0.0 nextcloud-php73-apache:latest

Damit sind wir in der Lage, anschließend das Image im Container mit „:latest“ zu deklarieren. Sollte Version 17.0.1 kommen und wir ein neues Image gebaut haben, brauchen wir das nur noch mit „:latest“ zu taggen. Der Container wird beim nächsten Start dann das neue Image benutzen. Wir sparen uns quasi das ständige Ändern der Versionsnummern in unseren „docker-compose“-Dateien…

Im nächsten Kapitel werden wir die „docker-compose“-Datei für Nextcloud definieren und dort gleich unser frisch gebackenes Image verwenden!

Anzeige *

Kommentar verfassen

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

Verwendung
von Cookies

Um unsere Webseite für Sie optimal zu gestalten und fortlaufend verbessern zu können, verwenden wir Cookies. Durch die weitere Nutzung der Webseite stimmen Sie der Verwendung von Cookies zu. Weitere Informationen zu Cookies erhalten Sie in unserer Datenschutzerklärung.

Scroll to Top