Teil 1: Nextcloud lokal im eigenen Netz betreiben

Ziele

Der Betrieb eines lokalen Nextcloud Servers ist eigentlich recht einfach und für den lokalen oder privaten Gebrauch völlig ausreichend. Ist dieser Teil abgeschlossen, kann auf einen kompletten Nextcloud Server im lokalen Netzwerk zugegriffen werden.
Zusammengefasst sind folgende Schritte nötig, um das Ziel dieses ersten Teils zu erreichen:

Diese einfachste Ausbaustufe des ersten Teils ist NICHT für den öffentlichen Betrieb geeignet!
Denn der Zugriff erfolgt (noch) nicht mittels einer verschlüsselter Verbindung.

Zeitaufwand: ca 30 Minuten.

Letzte Aktualisierung:

  • 05.08.2023: Update auf FreeBSD 13.2 / PHP 8.2 und diverse Anpassungen
  • 26.03.2023: Initiales Dokument

Voraussetzungen für lokalen Betrieb

  • TrueNAS Core oder reiner FreeBSD Server
    • Ein Jail (z.B. mit dem Namen NEXTCLOUD) ist eingerichtet und gestartet
    • SSH ist aktiviert und ein normaler BENUTZERNAME in der "Wheel" Gruppe ist angelegt
    • IP Adresse des NEXTCLOUD Jails ist bekannt (z.B. 192.168.178.102)
    • Hostname des NEXTCLOUD Jails ist bekannt (z.B. nextcloud.domain.local) und per internem DNS erreichbar

Begrifflichkeiten

  • USERNAME = SSH Benutzeraccount (root Login ist nicht direkt möglich) mit SU Rechten
  • NEXTCLOUDIP = IP Adresse des lokalen NEXTCLOUD Servers
  • NEXTCLOUDHOSTNAME = Hostname des lokalen NEXTCLOUD Servers
  • NEXTCLOUDDB = Name der Nextcloud Datenbank (z.B. nextcloud_db )
  • NEXTCLOUDDBUSER = Nextcloud Datenbank Benutzer (z.B. nextcloud_user )
  • NEXTCLOUDDBPASS = Kennwort des Nextcloud Datenbank Benutzers (z.B. N3XtCloud )

In diesem Artikel wird so viel wie möglich per Copy'n'Paste ermöglicht/vorbereitet.
Gerade bei längeren Konfigurationen kommt dann so etwas vor:

    cat > DATEINAME.sh << 'EOF'
    BEFEHL1
    BEFEHL2
    BEFEHL3
    'EOF'

Das erzeugt eine Datei mit dem Namen DATEINAME mit dem Inhalt:

    BEFEHL1
    BEFEHL2
    BEFEHL3

Also immer komplett von cat bis EOF kopieren und einfügen!

Diagramm

Damit sieht das Setup lokal so aus:

                                                                  ┌─────────────────────────────┐
                                                                  │ TrueNAS                     │
                                                                  │   192.168.178.100           │
                                                                  │ ┌─────────────────────────┐ │
                                                                  │ │ Vault                   │ │
                                                                  │ │   192.168.178.102       │ │
                                                                  │ │                         │ │
                                                                  │ │   postgresql13-server   │ │
                                                                  │ │       ▲                 │ │
                                                                  │ │       │                 │ │   
                                                                  │ │   nextcloud (php)       │ │
                                                                  │ │       ▲                 │ │                      
                                                                  │ │       │                 │ │
                                                LAN: 0.0.0.0:80 ──┼─┼─►   nginx               │ │
                                                                  │ └─────────────────────────┘ │
                                                                  └─────────────────────────────┘

Jail starten

Login per SSH in das NEXTCLOUD Jail:
ssh BENUTZERNAME@NEXTCLOUDTIP oder ssh BENUTZERNAME@NEXTCLOUDHOSTNAME um mit su root Rechte zu erlangen.

Paketequelle anpassen

Zuvor passen wir die Paketquellen auf die latest an, damit auch wirklich die neueste Pakete bezogen werden

Pakete installieren & Dienste aktivieren

Nun die Paketquelle mit pkg update aktualisieren und dann die benötigten Pakete installieren:
pkg install nextcloud-php82 postgresql13-server postgresql13-client nginx php82-ftp php82-pdo_pgsql php82-pgsql php82-pecl-redis php82-pecl-imagick php82-imap php82-phar redis

Dienste aktivieren und beim Start des Jails automatisch mit starten:
service postgresql enable && service nginx enable && service php-fpm enable && service redis enable

PostgreSQL Datenbankserver

PostgreSQL mit service postgresql initdb initialisieren und mit service postgresql start starten.

Datenbank erstellen

Die PostgreSQL Datenbank enthält alle Daten, die zum Betrieb von Nextcloud benötigt werden.
Diese Datenbank wird von Hand erstellt, ein Benutzer erzeugt und der Zugriff gestattet.
Dazu starten wir mit su -m postgres -c "psql" die PostgreSQL Shell.

CREATE DATABASE NEXTCLOUDDBNAME;
CREATE USER NEXTCLOUDDBUSER WITH PASSWORD 'NEXTCLOUDDBPASS';
ALTER DATABASE NEXTCLOUDDBNAME OWNER TO NEXTCLOUDDBUSER;
GRANT ALL PRIVILEGES ON DATABASE NEXTCLOUDDBNAME TO NEXTCLOUDDBUSER;

Bitte darauf achten, das NEXTCLOUDDBNAME, NEXTCLOUDDBUSER und NEXTCLOUDDBPASS vorher an eure Vorgaben angepasst werden. Mit den Beispielen von oben:

CREATE DATABASE nextcloud_user;
CREATE USER nextcloud WITH PASSWORD 'N3XtCloud';
ALTER DATABASE nextcloud_db OWNER TO nextcloud_user;
GRANT ALL PRIVILEGES ON DATABASE nextcloud_db TO nextcloud_user;

Regelmäßige Wartung der Datenbank

Datenbanken sollten regelmäßig und am besten automatisch gewartet werden:

  • vacuumdb ist ein Dienstprogramm zum Bereinigen einer PostgreSQL-Datenbank.
  • reindexdb ist ein Dienstprogramm zum Wiederaufbau von Indizes in einer PostgreSQL-Datenbank

Mit mkdir /var/db/postgres/bin eine Verzeichnis für das folgende Skript anlegen

cat > /var/db/postgres/bin/vacuum.sh << 'EOF'
#! /bin/sh
/usr/local/bin/vacuumdb -az 1> /dev/null 2> /dev/null
/usr/local/bin/reindexdb -a 1> /dev/null 2> /dev/null
'EOF'

und dann jeden Abend um 0:00 Uhr ausführen lassen:

echo "# PostgreSQL house keeping" >> /etc/crontab
echo "0       0       *       *       *       postgres /var/db/postgres/bin/vacuum.sh" >> /etc/crontab

Redis Datenbankserver

Redis ist ebenfalls eine Datenbank, die optional für Caching and Session Verwaltung genutzt werden kann.
Das schont die Hauptdatenbank (und damit auch ein Backup) und beschleunigt den Betrieb, insbesondere wenn ein paar mehr Benutzer angelegt werden.

Der Redis Benutzer muss mit pw groupmod redis -m www zur Gruppe www hinzugefügt werden.

Konfiguration anpassen

sed -i '' 's/port 6379/port 0/' /usr/local/etc/redis.conf
sed -i '' 's/# unixsocket \/run\/redis.sock/unixsocket \/var\/run\/redis\/redis.sock/' /usr/local/etc/redis.conf
sed -i '' 's/# unixsocketperm 700/unixsocketperm 770/' /usr/local/etc/redis.conf

NGINX Webserver

NGINX zusammen mit PHP bildet den Webserver und damit auch das Fundament für Nextcloud.

Konfiguration erstellen

Die Konfiguration wird zur besseren Übersicht in drei Dateien aufgeteilt:
Nextcloud und PHP-FPM kommen in ein eigenes Verzeichnis: mkdir /usr/local/etc/nginx/conf.d

  • Hauptkonfiguration: /usr/local/etc/nginx/nginx.conf
cat > /usr/local/etc/nginx/nginx.conf << 'EOF'
worker_processes auto;
error_log /var/log/nginx/error.log;

events {
 worker_connections 1024;
 use kqueue;
 multi_accept on;
}

http {
 access_log /var/log/nginx/access.log;
 include mime.types;
 default_type application/octet-stream;

 sendfile on;
 tcp_nopush on;
 tcp_nodelay on;
 reset_timedout_connection on;
 keepalive_timeout 65;
 keepalive_requests 1000;
 types_hash_max_size 2048;
 send_timeout 30;
 server_names_hash_max_size 4096;

 client_header_timeout 180s;
 client_body_temp_path /var/tmp/nginx/client_body_temp;

 proxy_buffer_size 4k;
 proxy_buffers 8 16k;
 proxy_busy_buffers_size 64k;
 proxy_temp_file_write_size 64k;
 proxy_temp_path /var/tmp/nginx/proxy_temp;
 proxy_cache_valid 1m;

 include /usr/local/etc/nginx/conf.d/*.conf;
}
'EOF'
  • PHP-FPM: /usr/local/etc/nginx/conf.d/php.conf
cat > /usr/local/etc/nginx/conf.d/php.conf << 'EOF'
upstream php-handler {
 server unix:/var/run/php-fpm.sock;
}
'EOF'
  • Nextcloud: /usr/local/etc/nginx/conf.d/nextcloud.conf
cat > /usr/local/etc/nginx/conf.d/nextcloud.conf << 'EOF'
server {
 listen 80;
 listen [::]:80;
 server_tokens off;
 root /usr/local/www/nextcloud/;
 client_max_body_size 10G;
 client_body_timeout 300s;
 fastcgi_buffers 64 4K;
 client_body_buffer_size 512k;

 gzip on;
 gzip_vary on;
 gzip_comp_level 4;
 gzip_min_length 256;
 gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
 gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

 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 "none" always;
 add_header X-XSS-Protection "1; mode=block" always;
 fastcgi_hide_header X-Powered-By;

 index index.php index.html /index.php$request_uri;

 if ( $http_user_agent ~ ^DavClnt ) {
  return 302 /remote.php/webdav/$is_args$args;
  }

 location = /robots.txt {
  allow all;
  log_not_found off;
  access_log off;
 }

 location ^~ /.well-known {
  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; }
  return 301 /index.php$request_uri;
 }

 location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
 location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
 location ~ \.php(?:$|/) {
  rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
  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 HTTPS on;
  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|svg|gif|png|jpg|ico|wasm|tflite|map)$ {
  try_files $uri /index.php$request_uri;
  add_header Cache-Control "public, max-age=15778463";
  access_log off;
  location ~ \.wasm$ {
  default_type application/wasm;
  }
 }

 location ~ \.woff2?$ {
  try_files $uri /index.php$request_uri;
  expires 7d;
  access_log off;
 }

 location /remote {
  return 301 /remote.php$request_uri;
 }

 location / {
  try_files $uri $uri/ /index.php$request_uri;
 }
}
'EOF'

PHP aktivieren

PHP ist eine weit verbreitete Skriptsprache, die als Modul in einen Webserver integriert wird. Nextcloud verwendet PHP und muss daher aktiviert sein. Die Standardeinstellungen sind jedoch etwas zu konservativ für Nextcloud und müssen angepasst werden:

cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini

sed -i '' 's/\;date.timezone =/date.timezone = Europe\/Berlin/' /usr/local/etc/php.ini
sed -i '' 's/post_max_size = 8M/post_max_size = 16M/' /usr/local/etc/php.ini
sed -i '' 's/max_execution_time = 30/max_execution_time = 300/' /usr/local/etc/php.ini
sed -i '' 's/max_input_time = 60/max_input_time = 300/' /usr/local/etc/php.ini
sed -i '' 's/memory_limit = 128M/memory_limit = 512M/' /usr/local/etc/php.ini

sed -i '' 's/;opcache.enable=1/opcache.enable=1/' /usr/local/etc/php.ini
sed -i '' 's/;opcache.enable_cli=0/opcache.enable_cli=1/' /usr/local/etc/php.ini
sed -i '' 's/;opcache.memory_consumption=128/opcache.memory_consumption=128/' /usr/local/etc/php.ini
sed -i '' 's/;opcache.interned_strings_buffer=8/opcache.interned_strings_buffer=8/' /usr/local/etc/php.ini
sed -i '' 's/;opcache.max_accelerated_files=10000/opcache.max_accelerated_files=10000/' /usr/local/etc/php.ini
sed -i '' 's/;opcache.revalidate_freq=2/opcache.revalidate_freq=1/' /usr/local/etc/php.ini
sed -i '' 's/;opcache.save_comments=1/opcache.save_comments=1/' /usr/local/etc/php.ini

echo "; Redis ;" >> /usr/local/etc/php.ini
echo "redis.session.locking_enabled = 1" >> /usr/local/etc/php.ini
echo "redis.session.lock_retries = -1" >> /usr/local/etc/php.ini
echo "redis.session.lock_wait_time = 10000" >> /usr/local/etc/php.ini

cp /usr/local/etc/php-fpm.d/www.conf /usr/local/etc/php-fpm.d/www.conf.bak

sed -i '' 's/;listen.owner = www/listen.owner = www/' /usr/local/etc/php-fpm.d/www.conf
sed -i '' 's/;listen.group = www/listen.group = www/' /usr/local/etc/php-fpm.d/www.conf
sed -i '' 's/;listen.mode = 0660/listen.mode = 0660/' /usr/local/etc/php-fpm.d/www.conf
sed -i '' 's/listen = 127.0.0.1:9000/listen = \/var\/run\/php-fpm.sock/' /usr/local/etc/php-fpm.d/www.conf
sed -i '' 's/;env\[HOSTNAME\]/env\[HOSTNAME\]/' /usr/local/etc/php-fpm.d/www.conf
sed -i '' 's/;env\[PATH\]/env\[PATH\]/' /usr/local/etc/php-fpm.d/www.conf
sed -i '' 's/;env\[TMP\]/env\[TMP\]/' /usr/local/etc/php-fpm.d/www.conf
sed -i '' 's/;env\[TMPDIR\]/env\[TMPDIR\]/' /usr/local/etc/php-fpm.d/www.conf
sed -i '' 's/;env\[TEMP\]/env\[TEMP\]/' /usr/local/etc/php-fpm.d/www.conf

Nextcloud

Konfiguration vorbereiten

Auch ohne diese Anpassungen könnte die Nextcloud Installation theoretisch zwar schon starten, würde aber nach der Eingabe der Datenbankinformationen auf einen Fehler bzw. eine Umleitung auf HTTPS (was wir hier nicht verwenden) stoßen. Redis würde dann auch ungenutzt bleiben. Daher wird die mitgelieferte Konfigurationsdatei vorher noch um einige Punkte erweitert.

cat > /usr/local/www/nextcloud/config/config.php << 'EOF'
<?php

/** This is the bare minimum configuration for the bundled installer
  * to function properly.
  */

$CONFIG = array (

// Disable HTTPS because of upfront HTTPS Proxy
 'overwriteprotocol' => 'http',

// Set defaultphone region (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements)
 'default_phone_region' => 'DE',

/** The FreeBSD package separates apps into bundled apps and user-
  * installed apps. If this 'apps_paths' array is missing from
  * your config, your Nextcloud installation is broken
  */
  'apps_paths' =>
  array (
    0 =>
    array (
     'path' => '/usr/local/www/nextcloud/apps',
     'url' => '/apps',
     'writable' => true,
    ),
    1 =>
    array (
     'path' => '/usr/local/www/nextcloud/apps-pkg',
     'url' => '/apps-pkg',
     'writable' => false,
    ),
  ),

// Log-files belong in the appropriate location
 'logfile' => '/var/log/nextcloud/nextcloud.log',

// Enable user caching when option is enabled
  'memcache.local' => '\OC\Memcache\APCu',

// Redis caching and session handling
 'filelocking.enabled' => true,
 'memcache.local' => '\OC\Memcache\Redis',
 'memcache.locking' => '\OC\Memcache\Redis',
 'distributed' => '\\OC\\Memcache\\Redis',
 'redis' =>
  array(
   'host' => '/var/run/redis/redis.sock',
   'port' => 0,
   'timeout' => 0.0,
  ),
 );
'EOF'

Berechtigungen der Config Datei anpassen

Der Nextcloud Installer braucht schreibenden Zugriff auf die Konfigurationsdatei.

chown www:www /usr/local/www/nextcloud/config/config.php
chmod 775 /usr/local/www/nextcloud/config/config.php

Das Logging Verzeichnis sollte mit der richtigen Berechtigung ebenfalls angelegt werden:

mkdir -p /var/log/nextcloud/
chown www:www /var/log/nextcloud

Dienste starten

Damit sind wir nun am Ende der Vorbereitungen angelangt
und alle Dienste können nun mit service redis start && service php-fpm start && service nginx start gestartet werden.

Installer

Die letzen Schritte und dann alles weitere wird in dem Nextcloud Installer eingestellt.
Hierzu mit dem Lieblingsbrowser nun die IP oder Hostname des Nextcloud Jails aufrufen:
http://NEXTCLOUDIP oder http://NEXTCLOUDHOSTNAME

installer

Die empfohlenen Apps sollten im zweiten Schritt direkt mit installiert werden:

apps

und nach ein paar Minuten zeigt sich das Nextcloud Dashboard:

dashboard

Voilá

Damit das ganze auch für Handys und Co. von unterwegs aus genutzt werden kann, wird in Teil 2 erklärt.

Anleitung und viele weitere Informationen sind hier zu finden.

Startover

service postgresql stop rm -rf /var/db/postgres/data13/ rm -rf /usr/local/www/nextcloud/data/nxadmin/ rm /usr/local/www/nextcloud/config/config.php service postgresql initdb