Seit gut einem Jahr läuft meine Nextcloud auf meinem Dell Precision 3540 unter macOS Ventura und Docker Desktop v4.47.0. Ventura kann mit maximal Docker Desktop v4.48.0 verwendet werden. Neuere Docker Desktop Versionen benötigen höhere macOS Versionen. Für mich passt das aber so. Ich verwende Nextcloud im Grunde nur für mich alleine im single user Betrieb. Mein Konfiguration sah so aus, dass ich kein Docker Volume für meine Daten vorgesehen habe. Hier habe ich einen physischen mount meiner SSD verwendend mit dem Ziel so immer auch an meine Daten zu kommen ohne dazu ein Docker Volume mounten zu müssen. Leider stellte sich heraus, dass dieses setup so ungeeignet, weil instabil ist und ich z.T. mit Dateninkostistenzen zu kämpfen hatte. So fehlten auf einmal ~1000 Dateien ohne erkennbaren Grund. Zum Glück habe ich aber auf Sicherungen zurückgreifen, sodass nicht verloren ging. Jetzt entschloss ich mich Docker Nextcloud in Version 33 komplett neu nach best practice für macOS 13 und Docker Desktop 4.47.0 einzurichten, was hier dokumentiert werden soll. Man kann bei einer Einrichtung mit anschließender Optimierung für Performance und anschließender Fehlersuche, weil z.B. Cron nicht läuft, schnell sehr viele Stunden an Zeit verbraten.
Doch nun zu meiner Vorgehensweise zum Einrichten von NC33 unter Docker Desktop und macOS:
Im MAC PC befindet sich eine 2TB SDD die in mehrere Partitionen unterteilt ist: macOS, Windows 11, extFAT als gemeinsames Volume für Windows und macOS sowie eine 1500GB Mac OS Extended (journaled) Partition auf der Nexcloud und Paperless NGX laufen.


Meine docker-compose.yml für NC33:
services:
db:
image: mariadb:11.4
container_name: nc_db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: **********
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: **********
healthcheck:
test: ["CMD-SHELL", "mariadb-admin ping -h 127.0.0.1 -uroot -p********** --silent"]
interval: 10s
timeout: 5s
retries: 10
start_period: 30s
volumes:
- db:/var/lib/mysql
command: >
--transaction-isolation=READ-COMMITTED
--binlog-format=ROW
--innodb-flush-log-at-trx-commit=2
--sync-binlog=0
--innodb-buffer-pool-size=512M
--innodb-log-file-size=128M
networks:
- internal
redis:
image: redis:7-alpine
container_name: nc_redis
restart: unless-stopped
command: redis-server --save "" --appendonly no --maxmemory 256mb --maxmemory-policy allkeys-lru
networks:
- internal
app:
image: nextcloud:33
container_name: nc_app
restart: unless-stopped
ports:
- "8080:80"
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
environment:
MYSQL_HOST: db
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: **********
NEXTCLOUD_TRUSTED_DOMAINS: cloud.easyr.de 192.168.1.222 127.0.0.1
TRUSTED_PROXIES: 192.168.1.222
OVERWRITEHOST: cloud.easyr.de
OVERWRITEPROTOCOL: https
OVERWRITECLIURL: https://cloud.easyr.de
REDIS_HOST: redis
healthcheck:
test: ["CMD-SHELL", "php -f /var/www/html/status.php >/dev/null 2>&1 || exit 1"]
interval: 10s
timeout: 5s
retries: 5
start_period: 20s
volumes:
- nextcloud_data:/var/www/html
- ./config:/var/www/html/config
- ./custom_apps:/var/www/html/custom_apps
- ./php/99-opcache.ini:/usr/local/etc/php/conf.d/99-opcache.ini
- ./php/zz-opcache.ini:/usr/local/etc/php/conf.d/zz-opcache.ini
networks:
- internal
- web
cron:
image: nextcloud:33
container_name: nc_cron
restart: unless-stopped
entrypoint: /cron.sh
depends_on:
- app
volumes:
- nextcloud_data:/var/www/html
- ./config:/var/www/html/config
networks:
- internal
volumes:
db:
nextcloud_data:
networks:
internal:
web:
external: trueWie man erkennen kann habe ich ein eigenes Network mit Namen „web“ angelegt sowie werden Docker Volumes für die Datenbank (db) sowie Daten (nextcloud_data) angelegt. Außerdem gibt es für die config, logs, custom apps und angepasste php ini’s lokale host volumes (Verzeichnisse) im Docker Ordner nextcloud_33.
Hier meine angepasste config.php
Mein aktueller Stand ist technisch sehr gut:
- Redis sauber integriert ✔
- File Locking aktiv ✔
- Reverse Proxy korrekt berücksichtigt ✔
- Logging + Rotation ✔
- Preview optimiert ✔
- 2FA enforced ✔
- SMTP sauber konfiguriert ✔
server_idkorrekt ✔- Warnungs-Noise reduziert ✔
Das ist weit über „Standard-Setup“ hinaus.
<?php
$CONFIG = array (
'htaccess.RewriteBase' => '/',
'memcache.local' => '\\OC\\Memcache\\APCu',
'memcache.distributed' => '\\OC\\Memcache\\Redis',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'redis' =>
array (
'host' => 'redis',
'password' => '',
'port' => 6379,
'dbindex' => 0,
),
'apps_paths' =>
array (
0 =>
array (
'path' => '/var/www/html/apps',
'url' => '/apps',
'writable' => false,
),
1 =>
array (
'path' => '/var/www/html/custom_apps',
'url' => '/custom_apps',
'writable' => true,
),
),
'overwritehost' => 'cloud.easyr.de',
'overwriteprotocol' => 'https',
'overwrite.cli.url' => 'https://cloud.easyr.de',
'trusted_proxies' =>
array (
0 => '192.168.1.222',
),
'trusted_domains' =>
array (
0 => '192.168.1.222:8080',
1 => 'cloud.easyr.de',
),
'datadirectory' => '/var/www/html/data',
'dbtype' => 'mysql',
'dbname' => 'nextcloud',
'dbhost' => 'db',
'dbtableprefix' => 'oc_',
'mysql.utf8mb4' => true,
'dbuser' => 'nextcloud',
'dbpassword' => '**********',
'instanceid' => '**********',
'passwordsalt' => '**********',
'secret' => '******************************',
'installed' => true,
'version' => '33.0.0.16',
'upgrade.disable-web' => true,
'log_type' => 'file',
'logfile' => '/var/www/html/data/nextcloud.log',
'loglevel' => 2,
'log_rotate_size' => 10485760,
'twofactor_enforced' => 'true',
'twofactor_enforced_groups' =>
array (
0 => 'admin',
),
'twofactor_enforced_excluded_groups' =>
array (
),
'maintenance' => false,
'enable_previews' => true,
'preview_max_x' => 2048,
'preview_max_y' => 2048,
'preview_max_filesize_image' => 50,
'enabledPreviewProviders' =>
array (
0 => 'OC\\Preview\\JPEG',
1 => 'OC\\Preview\\PNG',
2 => 'OC\\Preview\\GIF',
3 => 'OC\\Preview\\HEIC',
4 => 'OC\\Preview\\BMP',
5 => 'OC\\Preview\\XBitmap',
6 => 'OC\\Preview\\MarkDown',
7 => 'OC\\Preview\\TXT',
8 => 'OC\\Preview\\OpenDocument',
9 => 'OC\\Preview\\Movie',
10 => 'OC\\Preview\\PDF',
),
'mail_smtppassword' => '**********',
'mail_smtpname' => '**********',
'mail_domain' => 'easyr.de',
'mail_from_address' => 'info',
'mail_smtpmode' => 'smtp',
'mail_smtpsecure' => 'ssl',
'mail_smtphost' => 'smtp.1blu.de',
'mail_smtpauth' => true,
'mail_smtpport' => '465',
'mail_sendmailmode' => 'smtp',
'mail_smtpstreamoptions' =>
array (
'ssl' =>
array (
'allow_self_signed' => true,
'verify_peer' => false,
'verify_peer_name' => false,
),
),
'filelocking.enabled' => true,
'default_phone_region' => 'DE',
'server_id' => 'easyr-nextcloud',
'check_for_working_htaccess' => false,
);
Meine Docker Container. Schön zu sehen, dass unter NC33 die 4 sub container für die app, cron, db und redis separat laufen:

Die NC33 volumes. Das Volume für die DB hat ~250MB, das Volume für meine Daten nimmt derzeit ~15GB in Anspruch. Der größte Anteil mit ~10GB sind die Fotos vom Smartphone die in meine Nextcloud synchronisiert werden.

Jetzt gehe ich noch auf Nextcloud Preview + File Scan Optimierung ein, die mittels ini Dateien im php Ordner definiert werden.
Benefit:
Preview Generator optimal konfigurieren
cron CPU spikes eliminieren
Redis lock tuning
DB query optimization
file scanning drastisch reduzieren

Da musste ich etwas herumspielen, bis mir endlich ein:
docker exec -it nc_app php -i | grep opcache.memory_consumption
opcache.memory_consumption => 256 => 256
angezeigt wurde.
Die zz-opcache.ini sowie 99-opcache.ini haben folgenden Inhalt:
opcache.enable=1 opcache.enable_cli=1 opcache.memory_consumption=256 opcache.interned_strings_buffer=16 opcache.max_accelerated_files=20000 opcache.revalidate_freq=2 opcache.validate_timestamps=1 opcache.save_comments=1 opcache.enable_file_override=1
Wichtig, dass in der YAML für Nextcloud app die Volumes auch hinterlegt werden.
– ./php/99-opcache.ini:/usr/local/etc/php/conf.d/99-opcache.ini
– ./php/zz-opcache.ini:/usr/local/etc/php/conf.d/zz-opcache.ini
Reverse Proxy Anpassungen:
Wie man in der Containerübersicht sehen konnte, verwende ich einen reverse Proxy. Hier zeige ich noch kurz, was es hier noch zu beachten/optimieren gibt:



proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; real_ip_header CF-Connecting-IP;
Lokaler DNS:
zu Hause soll der Internet host name cloud.easyr.de natürlich mit der lokalen IP aufgelöst werden und nicht der Umweg über die Internet IP gemacht werden. Das hat den Riesenvorteil, dass bei größeren Synch’s zu Hause viel schneller größere Datenmengen verarbeitet werden können.

Wenn’s am Ende so aussieht, ist man schon sehr gut aufgestellt und hat eine saubere Nextcloud Installation. Ein Wartungsfenster macht bei meiner Instanz natürlich gar keinen Sinn. Das Fehlen der Server-ID ist schlicht ein Falschmeldung.


#