Hello, this is my personal pense-bete for my personal nextcloud server…
If you landed here, i hope you may find some help looking to my actual configuration.
This server is in production, up and running on a 24/7 base.
It may not being built like yours, but you may find clues…
Apache2 and nextcloud are cached directly to redis.
NEXTCLOUD HUB II - 23.0.4
based on:
- DEBIAN Bulleyes 11.3
- Apache 2.4.53
- Php8.0.18
- MariaDB 10.5.15
- Python 3
- Redis 6.xx
- Brotli
… and i may add stuff here later…
Server configuration detail UPDATED 21/04/2022
Operating system: Linux 5.10.0-13-amd64 #1 SMP Debian 5.10.106-1 (2022-03-17) x86_64 GNU/Linux
x
DATA FILESYSTEM 10TB Raid6 Array based on LVM2+MDADM, 6 physicals devices.
Webserver: Apache/2.4.53 (fpm-fcgi)
Database: mysql MariaDB 10.5.16 with Barracuda layout
PHP version:
php -v
PHP 8.0.18 (cli) (built: Apr 21 2022 10:49:51) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.18, Copyright (c) Zend Technologies
with Zend OPcache v8.0.18, Copyright (c), by Zend Technologies
php -m
[PHP Modules]
apcu
bcmath
bz2
calendar
Core
ctype
curl
date
dom
exif
FFI
fileinfo
filter
ftp
gd
gettext
gmp
hash
iconv
igbinary
imagick
intl
json
ldap
libxml
mbstring
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
Phar
posix
readline
redis
Reflection
session
shmop
SimpleXML
soap
sockets
sodium
SPL
standard
sysvmsg
sysvsem
sysvshm
tokenizer
xml
xmlreader
xmlwriter
xsl
Zend OPcache
zip
zlib
[Zend Modules]
Zend OPcache
Nextcloud version: 23.0.4
Updated from an older Nextcloud/ownCloud or fresh install: Updated from Fresh 23.0.3 install on new server march 2022.
Where did you install Nextcloud from: Web-installer on Debian 11.3 fresh instll, manual conf for apache2 and dependencies.
List of activated apps
app:list
Enabled:
- accessibility: 1.9.0
- activity: 2.15.0
- announcementcenter: 6.1.1
- apporder: 0.15.0
- breezedark: 23.2.1
- bruteforcesettings: 2.4.0
- camerarawpreviews: 0.7.15
- cloud_federation_api: 1.6.0
- comments: 1.13.0
- contactsinteraction: 1.4.0
- dav: 1.21.0
- external: 3.10.2
- extract: 1.3.3
- federatedfilesharing:1.13.0
- federation: 1.13.0
- files: 1.18.0
- files_pdfviewer: 2.4.0
- files_rightclick: 1.2.0
- files_sharing: 1.15.0
- files_trashbin: 1.13.0
- files_versions: 1.16.0
- files_videoplayer: 1.12.0
- firstrunwizard: 2.12.0
- flowupload: 1.1.3
- impersonate: 1.10.0
- logreader: 2.8.0
- lookup_server_connector: 1.11.0
- nextcloud_announcements: 1.12.0
- notifications: 2.11.1 - oauth2: 1.11.0
- occweb: 0.1.0
- password_policy: 1.13.0
- photos: 1.5.0
- previewgenerator: 4.0.0
- privacy: 1.7.0
- provisioning_api: 1.13.0
- recommendations: 1.2.0
- registration: 1.4.0
- serverinfo: 1.13.0
- settings: 1.5.0
- sharebymail: 1.13.0
- sharerenamer: 3.0.0
- support: 1.6.0
- survey_client: 1.11.0
- systemtags: 1.13.0
- text: 3.4.1
- theming: 1.14.0
- twofactor_admin: 3.2.0
- twofactor_backupcodes: 1.12.0
- twofactor_email: 2.3.0
- twofactor_nextcloud_notification: 3.3.1
- twofactor_totp: 6.2.0
- twofactor_webauthn: 0.3.1
- unsplash: 1.2.4
- updatenotification: 1.13.0
- user_status: 1.3.1
- video_converter: 1.0.4
- viewer: 1.7.0
- workflow_media_converter: 1.3.6
- workflowengine: 2.5.0
Disabled:
- admin_audit
- circles: 23.1.0
- dashboard: 7.3.0
- encryption
- files_external
- user_ldap
- weather_status: 1.3.0
Configuration (config/config.php)
{
"instanceid": "***REMOVED SENSITIVE VALUE***",
"passwordsalt": "***REMOVED SENSITIVE VALUE***",
"secret": "***REMOVED SENSITIVE VALUE***",
"trusted_domains": [
"n2.rkn.ovh"
],
"datadirectory": "***REMOVED SENSITIVE VALUE***",
"dbtype": "mysql",
"version": "23.0.3.2",
"overwrite.cli.url": "https:\/\/n2.rkn.ovh",
"dbname": "***REMOVED SENSITIVE VALUE***",
"dbhost": "***REMOVED SENSITIVE VALUE***",
"dbport": "",
"dbtableprefix": "oc_",
"mysql.utf8mb4": true,
"dbuser": "***REMOVED SENSITIVE VALUE***",
"dbpassword": "***REMOVED SENSITIVE VALUE***",
"installed": true,
"default_language": "fr",
"default_phone_region": "FR",
"knowledgebaseenabled": true,
"enable_previews": true,
"enabledPreviewProviders": [
"OC\\Preview\\Movie",
"OC\\Preview\\PNG",
"OC\\Preview\\JPEG",
"OC\\Preview\\GIF",
"OC\\Preview\\BMP",
"OC\\Preview\\XBitmap",
"OC\\Preview\\MP3",
"OC\\Preview\\MP4",
"OC\\Preview\\TXT",
"OC\\Preview\\MarkDown",
"OC\\Preview\\PDF"
],
"mail_smtpmode": "smtp",
"mail_smtpauthtype": "LOGIN",
"mail_smtpsecure": "ssl",
"mail_from_address": "***REMOVED SENSITIVE VALUE***",
"mail_domain": "***REMOVED SENSITIVE VALUE***",
"mail_smtpauth": 1,
"mail_smtphost": "***REMOVED SENSITIVE VALUE***",
"mail_smtpport": "465",
"mail_smtpname": "***REMOVED SENSITIVE VALUE***",
"mail_smtppassword": "***REMOVED SENSITIVE VALUE***",
"cache_chunk_gc_ttl": 86400,
"memcache.local": "\\OC\\Memcache\\Redis",
"redis": {
"host": "***REMOVED SENSITIVE VALUE***",
"port": 6379,
"password": "***REMOVED SENSITIVE VALUE***",
"timeout": 1.5
},
"memcache.locking": "\\OC\\Memcache\\Redis",
"filelocking.enabled": true,
"filelocking.ttl": 3600,
"check_data_directory_permissions": true,
"twofactor_enforced": "true",
"twofactor_enforced_groups": [
"admin",
"Users"
],
"twofactor_enforced_excluded_groups": [],
"maintenance": false
}
Are you using external storage, if yes which one: none, but a raid6 mdadm/lvm2 mounted as /mnt/raid6/nextcloud
Are you using encryption: no, but HTTPS and UF2 Auth for clients.
Are you using an external user-backend, if yes which one: no
**Others configuration
No alp1/Alp2, i use openssl 1.1.1.c with Letsencrypt for SSL certs.
Sorry, no caddyfile. I manually install all. This is a dedicated homemade server…
Redis configuration:
bind 127.0.0.1 ::1
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis/redis-server.pid
loglevel verbose
logfile /var/log/redis/redis-server.log
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir /var/lib/redis
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
requirepass Er@x140169!
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
appendonly no
appendfilename "appendonly.aof"
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
latency-monitor-threshold 0
hash-max-ziplist-entries 512
hash-max-ziplist-value 6
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
Redis log:
2560980:C 21 Apr 2022 15:52:52.385 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2560980:C 21 Apr 2022 15:52:52.385 # Redis version=6.0.16, bits=64, commit=00000000, modified=0, pid=2560980, just started
2560980:C 21 Apr 2022 15:52:52.385 # Configuration loaded
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 6.0.16 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 2560980
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
2560980:M 21 Apr 2022 15:52:52.389 # Server initialized
2560980:M 21 Apr 2022 15:52:52.389 * Loading RDB produced by version 6.0.16
2560980:M 21 Apr 2022 15:52:52.389 * RDB age 5 seconds
2560980:M 21 Apr 2022 15:52:52.389 * RDB memory usage when created 6.25 Mb
2560980:M 21 Apr 2022 15:52:52.404 * DB loaded from disk: 0.015 seconds
2560980:M 21 Apr 2022 15:52:52.404 * Ready to accept connections
2560980:M 21 Apr 2022 15:52:52.405 - DB 0: 6683 keys (282 volatile) in 8192 slots HT.
Apache2 configuration (obviously redacted)
/etc/apache2# nano apache2.conf
# Global configuration
ServerName **redacted**
Protocols h2c http/1.1
Protocols h2 http/1.1
ServerTokens Prod
ServerSignature Off
DefaultRuntimeDir ${APACHE_RUN_DIR}
PidFile ${APACHE_PID_FILE}
Timeout 800
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 20
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
# logging ip needed for fail2ban parsing (deprecated)
HostnameLookups Off
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf
Include ports.conf
# better security enable in vhost files
<Directory />
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
<Directory /usr/share>
AllowOverride All
Require all granted
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks
# Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
AccessFileName .htaccess
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
IncludeOptional conf-enabled/*.conf
IncludeOptional sites-enabled/*.conf
#EOF
/etc/apache2/sites-enabled# nano 000-default.conf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
Protocols h2 http/1.1
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =*redacted*
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
#EOF
/etc/apache2/sites-enabled# nano 000-default-le-ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
Protocols h2 h2c http/1.1
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Include /etc/letsencrypt/options-ssl-apache.conf
ServerName *redacted*
SetEnv proxy-sendcl 1
Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains"
SSLCertificateFile /etc/letsencrypt/live/*redacted*-0001/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/*redacted*-0001/privkey.pem
</VirtualHost>
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
SSLHonorCipherOrder on
SSLSessionTickets off
SSLOptions +StrictRequire
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)
Redirect 301 /.well-known/carddav /remote.php/dav
Redirect 301 /.well-known/caldav /remote.php/dav
</IfModule mod_ssl.c>
#EOF
Letsencrypt
sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot run -a webroot -i apache -w /var/www/html -d n2.rkn.ovh --rsa-key-size 4096
mdadm
# mdadm.conf
HOMEHOST <system>
MAILADDR root
ARRAY /dev/md0 metadata=1.2 name=n2:0 UUID=0f193445:5c2d5a41:ddbafec2:71fe9019
# This configuration 07 May 2021 mdadm –detail –scan >> /etc/mdadm/mdadm.con
# mdadm -–detail -–scan /dev/md0 >> /etc/mdadm/mdadm.con
LVM
/etc/lvm/backup# nano VG_raid6
contents = "Text Format Volume Group"
version = 1
description = "Created *after* executing 'lvcreate -nLV_nextdata -L10737418240k -p rw -C n VG_raid6'"
creation_host = "n2" # Linux n2 5.10.0-6-amd64 #1 SMP Debian 5.10.28-1 (2021-04-09) x86_64
creation_time = 1620421024 # Fri May 7 22:57:04 2021
VG_raid6 {
id = "tokSmy-W4U7-Uely-FimY-5ERy-Xw12-slVyDn"
seqno = 2
format = "lvm2" # informational
status = ["RESIZEABLE", "READ", "WRITE"]
flags = []
extent_size = 8192 # 4 Megabytes
max_lv = 0
max_pv = 0
metadata_copies = 0
physical_volumes {
pv0 {
id = "5A30CH-FaeE-izpV-Tlsc-TMAN-u7cY-TEtJ1A"
device = "/dev/md0" # Hint only
status = ["ALLOCATABLE"]
flags = []
dev_size = 23441310720 # 10.9157 Terabytes
pe_start = 3072
pe_count = 2861487 # 10.9157 Terabytes
}
}
logical_volumes {
LV_nextdata {
id = "0HVGBm-LMM6-dYYQ-y5me-zMPm-1Qlg-8weqYb"
status = ["READ", "WRITE", "VISIBLE"]
flags = []
creation_time = 1620421024 # 2021-05-07 22:57:04 +0200
creation_host = "n2"
segment_count = 1
segment1 {
start_extent = 0
extent_count = 2621440 # 10 Terabytes
type = "striped"
stripe_count = 1 # linear
stripes = [
"pv0", 0
]
}
}
}
}
contents = "Text Format Volume Group"
version = 1
description = "Created *after* executing 'vgcfgbackup'"
creation_host = "n2" # Linux n2 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64
creation_time = 1620321828 # Thu May 6 19:23:48 2021
n2-vg {
id = "LNrIvZ-atn0-Bw2n-oL5O-YewP-1zm8-ZiT2Sg"
seqno = 3
format = "lvm2" # informational
status = ["RESIZEABLE", "READ", "WRITE"]
flags = []
extent_size = 8192 # 4 Megabytes
max_lv = 0
max_pv = 0
metadata_copies = 0
physical_volumes {
pv0 {
id = "xjDUeE-E5EK-Ylia-AcSw-Ht7I-DQLh-tW6PN7"
device = "/dev/sdg3" # Hint only
status = ["ALLOCATABLE"]
flags = []
dev_size = 935651328 # 446.153 Gigabytes
pe_start = 2048
pe_count = 114215 # 446.152 Gigabytes
}
}
logical_volumes {
root {
id = "xuoBH5-lyu2-2Ny3-C5n1-73ZJ-X5vz-noeFiJ"
status = ["READ", "WRITE", "VISIBLE"]
flags = []
creation_time = 1620320455 # 2021-05-06 19:00:55 +0200
creation_host = "n2"
segment_count = 1
segment1 {
start_extent = 0
extent_count = 113970 # 445.195 Gigabytes
type = "striped"
stripe_count = 1 # linear
stripes = [
"pv0", 0
]
}
}
swap_1 {
id = "RnlEyd-qsiP-GCCt-CVBZ-Iuhe-kTmC-jtJdQ3"
status = ["READ", "WRITE", "VISIBLE"]
flags = []
creation_time = 1620320455 # 2021-05-06 19:00:55 +0200
creation_host = "n2"
segment_count = 1
segment1 {
start_extent = 0
extent_count = 245 # 980 Megabytes
type = "striped"
stripe_count = 1 # linear
stripes = [
"pv0", 113970
]
}
}
}
}
PHP
As php 7 to 8 are almost the same, here the conf files ( redacted ) for help…
Remember, some things are server relative, so fine tuning will be needed…
- PHP8.0 apache2 conf files
Short trick, the apache/cli/ are the same…
located /etc/php/8.0/apache2
[PHP]
; minimum conf file for my nextcloud test plateform, redacted.
engine = On
short_open_tag = Off
precision = 14
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off
unserialize_callback_func =
serialize_precision = -1
disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
disable_classes =
zend.enable_gc = On
zend.exception_ignore_args = On
zend.exception_string_param_max_len = 0
expose_php = Off
max_execution_time = 900
max_input_time = 300
memory_limit = 1024M
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off
display_startup_errors = Off
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
variables_order = "GPCS"
request_order = "GP"
register_argc_argv = Off
auto_globals_jit = On
post_max_size = 999GB
auto_append_file =
default_mimetype = "text/html"
default_charset = "UTF-8"
doc_root =
user_dir =
enable_dl = Off
file_uploads = On
upload_max_filesize = 999GB
max_file_uploads = 20
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60
zend_extension=opcache
cli_server.color = On
date.timezone = Europe/Paris
[Pdo_mysql]
pdo_mysql.default_socket=
[mail function]
SMTP = localhost
smtp_port = 25
mail.add_x_header = Off
[ODBC]
odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode = 1
[Session]
session.save_handler = redis
session.save_path = "tcp://localhost:6379?auth=redacted"
session.use_strict_mode = 0
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.cookie_samesite =
session.serialize_handler = php
session.gc_probability = 0
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.referer_check =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.sid_length = 26
session.trans_sid_tags = "a=href,area=href,frame=src,form="
session.sid_bits_per_character = 5
[Assertion]
zend.assertions = -1
[Tidy]
tidy.clean_output = Off
[soap]
soap.wsdl_cache_enabled=1
soap.wsdl_cache_dir="/tmp"
soap.wsdl_cache_ttl=86400
soap.wsdl_cache_limit = 5
[opcache]
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=1
opcache.save_comments=1
- php-fpm
located /etc/php/8.0/fpm
[global]
pid = /run/php/php8.0-fpm.pid
error_log = /var/log/php8.0-fpm.log
include=/etc/php/8.0/fpm/pool.d/*.conf
pool.d www.conf
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.process_idle_timeout = 99s;
;pm.max_requests = 500
;pm.status_listen = 127.0.0.1:9001
Misc
Debian cleaning logs:
The self maintenance method is to vacuum the logs by size or time.
EX: Retain only the past two days:
journalctl --vacuum-time=2d
EOF
Here is also a list of the package installed on my Debian bulleyes: