Teil 1: Nextcloud nur 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:

NEU: Für ganz ungeduldige habe ich einen Konsole only Abschnitt. Da gibts nur Befehle, keine Erklärungen.

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.

Letzte Aktualisierung:

  • 05.02.2024: Konsole Abschnitt hinzugefügt
  • 19.01.2024: Heftige Überarbeitung. Externe Verzeichnisse, Fehlerkorrektueren, PostgreSQL 15
  • 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 )

Diagramm

Damit sieht das Setup lokal so aus:

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

TrueNAS

Jail erstellen

  • TrueNAS / Jail / Add
    • Name: nextcloud
    • Jail Type: Basejail
    • Release: 13.2
    • DHCP Autoconfigure IPv4: Ja
    • VNET: Ja

Benutzer erstellen

Da die PostgreSQL Datenbank unter einem eigenen Benutzer ausgeführt wird, braucht es entsprechende Rechte auch vom Jail aus. Wichtig ist hierbei das die ID des Benutzers im Jail gleich dem Benutzer im TrueNAS ist.

  • TrueNAS / Accounts / Groups / Add
    • GID: 770
    • Name: postgres
  • TrueNAS / Accounts / Users / Add
    • Full Name: PostgreSQL Daemon
    • Username: postgres
    • Password: 123
    • User ID: 770
    • Primary Group: 770
    • Shell: nologin
    • Home: /nonexistent

Jail noch nicht starten!

Jail Grundeinstellungen

Datenverzeichnisse

Das Datenverzeichnis für Nextcloud können in ein eigenes Dataset außerhalb des Jails abgelegt werden. Damit sind diese Daten unabhängig vom Jail gespeichert. Wenn das Jail aus irgendeinem Grund beschädigt oder gelöscht wurde, sind wir so in der Lage, die vorherige Konfiguration und Daten mit minimalem Aufwand wiederherzustellen. Auch werden die erzeugten Backups außerhalb des Jails gespeichert.

└── /mnt/tank/jails_data
    └── nextcloud
        ├── backup      # Ablage für Backups (im Jail: /mnt/backup)
        ├── conf        # Ablage für Konfigurationsdateien (im Jail: /mnt/config)
        ├── db          # Ablage für die PostgreSQL Datenbank (im Jail: /var/db/postgres)
        └── data        # Datenbank und Log Dateien (im Jail: /usr/local/www/nextcloud/data)

Datenverzeichnisse erstellen

  • TrueNAS / Storage / Pools / tank/jails_data / Add Dataset
    • Name: nextcloud
  • TrueNAS / Storage / Pools / tank/jails_data/nexcloud / Add Dataset
    • Name: backup, config, db, data

Datenverzeichnisse Berechtigungen anpassen

  • TrueNAS / Jails / Mount Points / tank/jails_data/nexcloud/data / Edit Permissions
    • User: www
    • Group: www
    • Apply USER & Group: Ja
    • Apply Permissions Recursively: Ja
  • TrueNAS / Jails / Mount Points / tank/jails_data/nextcloud/db / Edit Permissions
    • User: postgres
    • Group: postgres
    • Apply USER & Group: Ja
    • Apply Permissions Recursively: Ja

Datenverzeichnisse einbinden

Hinweis: Die Zielverzeichnisse im Jail werden automatisch angelegt, wenn die Mount Punkte zugeordnet werden. Auch rekursiv!

  • TrueNAS / Jails / nextcloud / Mount Points / Actions / Add
    • backup:
      • Source: /mnt/tank/jails_data/nextcloud/backup
      • Destination: /mnt/tank/jails/nextcloud/root/mnt/backup
    • config:
      • Source: /mnt/tank/jails_data/nextcloud/conf
      • Destination: /mnt/tank/jails/nextcloud/root/mnt/conf
    • data:
      • Source: /mnt/tank/jails_data/nextcloud/data
      • Destination: /mnt/tank/jails/nextcloud/root/usr/local/www/nextcloud
    • db:
      • Source: /mnt/tank/jails_data/nextcloud/db
      • Destination: /mnt/tank/jails/nextcloud/root/var/db/postgres

Dienste aktivieren und Benutzer einrichten

Die Webshell in TrueNAS ist nicht geeignet und komplexe Konfigurationen vorzunehmen, daher wird SSH aktiviert.

  • Jail starten: TrueNAS / Jails / paperless / Start
  • Jail Shell öffnen: TrueNAS / Jails / paperless / Shell
    • Mit passwd das root Kennwort setzen
    • Mit adduser username einen Benutzer hinzufügen. Wichtig: Mit weiterer Gruppe wheel damit su Rechte erlangt werden können
    • service sshd enable aktiviert den SSH Dienst
    • service sshd start startet den SSH Dienst
    • ifconfig zeigt die aktuelle IPv4 Adresse an. Am besten im DHCP reservieren und per DNS (paperless.domain.local) hinterlegen

Nun kann die Shell verlassen und die TrueNAS Webseite erstmal geschlossen werden. Login per SSH in das Jail: ssh USERNAME@IP oder ssh USERNAME@HOSTNAME, um mit su root Rechte zu erlangen.

JAIL

Grundeinstellungen

Paketquelle anpassen

bsdbox_truenas_jail_pkg

Pakete installieren & Dienste aktivieren

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

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

PostgreSQL

Die PostgreSQL Datenbank enthält alle Daten, die zum Betrieb von Nextcloud benötigt werden.
PostgreSQL mit service postgresql initdb initialisieren und mit service postgresql start starten.
PostreSQL root Passwort mit su -m postgres -c "createuser -s root --pwprompt" setzen.

Bitte darauf achten, das NEXTCLOUDDBNAME, NEXTCLOUDDBUSER und NEXTCLOUDDBPASS an eure Vorgaben ausgetauscht werden.

su -m postgres -c "createuser -s NEXTCLOUDDBUSER --pwprompt"
su -m postgres -c "createdb -O NEXTCLOUDDBUSER -E Unicode -T template1 NEXTCLOUDDBNAME"

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 ein Verzeichnis für das folgende Skript anlegen, um regelmäßige Wartungen durchzuführen zu können:

fetch https://raw.githubusercontent.com/marzlberger/bsdbox/main/pgsql/vacuum.sh -o /var/db/postgres/bin/vacuum.sh
chown postgres /var/db/postgres/bin/vacuum.sh

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

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.

Redis Konfiguration anpassen

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

Symlink setzten um auf die Konfiguration in /mnt/conf/ zu verweisen: ln -sf /mnt/conf/redis.conf /usr/local/etc/redis.conf cp /usr/local/etc/redis.conf.sample /usr/local/etc/redis.conf

sed -i '' 's/port 6379/port 0/' /mnt/conf/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

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

Symlinks setzten um auf die Konfiguration in /mnt/conf/ zu verweisen:

ln -sf /mnt/conf/nginx.conf /usr/local/etc/nginx/nginx.conf
ln -sf /mnt/conf/php.conf /usr/local/etc/nginx/conf.d/php.conf
ln -sf /mnt/conf/nextcloud.conf /usr/local/etc/nginx/conf.d/nextcloud.conf
ln -sf /mnt/conf/php.ini /usr/local/etc/php.ini
ln -sf /mnt/conf/www.conf /usr/local/etc/php-fpm.d/www.conf
  • /usr/local/etc/nginx/nginx.conf = Allgemeine Optionen
  • /usr/local/etc/nginx/conf.d/php.conf = PHP aktivieren
  • /usr/local/etc/nginx/conf.d/nextcloud.conf = Nextcloud Konfiguration
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'
cat > /usr/local/etc/nginx/conf.d/php.conf << 'EOF'
upstream php-handler {
 server unix:/var/run/php-fpm.sock;
}
'EOF'
cat > /usr/local/etc/nginx/conf.d/nextcloud.conf << 'EOF'
server {
 listen 80;
# listen 443 ssl http2;
 listen [::]:80;
# listen [::]:443 ssl http2;
 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;

 ssl_certificate /usr/local/etc/ssl/nextcloud/cert.pem;
 ssl_certificate_key /usr/local/etc/ssl/nextcloud/key.pem;
 ssl_dhparam /usr/local/etc/ssl/nextcloud/dhparam.pem;

 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 Strict-Transport-Security "max-age=31536000; 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;
 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'

HTTPS Zertifikate

mkdir -p /usr/local/etc/ssl/nextcloud
openssl dhparam -out /usr/local/etc/ssl/nextcloud/dhparam.pem 4096
openssl req -x509 -nodes -days 3652 -sha512 -subj "/C=DE/CN=nextcloud" -newkey rsa:2048 -keyout "/usr/local/etc/ssl/nextcloud/key.pem" -out "/usr/local/etc/ssl/nextcloud/cert.pem"

PHP aktivieren

PHP Konfiguration anpassen

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/' /mnt/conf/php.ini
sed -i '' 's/post_max_size = 8M/post_max_size = 16M/' /mnt/conf/php.ini
sed -i '' 's/max_execution_time = 30/max_execution_time = 300/' /mnt/conf/php.ini
sed -i '' 's/max_input_time = 60/max_input_time = 300/' /mnt/conf/php.ini
sed -i '' 's/memory_limit = 128M/memory_limit = 512M/' /mnt/conf/php.ini
sed -i '' 's/;opcache.enable=1/opcache.enable=1/' /mnt/conf/php.ini
sed -i '' 's/;opcache.enable_cli=0/opcache.enable_cli=1/' /mnt/conf/php.ini
sed -i '' 's/;opcache.memory_consumption=128/opcache.memory_consumption=128/' /mnt/conf/php.ini
sed -i '' 's/;opcache.interned_strings_buffer=8/opcache.interned_strings_buffer=8/' /mnt/conf/php.ini
sed -i '' 's/;opcache.max_accelerated_files=10000/opcache.max_accelerated_files=10000/' /mnt/conf/php.ini
sed -i '' 's/;opcache.revalidate_freq=2/opcache.revalidate_freq=1/' /mnt/conf/php.ini
sed -i '' 's/;opcache.save_comments=1/opcache.save_comments=1/' /mnt/conf/php.ini
echo "; Redis ;" >> /usr/local/etc/php.ini
echo "redis.session.locking_enabled = 1" >> /mnt/conf/php.ini
echo "redis.session.lock_retries = -1" >> /mnt/conf/php.ini
echo "redis.session.lock_wait_time = 10000" >> /mnt/conf/php.ini

cp /usr/local/etc/php-fpm.d/www.conf.default /usr/local/etc/php-fpm.d/www.conf
sed -i '' 's/;listen.owner = www/listen.owner = www/' /mnt/conf/www.conf
sed -i '' 's/;listen.group = www/listen.group = www/' /mnt/conf/www.conf
sed -i '' 's/;listen.mode = 0660/listen.mode = 0660/' /mnt/conf/www.conf
sed -i '' 's/listen = 127.0.0.1:9000/listen = \/var\/run\/php-fpm.sock/' /mnt/conf/www.conf
sed -i '' 's/;env\[HOSTNAME\]/env\[HOSTNAME\]/' /mnt/conf/www.conf
sed -i '' 's/;env\[PATH\]/env\[PATH\]/' /mnt/conf/www.conf
sed -i '' 's/;env\[TMP\]/env\[TMP\]/' /mnt/conf/www.conf
sed -i '' 's/;env\[TMPDIR\]/env\[TMPDIR\]/' /mnt/conf/www.conf
sed -i '' 's/;env\[TEMP\]/env\[TEMP\]/' /mnt/conf/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 (kann weg, wenn intern auch über https gearbeitet werden soll)
 '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 wird mit install -d -o www -g www /var/log/nextcloud/ und den richtigen Berechtigung angelegt.

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 aufrufen

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

  • Adminaccount: nxadmin / password
  • Datenbankbenutzer = nextcloud
  • Datenbankkennwort = N3XtCloud!
  • Datenbankname = nextcloud
  • Datenbankhost: localhost

cron manuell

su -m www -c "php /usr/local/www/nextcloud/cron.php"

cron automatisch


ee /etc/crontab
*/5 * * * * www php /usr/local/www/nextcloud/cron.php

Konsole

tank = Der Name des ZFS Pools, bitte anpassen

iocage create -b -n "nextcloud" -r 13.2-RELEASE vnet="on" bpf="on" dhcp="on"

# OPTIONAL
zfs create -p tank/jails_data/nextcloud/backup
zfs create -p tank/jails_data/nextcloud/conf
zfs create -p tank/jails_data/nextcloud/db
zfs create -p tank/jails_data/nextcloud/data
chown www:www /mnt/tank/jails_data/nextcloud/data
chown 770:770 /mnt/tank/jails_data/nextcloud/db
iocage exec -f nextcloud "install -d /mnt/backup"
iocage exec -f nextcloud "install -d /mnt/conf"
iocage exec -f nextcloud "install -d /usr/local/etc/nginx/conf.d"
iocage exec -f nextcloud "install -d /usr/local/etc/php-fpm.d"
iocage exec -f nextcloud "install -d -g www -o www /usr/local/www/nextcloud"
iocage exec -f nextcloud "install -d -g 770 -o 770 /var/db/postgres/bin"
iocage exec -f nextcloud "ln -sf /mnt/conf/redis.conf /usr/local/etc/redis.conf"
iocage exec -f nextcloud "ln -sf /mnt/conf/nginx.conf /usr/local/etc/nginx/nginx.conf"
iocage exec -f nextcloud "ln -sf /mnt/conf/php.conf /usr/local/etc/nginx/conf.d/php.conf"
iocage exec -f nextcloud "ln -sf /mnt/conf/nextcloud.conf /usr/local/etc/nginx/conf.d/nextcloud.conf"
iocage exec -f nextcloud "ln -sf /mnt/conf/php.ini /usr/local/etc/php.ini"
iocage exec -f nextcloud "ln -sf /mnt/conf/www.conf /usr/local/etc/php-fpm.d/www.conf"
iocage stop nextcloud
iocage fstab -a nextcloud /mnt/tank/jails_data/nextcloud/backup /mnt/backup nullfs rw 0 0
iocage fstab -a nextcloud /mnt/tank/jails_data/nextcloud/conf /mnt/config nullfs rw 0 0
iocage fstab -a nextcloud /mnt/tank/jails_data/nextcloud/data /usr/local/www/nextcloud nullfs rw 0 0
iocage fstab -a nextcloud /mnt/tank/jails_data/nextcloud/db /var/db/postgres nullfs rw 0 0

iocage console -f nextcloud

mkdir -p /usr/local/etc/pkg/repos
sed -e 's|quarterly|latest|g' /etc/pkg/FreeBSD.conf > /usr/local/etc/pkg/repos/FreeBSD.conf
pkg install -y nextcloud-php82 postgresql15-server postgresql15-client nginx php82-pdo_pgsql php82-pgsql php82-pecl-redis redis php82-pecl-imagick

service postgresql enable && service nginx enable && service php-fpm enable && service redis enable
service postgresql initdb && service postgresql start

su -m postgres -c "createuser -s NEXTCLOUDDBUSER --pwprompt"
su -m postgres -c "createdb -O NEXTCLOUDDBUSER -E Unicode -T template1 NEXTCLOUDDBNAME"

install -d -g 770 -o 770 /var/db/postgres/bin
fetch https://raw.githubusercontent.com/marzlberger/bsdbox/main/pgsql/vacuum.sh -o /var/db/postgres/bin/vacuum.sh
echo "0 0 * * * postgres /var/db/postgres/bin/vacuum.sh" >> /etc/crontab

pw groupmod redis -m www
cp /usr/local/etc/redis.conf.sample /usr/local/etc/redis.conf
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

mkdir /usr/local/etc/nginx/conf.d
fetch https://raw.githubusercontent.com/marzlberger/bsdbox/main/nextcloud/nginx.conf -o /usr/local/etc/nginx/nginx.conf
fetch https://raw.githubusercontent.com/marzlberger/bsdbox/main/nextcloud/php.conf -o /usr/local/etc/nginx/conf.d/php.conf
fetch https://raw.githubusercontent.com/marzlberger/bsdbox/main/nextcloud/nextcloud.conf -o /usr/local/etc/nginx/conf.d/nextcloud.conf

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.default /usr/local/etc/php-fpm.d/www.conf
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

fetch https://raw.githubusercontent.com/marzlberger/bsdbox/main/nextcloud/config.php -o /usr/local/www/nextcloud/config/config.php
chown www:www /usr/local/www/nextcloud/config/config.php
chmod 775 /usr/local/www/nextcloud/config/config.php
install -d -o www -g www /var/log/nextcloud
service redis start && service php-fpm start && service nginx start
echo "*/5 * * * * www php /usr/local/www/nextcloud/cron.php" >> /etc/crontab

# Nach dem Setup
su -m www -c "php /usr/local/www/nextcloud/occ db:add-missing-primary-keys"
su -m www -c "php /usr/local/www/nextcloud/occ db:add-missing-indices"
su -m www -c "php /usr/local/www/nextcloud/occ db:add-missing-columns"
su -m www -c "php /usr/local/www/nextcloud/occ db:convert-filecache-bigint --no-interaction"
su -m www -c "php /usr/local/www/nextcloud/occ maintenance:mimetype:update-db"

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

Tuning

su -m www -c "php /usr/local/www/nextcloud/occ db:add-missing-indices"
su -m www -c "php /usr/local/www/nextcloud/occ db:add-missing-primary-keys"
su -m www -c "php /usr/local/www/nextcloud/occ db:add-missing-indices"
su -m www -c "php /usr/local/www/nextcloud/occ db:add-missing-columns"
su -m www -c "php /usr/local/www/nextcloud/occ db:convert-filecache-bigint --no-interaction"
su -m www -c "php /usr/local/www/nextcloud/occ maintenance:mimetype:update-db"

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.