Nextcloud im Proxmox LXC auf Debian 10 mit PHP-FPM und externer MySQL Datenbank hinter einen Reverse Proxy installieren

Hallo!

Heute beschäftige ich mich mit der Installation von Nextcloud in einem Proxmox LXC Container. Wir frühstücken das ganze aber in einer besonderen Konstellation ab. Bedeutet kurz und knapp wir installieren das ganze unter Debian 10 mit PHP-FPM hinter einem Nginx Reverse Proxy und einer seperaten MySQL Datenbank. In diesem Fall wird der Reverse Proxy das SSL Zertifikat besitzen und die Anfragen an die Cloud im internen Netz unverschlüsselt weiter zu reichen.

Was ihr dazu benötigt:

Wir verbinden uns als root per SSH auf den Container. Dann führen wir ein Upgrade durch und installieren grundlegende Pakete.

apt update && apt upgrade -y
apt install htop sudo net-tools unzip software-properties-common curl git lsb-release ca-certificates apt-transport-https locate screen zip bzip2 gnupg2 -y

Anschließend wechseln wir in das sources Verzeichnis und fügen alternative und vorallem aktuellere Repos dem System hinzu. So können wir sicherstellen, dass unsere Cloud mit den aktuellsten Sicherheitspatches versorgt wird. Dazu gehört PHP und Apache2. Im Normalfall würde ich noch MySQL hinzufügen, da die Datenbank in einem seperaten Container läuft, fällt dies weg.

cd /etc/apt/sources.list.d/
echo "deb [arch=amd64] https://packages.sury.org/php/ $(lsb_release -cs) main" | tee php.list
echo "deb [arch=amd64] https://packages.sury.org/apache2/ $(lsb_release -cs) main" | tee apache2.list

Nun müssen wir dem System noch klar machen, dass die hinzugefügten Repos als sicher zu bewerten sind. Dies erledigen wir indem wir die Sicherheitsschüssel der jeweiligen Repo herunterladen und installieren.

wget -q https://packages.sury.org/php/apt.gpg -O- | apt-key add -
wget -q https://packages.sury.org/apache2/apt.gpg -O- | apt-key add -

Nachdem wir die Repos hinzugefügt haben aktualisieren wir die Paketlisten und upgraden vorhandene Pakete.

apt update && apt upgrade -y

Solltet ihr den LXC Container mithilfe meines Guides erstellt und konfiguriert haben, fällt dieser Step weg. Alle anderen. Ufpasse! Wir konfigurieren die Timezone und Locales des Systems.

dpkg-reconfigure tzdata 
Europe -> Berlin

dpkg-reconfigure locales
de_DE.UTF8 UTF8 -> de_DE.UTF8

Solltet ihr den LXC Container mithilfe meines Guides erstellt und konfiguriert haben, fällt dieser Step weg. Alle anderen. Ufpasse! Wir legen einen User an, erteilen ihm sudo Rechte und wechseln auf den erstellten User.

adduser username
nano /etc/sudoers

# User privilege specification
root    ALL=(ALL:ALL) ALL
username ALL=(ALL:ALL) ALL

su username

Als nächstes installieren wir Webserver Apache2.

sudo apt install apache2 apache2-utils

Anschließend installieren wir Redis und konfigurieren den Server. Redis nutzen wir zu besseren caching und memlocken.

sudo apt install redis
sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.bak
sudo sed -i "s/port 6379/port 0/" /etc/redis/redis.conf
sudo sed -i s/\#\ unixsocket/\unixsocket/g /etc/redis/redis.conf
sudo sed -i "s/unixsocketperm 700/unixsocketperm 770/" /etc/redis/redis.conf
sudo sed -i "s/# maxclients 10000/maxclients 512/" /etc/redis/redis.conf

Damit der Webserver User www-data auch Redis nutzen darf müssen wir ihm die Berechtigung dazu erteilen.

sudo usermod -aG redis www-data

Nun kommt der Löwenteil der Installation. Die Rede ist von PHP7.4. Wir starten mit dem Installieren.

sudo apt install php7.4-cli php7.4-common php7.4-fpm libapache2-mod-php7.4 php7.4-gd php7.4-mysql php7.4-curl php7.4-xml php7.4-zip php7.4-intl php7.4-mbstring php7.4-json php7.4-bz2 php7.4-ldap php-apcu php7.4-bcmath php7.4-gmp imagemagick php-imagick php-smbclient ldap-utils -y

Damit wir im Fehlerfall noch ein Backup der Configdatei haben erstellen wir nun erst von jeder Config eines.

sudo cp /etc/php/7.4/fpm/pool.d/www.conf /etc/php/7.4/fpm/pool.d/www.conf.bak
sudo cp /etc/php/7.4/cli/php.ini /etc/php/7.4/cli/php.ini.bak
sudo cp /etc/php/7.4/fpm/php.ini /etc/php/7.4/fpm/php.ini.bak
sudo cp /etc/php/7.4/fpm/php-fpm.conf /etc/php/7.4/fpm/php-fpm.conf.bak
sudo cp /etc/ImageMagick-6/policy.xml /etc/ImageMagick-6/policy.xml.bak

Jetzt kommt das was ich persönlich HASSE wenn ich eine Cloud für Testzwecke aufsetze. Ich spreche von den Optimierungen und Einstellungen innerhalb der PHP Configs. Ich wünsche euch viel Spaß! 🙂

sudo sed -i "s/;env\[HOSTNAME\] = /env[HOSTNAME] = /" /etc/php/7.4/fpm/pool.d/www.conf
sudo sed -i "s/;env\[TMP\] = /env[TMP] = /" /etc/php/7.4/fpm/pool.d/www.conf
sudo sed -i "s/;env\[TMPDIR\] = /env[TMPDIR] = /" /etc/php/7.4/fpm/pool.d/www.conf
sudo sed -i "s/;env\[TEMP\] = /env[TEMP] = /" /etc/php/7.4/fpm/pool.d/www.conf
sudo sed -i "s/;env\[PATH\] = /env[PATH] = /" /etc/php/7.4/fpm/pool.d/www.conf
sudo sed -i "s/pm.max_children =.*/pm.max_children = 120/" /etc/php/7.4/fpm/pool.d/www.conf
sudo sed -i "s/pm.start_servers =.*/pm.start_servers = 12/" /etc/php/7.4/fpm/pool.d/www.conf
sudo sed -i "s/pm.min_spare_servers =.*/pm.min_spare_servers = 6/" /etc/php/7.4/fpm/pool.d/www.conf
sudo sed -i "s/pm.max_spare_servers =.*/pm.max_spare_servers = 18/" /etc/php/7.4/fpm/pool.d/www.conf
sudo sed -i "s/;pm.max_requests =.*/pm.max_requests = 1000/" /etc/php/7.4/fpm/pool.d/www.conf

sudo sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/7.4/cli/php.ini
sudo sed -i "s/max_execution_time =.*/max_execution_time = 3600/" /etc/php/7.4/cli/php.ini
sudo sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/7.4/cli/php.ini
sudo sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/7.4/cli/php.ini
sudo sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/7.4/cli/php.ini
sudo sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/7.4/cli/php.ini
 
sudo sed -i "s/memory_limit = 128M/memory_limit = 1024M/" /etc/php/7.4/fpm/php.ini
sudo sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/7.4/fpm/php.ini 
sudo sed -i "s/max_execution_time =.*/max_execution_time = 3600/" /etc/php/7.4/fpm/php.ini
sudo sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/7.4/fpm/php.ini
sudo sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/7.4/fpm/php.ini
sudo sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/7.4/fpm/php.ini
sudo sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/7.4/fpm/php.ini
sudo sed -i "s/;session.cookie_secure.*/session.cookie_secure = True/" /etc/php/7.4/fpm/php.ini
sudo sed -i "s/;opcache.enable=.*/opcache.enable=1/" /etc/php/7.4/fpm/php.ini
sudo sed -i "s/;opcache.enable_cli=.*/opcache.enable_cli=1/" /etc/php/7.4/fpm/php.ini
sudo sed -i "s/;opcache.memory_consumption=.*/opcache.memory_consumption=128/" /etc/php/7.4/fpm/php.ini
sudo sed -i "s/;opcache.max_accelerated_files=.*/opcache.max_accelerated_files=10000/" /etc/php/7.4/fpm/php.ini
sudo sed -i "s/;opcache.revalidate_freq=.*/opcache.revalidate_freq=1/" /etc/php/7.4/fpm/php.ini
sudo sed -i "s/;opcache.save_comments=.*/opcache.save_comments=1/" /etc/php/7.4/fpm/php.ini
 
sudo sed -i '$aapc.enable_cli=1' /etc/php/7.4/mods-available/apcu.ini
 
sudo sed -i "s/rights=\"none\" pattern=\"PS\"/rights=\"read|write\" pattern=\"PS\"/" /etc/ImageMagick-6/policy.xml
sudo sed -i "s/rights=\"none\" pattern=\"EPS\"/rights=\"read|write\" pattern=\"EPS\"/" /etc/ImageMagick-6/policy.xml
sudo sed -i "s/rights=\"none\" pattern=\"PDF\"/rights=\"read|write\" pattern=\"PDF\"/" /etc/ImageMagick-6/policy.xml
sudo sed -i "s/rights=\"none\" pattern=\"XPS\"/rights=\"read|write\" pattern=\"XPS\"/" /etc/ImageMagick-6/policy.xml

Na wie schauts mit der Motivation aus? 😛 Da wir PHP-FPM nutzen wollen müssen wir die normale CLI für Apache2 deaktivieren.

sudo a2dismod php7.4 mpm_prefork

Nun aktivieren wir PHP-FPM.

sudo a2enconf php7.4-fpm

Wir aktivieren relevante Module für Apache2. Damit die ersten Änderungen wirksam werden starten wir Apache2 neu.

sudo a2enmod proxy_fcgi setenvif mpm_event rewrite headers env dir mime ssl http2
sudo systemctl restart apache2

Anschließend legen wir die vHost Datei für Apache2 an.

sudo nano /etc/apache2/sites-available/nextcloud.conf

<VirtualHost *:80>
     ServerAdmin admin@domain.tld
     DocumentRoot /var/www/nextcloud/
     ServerName subdomain.domain.tld
     #ServerAlias 192.168.xxx.xxx
 
     #Alias /nextcloud "/var/www/nextcloud/"
     #Fix für __Host-prefix

     <Directory /var/www/nextcloud/>
        Options FollowSymlinks MultiViews
        AllowOverride All
        Require all granted
          <IfModule mod_dav.c>
            Dav off
          </IfModule>
        SetEnv HOME /var/www/nextcloud
        SetEnv HTTP_HOME /var/www/nextcloud
     </Directory>
 
     ErrorLog ${APACHE_LOG_DIR}/error.log
     CustomLog ${APACHE_LOG_DIR}/access.log combined
 
RewriteEngine on
</VirtualHost>

Ist dieser Step erledigt aktivieren wir die eben angelegte vHost Datei. Danach deaktivieren wir die vHost Default und starten neu.

sudo a2ensite nextcloud.conf
sudo a2dissite 000-default.conf
sudo systemctl restart apache2

Wir laden als nächstes Nextcloud herunter und kopieren den Inhalt der ZIP Datei in das Webverzeichnis unter /var/www/nextcloud.

cd /tmp && wget https://download.nextcloud.com/server/releases/latest.zip
sudo unzip latest.zip && sudo mv nextcloud /var/www/
sudo rm latest.zip

Nun legen wir einige Verzeichnisse an. Damit Nextcloud die Daten, die sich in der Cloud befinden, nicht im Webverzeichnis speichert, müssen wir den Speicherort verlagern. Ich persönlich mounte dafür ein ZFS Share in den Container. So sind alle Daten unabhängig von der Cloud, selbst wenn die Cloud mal ausfällt oder der LXC sich ins Nirvana verabschiedet. Damit alle User die erstellt werden ein „leeres“ Nutzerverzeichnis besitzen und von diesem „Default Nextcloud Intro Schrott“ verschont bleiben, legen wir ein sogenanntes Skelleton Verzeichnis an. Hier können auch Daten gespeichert werden die jeder neu erstellte Nutzer bereitgestellt bekommen soll. Da der User www-data Zugriff auf diese Verzeichnisse haben muss erteilen wir ihm die Berechtigung.

sudo mkdir /data
sudo mkdir /data/nextcloud
sudo mkdir /data/nextcloud/skeleton
sudo chown -R www-data:www-data /data/nextcloud

Damit das Log sammeln übersichtlicher wird legen wir ein für die Cloud eigenes Verzeichnis an. Auch hier müssen wir Besitzerrechte erteilen.

sudo mkdir /var/log/nextcloud
sudo chown -R www-data:www-data /var/log/nextcloud

Nextcloud benötigt obendrein noch eine PHP Config in der wir diverse Settings setzen müssen.

sudo nano /var/www/nextcloud/config/config.php

<?php
$CONFIG = array (
  'trusted_domains' => 
  array (
    0 => 'localhost',
    1 => 'subdomain.domain.tld',
    2 => '192.168.XXX.XXX',
  ),
  'trusted_proxies' => 
  array (
    0 => '192.168.XXX.XXX',
  ),
  'log_type' => 'file',
  'logtimezone' => 'Europe/Berlin',
  'loglevel' => 2,
  'logfile' => '/var/log/nextcloud/nextcloud.log',
  'datadirectory' => '/data/nextcloud/',
  'skeletondirectory' => '/data/nextcloud/skeleton',
  'filelocking.enabled' => 'true',
  'memcache.locking' => '\\OC\\Memcache\\Redis',
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'redis' => 
  array (
    'host' => '/var/run/redis/redis-server.sock',
    'port' => 0,
    'timeout' => 1.5,
  ),
  'default_language' => 'de',
  'default_locale' => 'de_DE',
  'default_phone_region' => 'DE',
  'trashbin_retention_obligation' => '15, 30',
  'updater.release.channel' => 'stable',
  'overwrite.cli.url' => 'https://subdomain.domain.tld/',
  'overwriteprotocol' => 'https',
  'htaccess.RewriteBase' => '/',
);

Der User www-data benötigt auch im /var/www/nextcloud Verzeichnis Berechtigung.

sudo chown -R www-data:www-data /var/www/nextcloud

Danach führen wir einen Restart der Dienste durch.

sudo systemctl restart apache2
sudo systemctl restart php7.4-fpm
sudo systemctl restart redis

Tada! Wir können die Cloud über ihre IP ansteuern und bekommen den Setup Wizard vor die Nase gesetzt. Wir tragen im ersten Punkt einen Adminnutzer mit Passwort ein. Als nächstes geben wir das vorher angelegte Datenverzeichnis an. Nun tragen wir den MySQL Nutzer mit Passwort und dazu gehörigen Datenbanknamen ein. Localhost ersetzen wir mit der IP des MySQL Server. Im letzten Step klicken wir auf Installation abschließen.

Nun öffnen wir erneut unseren SSH Tunnel und aktualisieren die .htaccess Datei für die Cloud.

sudo -u www-data php /var/www/nextcloud/occ maintenance:update:htaccess

Nun führen wir einen letzten Restart der Services durch.

sudo systemctl restart apache2
sudo systemctl restart php7.4-fpm
sudo systemctl restart redis

Damit die Cloud nicht per AJAX aktualisiert wird sondern per CRON müssen wir einen Cronjob für den User www-data anlegen.

sudo crontab -u www-data -e

*/5  *  *  *  * php -f /var/www/nextcloud/cron.php

Nun rufen wir die Cloud wieder unter ihrer IP auf und stellen von AJAX auf Cron um. Dazu klicken wir auf Einstellungen -> Grundeinstellungen und ändern AJAX auf Cron.

Nun habt ihr die grundlegende Installation durchgeführt und könnt die Cloud nutzen.


Grüße gehen aus dem Archiv!

[c] [y] Lucas Schreiner

Kommentar verfassen

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