Nextcloud 15 installation guide (Ubuntu/Apache2)


Nextcloud installation guide


Following this guide you will be able to install and configure Nextcloud 15 (latest) based on Ubuntu 18.04.1 LTS, Apache 2.4.x (mpm_event, http2), PHP 7.3, MariaDB 10.3, Redis, fail2ban, ufw and achieve an A+ rating from both, Nextcloud and Qualys SSL Labs. We will request and implement the ssl certificate from Let’s Encrypt in this guide. You only have to ammend the red marked values (YOUR.DEDYN.IO, 192.168.2.x, 22) regarding your environment!


Last Updates:

January 30th, 2019:
– removed /upload_tmp from PHP to prevent Nextcloud errors

… the entire update history


Pre-requirements

From my perspective the requirements for this guide may be rated as low: you only have to

  • provide a 64Bit Server (e.g. Intel NUC),
  • forward two ports (80 and 443) from internet (your router e.g. FritzBox or Speedport) to your internal Nextcloud server
  • and install the operating system Ubuntu 18.04. LTS (64Bit).

Preparation:

sudo -s
apt update && apt upgrade -y
apt install software-properties-common && apt install -y zip unzip screen curl ffmpeg
add-apt-repository -y ppa:ondrej/php && add-apt-repository -y ppa:ondrej/apache2 && add-apt-repository -y ppa:certbot/certbot
apt update && apt upgrade -y && apt autoremove -y && apt autoclean -y

Determine the uid of your www-data user by issuing

id www-data

and only if it differs from ‘uid=33‘ replace the ‘uid=33‘ in the following rows properly before executing them!

sed -i '$atmpfs /usr/local/tmp/apc tmpfs defaults,uid=33,size=300M,noatime,nosuid,nodev,noexec,mode=1777 0 0' /etc/fstab
sed -i '$atmpfs /usr/local/tmp/sessions tmpfs defaults,uid=33,size=300M,noatime,nosuid,nodev,noexec,mode=1777 0 0' /etc/fstab
OPTIONAL:
sed -i '$atmpfs /tmp tmpfs defaults,noatime,nosuid,nodev,noexec,mode=1777 0 0' /etc/fstab
sed -i '$atmpfs /var/tmp tmpfs defaults,noatime,nosuid,nodev,noexec,mode=1777 0 0' /etc/fstab
mkdir -p /var/www /var/nc_data /usr/local/tmp/sessions /usr/local/tmp/apc
chown -R www-data:www-data /var/nc_data /var/www
chown -R www-data:root /usr/local/tmp/sessions /usr/local/tmp/apc
mount -a

MariaDB

If you are interested in Postgresql instead of MariaDB please have a look here.
First we add the MariaDB repository to gain long term support using MariaDB 10.3 – maintained until 2023:

apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
add-apt-repository 'deb [arch=amd64,arm64] http://ftp.hosteurope.de/mirror/mariadb.org/repo/10.3/ubuntu bionic main'

Update your system and install MariaDB:

apt update && apt install mariadb-server -y

Verify your database server version:

mysql --version

An output like

mysql  Ver 15.1 Distrib 10.3.12-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2

should appear.

Secure MariaDB:

mysql_secure_installation
Enter current password for root (enter for none): <ENTER> or type the password
Set root password? [Y/n] Y

If already set during the MariaDB installation you will be asked wether to change or keep the password

Remove anonymous users? [Y/n] Y
Disallow root login remotely? [Y/n] Y
Remove test database and access to it? [Y/n] Y
Reload privilege tables now? [Y/n] Y

Configure MariaDB:

service mysql stop
mv /etc/mysql/my.cnf /etc/mysql/my.cnf.bak && vi /etc/mysql/my.cnf

Change the entire my.cnf-file to:

[client]
default-character-set = utf8mb4
port = 3306
socket = /var/run/mysqld/mysqld.sock

[mysqld_safe]
log_error=/var/log/mysql/mysql_error.log
nice = 0
socket = /var/run/mysqld/mysqld.sock

[mysqld]
basedir = /usr
bind-address = 127.0.0.1
binlog_format = ROW
bulk_insert_buffer_size = 16M
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
concurrent_insert = 2
connect_timeout = 5
datadir = /var/lib/mysql
default_storage_engine = InnoDB
expire_logs_days = 10
general_log_file = /var/log/mysql/mysql.log
general_log = 0
innodb_buffer_pool_size = 1024M
innodb_buffer_pool_instances = 1
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 32M
innodb_max_dirty_pages_pct = 90
innodb_file_per_table = 1
innodb_open_files = 400
innodb_io_capacity = 4000
innodb_flush_method = O_DIRECT
key_buffer_size = 128M
lc_messages_dir = /usr/share/mysql
lc_messages = en_US
log_bin = /var/log/mysql/mariadb-bin
log_bin_index = /var/log/mysql/mariadb-bin.index
log_error=/var/log/mysql/mysql_error.log
log_slow_verbosity = query_plan
log_warnings = 2
long_query_time = 1
max_allowed_packet = 16M
max_binlog_size = 100M
max_connections = 200
max_heap_table_size = 64M
myisam_recover_options = BACKUP
myisam_sort_buffer_size = 512M
port = 3306
pid-file = /var/run/mysqld/mysqld.pid
query_cache_limit = 2M
query_cache_size = 64M
query_cache_type = 1
query_cache_min_res_unit = 2k
read_buffer_size = 2M
read_rnd_buffer_size = 1M
skip-external-locking
skip-name-resolve
slow_query_log_file = /var/log/mysql/mariadb-slow.log
slow-query-log = 1
socket = /var/run/mysqld/mysqld.sock
sort_buffer_size = 4M
table_open_cache = 400
thread_cache_size = 128
tmp_table_size = 64M
tmpdir = /tmp
transaction_isolation = READ-COMMITTED
user = mysql
wait_timeout = 600

[mysqldump]
max_allowed_packet = 16M
quick
quote-names

[isamchk]
!include /etc/mysql/mariadb.cnf
!includedir /etc/mysql/conf.d/
key_buffer = 16M

Restart MariaDB:

service mysql restart

Create the database and the user:

mysql -uroot -p -e "CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER nextcloud@localhost identified by 'nextcloud'; GRANT ALL PRIVILEGES on nextcloud.* to nextcloud@localhost; FLUSH privileges;"

Verify the transaction Isolation level was set to READ_Commit and the collation was set to UTF8MB4 properly:

mysql -h localhost -uroot -p -e "SELECT @@TX_ISOLATION; SELECT SCHEMA_NAME 'database', default_character_set_name 'charset', DEFAULT_COLLATION_NAME 'collation' FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='nextcloud'"

If the resultset will be “READ-COMMITTED” and “utf8mb4_general_ci” as shown go ahead with the installation of Apache, PHP and Redis.

Install Apache2, PHP and Redis-Server:

apt install libapache2-mod-php7.3 php7.3-cli php7.3-common php7.3-mbstring php7.3-gd php7.3-intl php7.3-xml php7.3-mysql php7.3-zip php7.3-dev php7.3-curl php7.3-fpm php7.3-json php7.3-bz2 php7.3-ldap php-dompdf php-apcu imagemagick php-imagick php-smbclient redis-server php-redis unzip -y

Disable PHP 7.3 and mpm_prefork and enable php7.3-fpm with mpm_event:

a2dismod php7.3 && a2dismod mpm_prefork && a2enmod proxy_fcgi setenvif mpm_event && service apache2 restart
a2enconf php7.3-fpm && service apache2 restart

Download and extract the latest Nextcloud Release:

wget https://download.nextcloud.com/server/releases/latest.zip
unzip latest.zip && mv nextcloud/ /var/www/html/ && chown -R www-data:www-data /var/www/html/nextcloud && rm latest.zip

Redis

Change configuration and group membership:

cp /etc/redis/redis.conf /etc/redis/redis.conf.bak
sed -i "s/port 6379/port 0/" /etc/redis/redis.conf
sed -i s/\#\ unixsocket/\unixsocket/g /etc/redis/redis.conf
sed -i "s/unixsocketperm 700/unixsocketperm 770/" /etc/redis/redis.conf 
sed -i "s/# maxclients 10000/maxclients 512/" /etc/redis/redis.conf
usermod -a -G redis www-data
cp /etc/sysctl.conf /etc/sysctl.conf.bak && sed -i '$avm.overcommit_memory = 1' /etc/sysctl.conf

Enable further Apache modules:

a2enmod rewrite headers env dir mime && service apache2 restart

Prepare your server for Let’s Encrypt:

apt install python-certbot-apache -y
cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/001-nextcloud.conf
rm /etc/apache2/sites-available/000-default.conf && rm /etc/apache2/sites-enabled/000-default.conf

Modify the initial Nextcloud vhost:

vi /etc/apache2/sites-available/001-nextcloud.conf

Make ammendments to the following rows:

ServerName your.dedyn.io
ServerAdmin webmaster@dedyn.io
DocumentRoot /var/www/html/nextcloud

Request your certificates by issuing

a2ensite 001-nextcloud.conf && service apache2 restart && certbot --apache

Choose ‘1’, then ‘2’ as shown in the screenshot:

Make further adjustements to the intial vhost:

mv /etc/apache2/sites-available/001-nextcloud.conf /etc/apache2/sites-available/001-nextcloud.conf.le-bak
vi /etc/apache2/sites-available/001-nextcloud.conf

Paste all the following rows and replace the red ones:

<VirtualHost *:80>
Servername your.dedyn.io
ServerAdmin mail@dedyn.io
DocumentRoot /var/www/html/nextcloud
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =your.dedyn.io
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

Make further adjustements to the intial vhost:

cp /etc/apache2/sites-available/001-nextcloud-le-ssl.conf /etc/apache2/sites-available/001-nextcloud-le-ssl.conf.bak
vi /etc/apache2/sites-available/001-nextcloud-le-ssl.conf

Paste all the following rows and replace the red ones:

<IfModule mod_ssl.c>
<VirtualHost *:443>
SSLEngine on
SSLOptions +StrictRequire
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined
LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common
ServerAdmin mail@dedyn.io
DocumentRoot /var/www/html/nextcloud
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
ServerName your.dedyn.io
SSLCertificateFile /etc/letsencrypt/live/your.dedyn.io/fullchain.pem
SSLCACertificateFile /etc/letsencrypt/live/your.dedyn.io/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/your.dedyn.io/privkey.pem
<Directory /var/www/html/nextcloud/>
Options +FollowSymlinks
AllowOverride All
<IfModule mod_dav.c>
Dav off
</IfModule>
SetEnv HOME /var/www/html/nextcloud
SetEnv HTTP_HOME /var/www/html/nextcloud
</Directory>
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=15768000; preload"
Header set Referrer-Policy "strict-origin-when-cross-origin"
Header set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Feature-Policy "accelerometer 'none'; autoplay 'self'; geolocation 'none'; midi 'none'; notifications 'self'; push 'self'; sync-xhr 'self' https://your.dedyn.io; microphone 'self'; camera 'self'; magnetometer 'none'; gyroscope 'none'; speaker 'self'; vibrate 'self'; fullscreen 'self'; payment 'none'; usb 'none'"
</IfModule>
</VirtualHost>
SSLProtocol TLSv1.2
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK:!AES128
SSLHonorCipherOrder on
SSLCompression off
SSLSessionTickets off
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)
SSLOpenSSLConfCmd Curves secp384r1
SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem"
</IfModule>

Enhance security:

screen -S dhparam
openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096

To leave screen press STRG+A following by ‘d’ – to resume run screen -r. Please be patient, it will take a while. When dhparam was generated just modify the apache.conf:

vi /etc/apache2/apache2.conf

At the beginning of this file add the following new row

ServerName your.dedyn.io

and replace ‘AllowOverride None‘ to ‘All‘ as follows in the shown section:

...
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
...

Restart apache by issuing

service apache2 restart

Tune your PHP:

cp /etc/php/7.3/fpm/pool.d/www.conf /etc/php/7.3/fpm/pool.d/www.conf.bak
cp /etc/php/7.3/cli/php.ini /etc/php/7.3/cli/php.ini.bak
cp /etc/php/7.3/fpm/php.ini /etc/php/7.3/fpm/php.ini.bak
cp /etc/php/7.3/fpm/php-fpm.conf /etc/php/7.3/fpm/php-fpm.conf.bak
sed -i "s/;env\[HOSTNAME\] = /env[HOSTNAME] = /" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/;env\[TMP\] = /env[TMP] = /" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/;env\[TMPDIR\] = /env[TMPDIR] = /" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/;env\[TEMP\] = /env[TEMP] = /" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/;env\[PATH\] = /env[PATH] = /" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/pm.max_children = .*/pm.max_children = 240/" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/pm.start_servers = .*/pm.start_servers = 20/" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/pm.min_spare_servers = .*/pm.min_spare_servers = 10/" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/pm.max_spare_servers = .*/pm.max_spare_servers = 20/" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/;pm.max_requests = 500/pm.max_requests = 500/" /etc/php/7.3/fpm/pool.d/www.conf
sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/7.3/cli/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 1800/" /etc/php/7.3/cli/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/7.3/cli/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/7.3/cli/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/7.3/cli/php.ini
sed -i "s/max_file_uploads =.*/max_file_uploads = 100/" /etc/php/7.3/cli/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/7.3/cli/php.ini
sed -i "s/;session.cookie_secure.*/session.cookie_secure = True/" /etc/php/7.3/cli/php.ini
sed -i "s/;session.save_path =.*/session.save_path = \"N;700;\/usr\/local\/tmp\/sessions\"/" /etc/php/7.3/cli/php.ini
sed -i '$aapc.enable_cli = 1' /etc/php/7.3/cli/php.ini
sed -i "s/memory_limit = 128M/memory_limit = 512M/" /etc/php/7.3/fpm/php.ini
sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/7.3/fpm/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 1800/" /etc/php/7.3/fpm/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/7.3/fpm/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/7.3/fpm/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/7.3/fpm/php.ini
sed -i "s/max_file_uploads =.*/max_file_uploads = 100/" /etc/php/7.3/fpm/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/7.3/fpm/php.ini
sed -i "s/;session.cookie_secure.*/session.cookie_secure = True/" /etc/php/7.3/fpm/php.ini
sed -i "s/;opcache.enable=.*/opcache.enable=1/" /etc/php/7.3/fpm/php.ini
sed -i "s/;opcache.enable_cli=.*/opcache.enable_cli=1/" /etc/php/7.3/fpm/php.ini
sed -i "s/;opcache.memory_consumption=.*/opcache.memory_consumption=128/" /etc/php/7.3/fpm/php.ini
sed -i "s/;opcache.interned_strings_buffer=.*/opcache.interned_strings_buffer=8/" /etc/php/7.3/fpm/php.ini
sed -i "s/;opcache.max_accelerated_files=.*/opcache.max_accelerated_files=10000/" /etc/php/7.3/fpm/php.ini
sed -i "s/;opcache.revalidate_freq=.*/opcache.revalidate_freq=1/" /etc/php/7.3/fpm/php.ini
sed -i "s/;opcache.save_comments=.*/opcache.save_comments=1/" /etc/php/7.3/fpm/php.ini
sed -i "s/;session.save_path =.*/session.save_path = \"N;700;\/usr\/local\/tmp\/sessions\"/" /etc/php/7.3/fpm/php.ini
sed -i "s/;emergency_restart_threshold =.*/emergency_restart_threshold = 10/" /etc/php/7.3/fpm/php-fpm.conf
sed -i "s/;emergency_restart_interval =.*/emergency_restart_interval = 1m/" /etc/php/7.3/fpm/php-fpm.conf
sed -i "s/;process_control_timeout =.*/process_control_timeout = 10s/" /etc/php/7.3/fpm/php-fpm.conf
sed -i '$aapc.enabled=1' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.file_update_protection=2' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.optimization=0' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.shm_size=256M' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.include_once_override=0' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.shm_segments=1' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.ttl=7200' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.user_ttl=7200' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.gc_ttl=3600' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.num_files_hint=1024' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.enable_cli=0' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.max_file_size=5M' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.cache_by_default=1' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.use_request_time=1' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.slam_defense=0' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.mmap_file_mask=/usr/local/tmp/apc/apc.XXXXXX' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.stat_ctime=0' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.canonicalize=1' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.write_lock=1' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.report_autofilter=0' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.rfc1867=0' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.rfc1867_prefix =upload_' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.rfc1867_name=APC_UPLOAD_PROGRESS' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.rfc1867_freq=0' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.rfc1867_ttl=3600' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.lazy_classes=0' /etc/php/7.3/fpm/php.ini
sed -i '$aapc.lazy_functions=0' /etc/php/7.3/fpm/php.ini
sed -i "s/09,39.*/# &/" /etc/cron.d/php
(crontab -l ; echo "09,39 * * * * /usr/lib/php/sessionclean 2>&1") | crontab -u root -

Nextcloud Installation:

Open your browser and call to configure Nextcloud. Enter the following values:

https://your.dedyn.io

Username: Your-NC-Admin
Password*: Your-NC_Password!

Data folder: /var/nc_data
Datenbankuser: nextcloud
DB-Passwort*: nextcloud
Datenbank-Name: nextcloud
Host: localhost

After a few seconds Nexcloud will be installed and you will be redirected to Nextclouds file app. Please log out directly and make further ammendments.

sudo -u www-data vi /var/www/html/nextcloud/.htaccess

Replace all or replace the red ones:

<IfModule mod_headers.c>
<IfModule mod_setenvif.c>
<IfModule mod_fcgid.c>
SetEnvIfNoCase ^Authorization$ "(.+)" XAUTHORIZATION=$1
RequestHeader set XAuthorization %{XAUTHORIZATION}e env=XAUTHORIZATION
</IfModule>
<IfModule mod_proxy_fcgi.c>
SetEnvIfNoCase Authorization "(.+)" HTTP_AUTHORIZATION=$1
</IfModule>
</IfModule>

<IfModule mod_env.c>
# Add security and privacy related headers
Header set X-Content-Type-Options "nosniff"
Header set X-XSS-Protection "1; mode=block"
Header set X-Robots-Tag "none"
Header set X-Download-Options "noopen"
Header set X-Permitted-Cross-Domain-Policies "none"
Header set Referrer-Policy "no-referrer"
SetEnv modHeadersAvailable true
</IfModule>

# Add cache control for static resources
<FilesMatch "\.(css|js|svg|gif)$">
Header set Cache-Control "max-age=15778463"
</FilesMatch>

# Let browsers cache WOFF files for a week
<FilesMatch "\.woff2?$">
Header set Cache-Control "max-age=604800"
</FilesMatch>
</IfModule>
<IfModule mod_php5.c>
php_value upload_max_filesize 10240M
php_value post_max_size 10240M
php_value memory_limit 512M
php_value mbstring.func_overload 0
php_value always_populate_raw_post_data -1
php_value default_charset 'UTF-8'
php_value output_buffering 'Off'
<IfModule mod_env.c>
SetEnv htaccessWorking true
</IfModule>
</IfModule>
<IfModule mod_php7.c>
php_value upload_max_filesize 10240M
php_value post_max_size 10240M
php_value memory_limit 512M
php_value mbstring.func_overload 0
php_value default_charset 'UTF-8'
php_value output_buffering 'Off'
<IfModule mod_env.c>
SetEnv htaccessWorking true
</IfModule>
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} DavClnt
RewriteRule ^$ /remote.php/webdav/ [L,R=302]
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteRule ^\.well-known/host-meta /public.php?service=host-meta [QSA,L]
RewriteRule ^\.well-known/host-meta\.json /public.php?service=host-meta-json [QSA,L]
RewriteRule ^\.well-known/webfinger /public.php?service=webfinger [QSA,L]
RewriteRule ^\.well-known/carddav /remote.php/dav/ [R=301,L]
RewriteRule ^\.well-known/caldav /remote.php/dav/ [R=301,L]
RewriteRule ^remote/(.*) remote.php [QSA,L]
RewriteRule ^(?:build|tests|config|lib|3rdparty|templates)/.* - [R=404,L]
RewriteCond %{REQUEST_URI} !^/\.well-known/(acme-challenge|pki-validation)/.*
RewriteRule ^(?:\.|autotest|occ|issue|indie|db_|console).* - [R=404,L]
</IfModule>
<IfModule mod_mime.c>
AddType image/svg+xml svg svgz
AddEncoding gzip svgz
</IfModule>
<IfModule mod_dir.c>
DirectoryIndex index.php index.html
</IfModule>
AddDefaultCharset utf-8
Options -Indexes
<IfModule pagespeed_module>
ModPagespeed Off
</IfModule>
#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####

ErrorDocument 403 /
ErrorDocument 404 /
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]
RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]
RewriteCond %{REQUEST_FILENAME} !\.(css|js|svg|gif|png|html|ttf|woff2?|ico|jpg|jpeg)$
RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$
RewriteCond %{REQUEST_FILENAME} !core/img/manifest.json$
RewriteCond %{REQUEST_FILENAME} !/remote.php
RewriteCond %{REQUEST_FILENAME} !/public.php
RewriteCond %{REQUEST_FILENAME} !/cron.php
RewriteCond %{REQUEST_FILENAME} !/core/ajax/update.php
RewriteCond %{REQUEST_FILENAME} !/status.php
RewriteCond %{REQUEST_FILENAME} !/ocs/v1.php
RewriteCond %{REQUEST_FILENAME} !/ocs/v2.php
RewriteCond %{REQUEST_FILENAME} !/robots.txt
RewriteCond %{REQUEST_FILENAME} !/updater/
RewriteCond %{REQUEST_FILENAME} !/ocs-provider/
RewriteCond %{REQUEST_URI} !^/\.well-known/(acme-challenge|pki-validation)/.*
RewriteRule . index.php [PT,E=PATH_INFO:$1]
RewriteBase /
<IfModule mod_env.c>
SetEnv front_controller_active true
<IfModule mod_dir.c>
DirectorySlash off
</IfModule>
</IfModule>
</IfModule>

Then adjust Nextclouds config.php.

sudo -u www-data cp /var/www/html/nextcloud/config/config.php /var/www/html/nextcloud/config/config.php.bak

Expand your Nextcloud config.php:

sudo -u www-data sed -i 's/^[ ]*//' /var/www/html/nextcloud/config/config.php
sudo -u www-data sed -i '/);/d' /var/www/html/nextcloud/config/config.php
sudo -u www-data cat <<EOF >>/var/www/html/nextcloud/config/config.php
'activity_expire_days' => 14,
'auth.bruteforce.protection.enabled' => true,
'blacklisted_files' => 
array (
0 => '.htaccess',
1 => 'Thumbs.db',
2 => 'thumbs.db',
),
'cron_log' => true,
'enable_previews' => true,
'enabledPreviewProviders' => 
array (
0 => 'OC\\Preview\\PNG',
1 => 'OC\\Preview\\JPEG',
2 => 'OC\\Preview\\GIF',
3 => 'OC\\Preview\\BMP',
4 => 'OC\\Preview\\XBitmap',
5 => 'OC\\Preview\\Movie',
6 => 'OC\\Preview\\PDF',
7 => 'OC\\Preview\\MP3',
8 => 'OC\\Preview\\TXT',
9 => 'OC\\Preview\\MarkDown',
),
'filesystem_check_changes' => 0,
'filelocking.enabled' => 'true',
'htaccess.RewriteBase' => '/',
'integrity.check.disabled' => false,
'knowledgebaseenabled' => false,
'logfile' => '/var/nc_data/nextcloud.log',
'loglevel' => 2,
'logtimezone' => 'Europe/Berlin',
'log_rotate_size' => 104857600,
'maintenance' => false,
'memcache.local' => '\\OC\\Memcache\\APCu',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'overwriteprotocol' => 'https',
'preview_max_x' => 1024,
'preview_max_y' => 768,
'preview_max_scale_factor' => 1,
'redis' => 
array (
'host' => '/var/run/redis/redis-server.sock',
'port' => 0,
'timeout' => 0.0,
),
'quota_include_external_storage' => false,
'share_folder' => '/Shares',
'skeletondirectory' => '',
'theme' => '',
'trashbin_retention_obligation' => 'auto, 7',
'updater.release.channel' => 'stable',
);
EOF

Edit the .user.ini:

sudo -u www-data sed -i "s/upload_max_filesize=.*/upload_max_filesize=10240M/" /var/www/html/nextcloud/.user.ini
sudo -u www-data sed -i "s/post_max_size=.*/post_max_size=10240M/" /var/www/html/nextcloud/.user.ini
sudo -u www-data sed -i "s/output_buffering=.*/output_buffering='Off'/" /var/www/html/nextcloud/.user.ini
service php7.3-fpm restart && service redis-server restart && service apache2 restart

Adjust Nextcloud

sudo -u www-data php /var/www/html/nextcloud/occ config:system:set 'auth.bruteforce.protection.enabled' --value=false
sudo -u www-data php /var/www/html/nextcloud/occ app:disable survey_client
sudo -u www-data php /var/www/html/nextcloud/occ app:disable firstrunwizard
sudo -u www-data php /var/www/html/nextcloud/occ app:enable admin_audit
sudo -u www-data php /var/www/html/nextcloud/occ app:enable files_pdfviewer

Optimize your Nextcloud once (a) and regulary (b) using a script

(a)

/usr/sbin/service apache2 stop
sudo -u www-data php /var/www/html/nextcloud/occ db:add-missing-indices
sudo -u www-data php /var/www/html/nextcloud/occ db:convert-filecache-bigint
/usr/sbin/service apache2 start

(infos: BigInt, missing indices)

(b)

vi /root/optimize.sh
#!/bin/bash
redis-cli -s /var/run/redis/redis-server.sock <<EOF
FLUSHALL
quit
EOF
sudo -u www-data php /var/www/html/nextcloud/occ files:scan --all
sudo -u www-data php /var/www/html/nextcloud/occ files:scan-app-data
exit 0

Save the script and mark it as executable

chmod +x /root/optimize.sh

Issue the optimize.sh script initially:

/root/optimize.sh

Add Nextcloud cronjobs for www-data and root

For www-data:

crontab -u www-data -e

Paste the following rows

*/15 * * * * php -f /var/www/html/nextcloud/cron.php > /dev/null 2>&1

For root:

crontab -e

Paste the follwoing rows:

5 1 * * * /root/optimize.sh > /dev/null 2>&1

Don’t forget to switch from Ajax to Cron in Nextclouds-Adminpanel or use Nextcloud CLI to switch immediately:

sudo -u www-data php /var/www/html/nextcloud/occ background:cron

Modify the mpm_event.conf

vi /etc/apache2/mods-available/mpm_event.conf

Change the “MaxConnectionsPerChild” value to 1000:

StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 1000

At least we will enable http2 by issuing

a2enmod http2 && service php7.3-fpm restart && service apache2 restart

and create a http2.conf with few settings:

vi /etc/apache2/conf-available/http2.conf

Paste all the following rows:

<IfModule http2_module>
Protocols h2 h2c http/1.1
H2Direct on
H2StreamMaxMemSize 5120000000
</IfModule>

and enable this configuration by issuing

a2enconf http2 && service apache2 restart

Finally we will secure Apache to a minimum level by disabling Apaches status module (as long as you won’t need it in particular) and altering the security.conf:

a2dismod status && vi /etc/apache2/conf-available/security.conf

Change the values to the red ones:

ServerTokens Prod
ServerSignature Off
TraceEnable Off

and restart PHP, Apache2 and Redis one last time.

service php7.3-fpm restart && service redis-server restart && service apache2 restart

Nextcloud is now already secured, up and running! Beyond that we will harden the system using fail2ban and ufw. First we install and configure fail2ban and finally we will configure the firewall (ufw).

Install and configure fail2ban:

apt update && apt install fail2ban -y

Create the Nextcloud-filter:

vi /etc/fail2ban/filter.d/nextcloud.conf

Paste the following rows to the fail2ban filter for Nextcloud (or download as txt file to avoid WordPress-code-issues!):

[Definition]
failregex=^{"reqId":".*","remoteAddr":".*","app":"core","message":"Login failed: '.*' \(Remote IP: '<HOST>'\)","level":2,"time":".*"}$
            ^{"reqId":".*","level":2,"time":".*","remoteAddr":".*","app":"core".*","message":"Login failed: '.*' \(Remote IP: '<HOST>'\)".*}$
            ^.*\"remoteAddr\":\"<HOST>\".*Trusted domain error.*$

Create a new jail:

vi /etc/fail2ban/jail.d/nextcloud.local

Paste the following rows:

[nextcloud]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = nextcloud
maxretry = 3
bantime = 36000
findtime = 36000
logpath = /var/nc_data/nextcloud.log

Re-start the fail2ban-service:

service fail2ban restart

Configure your ufw (uncomplicated firewall):

ufw allow 80/tcp && ufw allow 443/tcp && ufw allow 22/tcp

Enable and restart ufw by running

ufw enable && service ufw restart

Enjoy your personal data in your secured and hardened Nextcloud-Server!

Don’t forget to backup your Nextcloud

Find more instructions here: Nextcloud Backup and Restore



Carsten Rieger

Carsten Rieger

Carsten Rieger is a senior system engineer in full-time and also working as an IT freelancer. He is working with linux environments for more than 13 years, an Open Source enthusiast and highly motivated on linux installation and troubleshooting. Mostly working with Debian/Ubuntu Linux, Nginx and Apache web server, MariaDB/MySQL/PostgreSQL, PHP, Cloud infrastructure (e.g. Nextcloud) and other open source projects (e.g. Roundcube) and in voluntary work for the Dr. Michael & Angela Jacobi Stiftung for more than 7 years.

88 Responses

  1. kosar says:

    hello

    i don’t know what to replace them can some one help me

    Make ammendments to the following rows:

    ServerName your.dedyn.io
    ServerAdmin webmaster@dedyn.io
    DocumentRoot /var/www/html/nextcloud

    i get this when i changed them

    Site 001-nextcloud already enabled
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Plugins selected: Authenticator apache, Installer apache
    No names were found in your configuration files. Please enter in your domain

  2. Robert says:

    Hey,

    erstmal: Vielen Dank für die Anleitung, Sie hat bislang sehr weitergeholfen.
    Dennoch renne ich in ein Problem:

    The “X-Frame-Options” HTTP header is not set to “SAMEORIGIN”. This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.

    Wenn ich diese Anleitung nach dieser Option durchsuche, muss diese Einstellung innherlab der SSL vHost eingefügt werden, was ich auch gemacht hab.,

    Leider wird mir diese Meldung trd angezeigt, daher frage ich mich, ob du, oder andere hierzu eine Idee haben.

    Header always set Strict-Transport-Security “max-age=15768000; preload”
    Header set Referrer-Policy “-origin-when-cross-origin”
    Header set X-Content-Type-Options “nosniff”
    Header always set X-Frame-Options “SAMEORIGIN”
    Header always set Feature-Policy “accelerometer ‘none’; autoplay ‘self’; geolocation ‘none’; midi ‘none’; notifications ‘self’; push ‘self’; sync-xhr ‘self’ https://cloud.vegafinder.de; microphone ‘self’; camera ‘self’; magnetometer ‘none’; gyroscope ‘none’; speaker ‘self’; vibrate ‘self’; fullscreen ‘self’; payment ‘none’; usb ‘none'”

    Besten Dank soweit!

    LG

    • Robert says:

      Kleine Ergänzung im Bezug auf den anderen Kommentar zum Thema:

      Mein Zertifikat ist nicht selbssigniert, es kommt von Lets Enrypt.

  3. Frands Tjagvad says:

    Thanks for the best and most thorough guide to Nextcloud 15 on Ubuntu.

  4. Matthias says:

    Hi Carsten,
    ich habe das Problem das ich mich mit der mobile App und auch mit dem Client auf meinem Notebook nicht mit meinem Account einloggen kann.
    Wenn ich aber Nextcloud über den Browser öffne und mich mit den selben Credentals einlogge funktionierts.
    Hast du eine Idee?

    • Nein, das klingt nach 2FA (wobei ja die Anmeldung im Browser klappt???)…was steht denn im nextcloud.log?

      • Matthias says:

        Das nextcloud.log lässt sich darüber leider gar nicht aus :-/
        Sobald ich auf meiner iOS App die Option “zur alten Anmeldemethode zurückkehren” auswähle kann ich mich einloggen. Die 2FA ist nicht aktiviert. Was hat sich denn in der Anmeldemethode von Version 14 auf 15 geändert?

  5. Goblin171 says:

    Hi Carsten
    Ich habe leider in letzter zeit zimliche probleme mit redis und bekomme meine Cloud nicht mehr zum laufen,
    ich bekomme immer folgende fehler meldung

    redis-server.service: Can’t open PID file /var/run/redis/redis-server.pid (yet?) after start: No such file or directory

    für deine hilfe wäre ich dir sehr dankbar

  6. Karl-Heinz Trieglaff says:

    Moin, vergessen Sie meine dumme Anfrage von vorhin.bezüglich des Ordners rieger in letsencrypt/live/. War natürlich totaler Blödsinn. Trotzdem, der restart von apache 2 vor der Überschrift Tune your PHP zeigt immer eine aus mir unerklärlichem Grund eine Fehlermeldung und welche Addresse zum Aufruf von nextcloud ist richtig: https://kht-ohz.de oder https://kht-ohz.de/nextcloud?

    Pardon, aber ich beschäftige mich erst seit einem Jahr mit Ubuntu und bin 71 Jahre jung.

  7. Karl-Heinz Trieglaff says:

    Moin, moin,
    irgendwie bin ich mir unschlüssig über die Richtigkeit meiner Installation. Beim Aufruf im Browser https://kht-ohz.de/nextcloud erhalte ich die Antwort über ein ungültiges Zertifikat. https://kht-ohz dagegen zeigt unverzüglich die Startseite von nextcloud. Meine weiteren Recherchen haben ergeben, dass im Verzeichnis /etc/letsencrypt/live der Ordner apache2.c-rieger.de nicht vorhanden ist sondern nur kht-ohz.de. Der Fehler liegt sicherlich in der Anforderung des Zertifikates. Mit der Bitte um einen kleinen Hinweis.

  8. Heinz says:

    Hallo,

    Kompliment für diese tolle Anleitung, allerdings bin ich nicht sehr weit gekommen … ich glaube in der Ordnerstruktur der mariadb-repos hat sich etwas geändert.
    Der Befehl
    “sudo add-apt-repository ‘deb [arch=amd64,arm64] http://ftp.hosteurope.de/mirror/mariadb.org/repo/10.3/ubuntu bionic main’ ”
    führt mir leider zu einem python IndexError. Der Link selbst gibt im Browser einen Error 404

    Da ich mich selbst Anfänger schimpfe würde ich mich freuen, wenn der Schritt entsprechend aktualisiert werden könnte 🙂

    Viele Grüße,
    Heinz

    • Vergleiche bitte: MariaDB
      Vermutlich ein temporäres Problem?!

      • Heinz says:

        Vielen Dank für die schnelle Antwort. Schlussendlich hat mir das highlighting der Hyperlinks in diesem Kommentar die Augen geöffnet: Als vermeindlich kompletten Dateipfad habe ich “ubuntu_bionic_main” mit Unterstrichen statt Leerzeichen geschrieben. Mit Leerzeichen funktioniert es. Also doch soweit korrekt in der Anleitung geschrieben.

        Viele Grüße!

  9. Bene says:

    Thx for the great tutorial.
    I have some additional question.
    When I want to change the url address from my.domain.eu to my.domain.eu/nextcloud, what I need to change.

    I tried something like alias in the virtual host but with no success.

    • config.php:
      'overwrite.cli.url' => 'https://example.org/nextcloud',
      'htaccess.RewriteBase' => '/nextcloud',

      Find out more here:

      vhosts:
      vi /etc/apache2/sites-available/001-nextcloud.conf
      vi /etc/apache2/sites-available/001-nextcloud-le-ssl.conf

  10. Rodney says:

    Hi Carsten, excellent guide. I have followed it exactly as written on a clean installation of Ubuntu 18.04.1, but the only issue I am having is that in fail2ban, only my default gateway (192.168.1.1) is banned. The jail config was copied from this guide. A brute force attempt from any IP means I will then have to unban 192.168.1.1. It happens several times a day. Any ideas as to why this would be? Thanks!

  11. Robert says:

    Hi Carsten,

    thanks a lot for this guide. I had a running NC instance in Xenial and now updated to Bionic. Afterwards I have followed your guide in total to complete/repair the server configuration. Besides the Mail app which is not ready for PHP 7.3 everything seems to be fine on a first look. Also the internal check succeeds – no setup warnings. But unfortunately I’m experiencing some trouble with “bigger” files especially with videos: The video player app does start but its screen stays black. The server’s CPU and RAM load increase at the same time. First I thought the video player is broken, but then I have discovered that small videos (< 10MB) can be played. Furthermore I have the same issue when just initiating a download of a big file (high load and endless waiting for the browser dialog where to save the file).

    I checked the logs and did not find suspicous entries. Anyway I assume that some cache setting might be wrong. Do you have a hint what to check?

    Thanks a lot!
    Robert

  12. philippe says:

    Hi Carsten,
    An excellent jog ! Great …
    All was perfect till I continue the tuto /
    “After a few seconds Nexcloud will be installed and you will be redirected to Nextclouds file app. Please log out directly and make further ammendments.”

    I did all your request till the end and it’s strange now . I still have access to the nextcloud “login & Password” but before this line
    – After a few seconds Nexcloud will be installed and you will be redirected to Nextclouds file app. Please log out directly and make further ammendments.
    All was perfect and now I input the right login and password but nothing change , I still in the same page with no error but just the same , I cannot enter to nextcloud …
    Did you have a idea ??

    Thank in advance
    Philippe

  13. Mark says:

    Hi Carsten,

    Thanks a lot for your Guide. Helped me so much configurate my nextcloud server.
    I found one point, which is different in my Debian9 system:

    My Redis socket is running in the following path: /var/run/redis/redis.sock
    So I had to change the host in “/var/www/html/nextcloud/config/config.php” from “redis-server.sock” to “redis.sock”
    Otherwise I was not able to use the nextcloud “occ” commands

    Greetings and Thanks again
    Mark

  14. Joe says:

    I tried replying and it wasn’t showing up, so posting another top level comment.

    I gave your suggestion (sudo -u www-data php /var/www/html/nextcloud/occ add:user test) a go, and it had issues with the syntax, apparently it’s user:add instead of add:user.

    I took some screenshots of the issue incase it’s showing something I’m not describing correctly. The new user has incremented the user numbers in the left pane, but it still shows no users in the main pane.

    https://imgur.com/a/j8nUj2k

  15. Joe says:

    Hey mate, went through the guide, found a spelling mistake, just search for “diasbaling”

    Unfortunately I seem to be having a problem though, got all the way through, but now when I login with my admin user (the only user) and I go to the users section to add additional users it says “An error occured during the request. Unable to proceed.” in a bar at the top centre. It then shows no users below (even though I’ve logged in with a user).

    I know you have no obligation to help, but if you’ve any advice I would be very grateful. At the moment it’s either I can work this out, or I have to reinstall everything to start from scratch and hope it doesn’t happen again.

    • Thanks, i made the correction already. Please try to add a user using the Nextcloud cli: sudo -u www-data php /var/www/html/nextcloud/occ add:user test Does it work as expected?

      • Joe says:

        Unfortunately upon running that command I get “There are no commands defined in the “add” namespace.”

        Any other suggestions? More information I can provide you to help?

      • Joe says:

        So apparently that syntax was incorrect, it’s user:add instead of add:user. It did add a user, and when going to the user section in the nextcloud ui, it shows 2 in everyone & 1 in admin as it should (on the left sidebar). It still gives the error and doesn’t show the users in the main pane though. Is there a setting in the walkthrough that might’ve cause it to not allow the server to view that information?

  16. Oscar says:

    It seems that your modification in /var/www/html/nextcloud/.htaccess may cause part of the ui not loading.

  17. Axel says:

    Best nextcloud tuto ever from far !!!
    Many thanks !

  18. Micha says:

    Hallo Carsten

    ich nutze ubuntu 18.04.1 auf einem arm System (odroid c2)
    Es ist leider kein PHP7.3 zu finden. Bis zur Grundeinrichtung (anlegen NC Admin User) läuft die Installation. Nach den weiteren Anpassungen wird kein Inhalt mehr auf der Website angezeigt (File not found).
    Im Apache Logfile erscheint: “AH01071: Got error ‘Primary script unknownn” und” proxy_fcgi:error”.
    Kann das am fehlenden PHP7.3 liegen (wir haben anstelle dessen PHP7.2 installiert).

    Das Versionsproblem betrifft auch Maria-DB. Hier haben wir die Version mariadb-server-10.1 installiert, weil 10.3 ebenfalls nicht auffindbar ist.

    Danke und VG
    Micha

    • PHP:
      sudo apt install software-properties-common && sudo add-apt-repository ppa:ondrej/php
      sudo apt update

      Dann kann PHP 7.3 nachinstalliert werden.

      MariaDB:
      sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
      sudo add-apt-repository 'deb [arch=amd64,arm64] http://ftp.hosteurope.de/mirror/mariadb.org/repo/10.3/ubuntu bionic main'
      sudo apt update

      Dann kann MariaDB 10.3 installiert werden.

      Ggf. die vorherigen Installationsversuche entfernen und nach einer Bereinigung von vorne beginnen: apt purge apache2* mysql* php* redis* -y
      Ggf. vorab die Daten und die DB sichern: https://www.c-rieger.de/nextcloud-backup-and-restore/

  19. Siggi.d says:

    Thank you very much for this how-to, I followed it and I have a working nextcloud server! I did just copy and paste, but it would be nice to know what I did there¯_(ツ)_/¯ Happy New Year! Frohes neues!

  20. Whisht says:

    Hello there.
    I have cofig my sites according your 001-nextcloud.conf and 001-nextcloud-le-ssl.conf. And I have encountered this Problem “HTTP headers do not setting to “X-Frame-Options” 。 But in 001-nextcloud-le-ssl.conf, I have this config line:

    **Header always set X-Frame-Options “SAMEORIGIN”**

    Just same as you.
    It seems a little confused. Thanks for your help~

  21. Inside Void says:

    After a system restart… nothing is loading up…

    I have done a small mistake, instead of changing the database folder to /var/nc_data, i left it as it is(actually forgot to see that) but everything was working fine until i planned for a restart…

    Thank you in advance

  22. Mark Johnson says:

    Awesome tutorial! Just done NextCloud 15 on Ubuntu 18.04 LTS and all went reasonably well. But the admin UI does say:

    Some columns in the database are missing a conversion to big int. Due to the fact that changing column types on big tables could take some time they were not changed automatically. By running ‘occ db:convert-filecache-bigint’ those pending changes could be applied manually. This operation needs to be made while the instance is offline.

    Which is strange because the steps to fix this are in the tutorial under “Optimize your Nextcloud once (a) and regulary (b) using a script” and I did execute them. I manually ran

    sudo -u www-data php /var/www/html/nextcloud/occ db:add-missing-indices
    and
    sudo -u www-data php /var/www/html/nextcloud/occ db:add-missing-indices

    again and they executed without errors but then the warning is still showing in Nextcloud UI.

    The other warning is “The “Referrer-Policy” HTTP header is not set to “no-referrer”, “no-referrer-when-downgrade”, “strict-origin”, “strict-origin-when-cross-origin” or “same-origin”. This can leak referer information. ” but that, too was covered in the tutorial.

    I will spin up a sandbox VPS and start again from top to bottom to see if the sandbox would also keep throwing these warning messages.

    Other than that the tutorial saved a lot of time. It is very comprehensive and unlike others it pays a lot of attention to security. Much better than a sloppy docker or snap install 🙂

    • Please don’t hesitate to contact me (MAIL) directly if these messages will remain on your second server either. Cheers, Carsten

    • Please change /etc/apache2/sites-available/001-nextcloud-le-ssl.conf with regards to the current guide update from today.
      1. Solution for referrer: here.
      2. Solution for database: issue sudo -u www-data php /var/www/html/nextcloud/occ db:convert-filecache-bigint manually again.

  23. Matthias says:

    Hi Carsten, ich habe meine Nextcloud Installation nach deinem Beispiel durchgeführt. Respekt und vielen Dank für die tolle Anleitung. Heute habe ich das Update auf die Version 13.0.2 über die CLI eingespielt. Das einspielen hat ohne Probleme funktioniert. Auch kann ich über meinen Client der auf meinem Notebook läuft meine Daten wieder sauber synchronisieren. Allerdings kann ich die Weboberfläche nicht mehr erreichen. Als Fehlermeldung erschein
    “Forbidden You don’t have permission to access /index.php on this server.”

    Hattest du schon mal ein ähnliches Problem?
    VG

  24. dongha28 says:

    When trying to enable php7.2-fpm, a2enmod says it does not exist
    root@ubuntu01:~# a2enmod php7.2-fpm
    ERROR: Module php7.2-fpm does not exist!

    How do I enable php7.2-fpm?

    • First you have to install it as simple as i wrote in the guide:
      apt install libapache2-mod-php7.2 php7.2-cli php7.2-common php7.2-mbstring php7.2-gd php7.2-intl php7.2-xml php7.2-mysql php7.2-zip php7.2-dev php7.2-curl php7.2-fpm php7.2-json php7.2-bz2 php7.2-ldap php-dompdf php-apcu imagemagick php-imagick php-smbclient redis-server php-redis unzip -y
      Then you will be able to disable PHP 7.2 and mpm_prefork and enable php7.2-fpm with mpm_event by issuing
      a2dismod php7.2 && a2dismod mpm_prefork && a2enmod proxy_fcgi setenvif mpm_event && service apache2 restart
      a2enconf php7.2-fpm && service apache2 restart

      • dongha28 says:

        I already have php7.2-fpm installed
        php7.2-fpm is already the newest version (7.2.5-1+ubuntu16.04.1+deb.sury.org+1).

        But there is no conf OR load file in the /etc/apache2/mods-enabled directory.
        The funny thing is, php7.2-fpm has its own directory at /etc/php/7.2/fpm
        root@ubuntu01:/etc/php/7.2/fpm# ls
        conf.d php-fpm.conf php-fpm.conf.bak php.ini php.ini.bak pool.d

        Will I be ablate enable php7.2-fpm by copying over the php-fpm.conf file to the /mods-enabled/ directory?
        I already executed the previous step ‘a2dismod php7.2 && a2dismod mpm_prefork && a2enmod proxy_fcgi setenvif mpm_event && service apache2 restart’ and everything went ok, including apache2 restart. I keep getting stuck at the php7.2-fpm part.

  25. Michael says:

    Bravo!

  26. steffen says:

    Hallo,

    Ich habe alles soweit hinbekommen, nun habe ich meine PiDrive Platte von WD eingebunden und diese wird auch in nextcloud angezeigt.
    Das einzige Problem das ich hab ist, ich kann auf die Platte keine Datein hochladen? Was mach ich falsch.

  27. aytac says:

    hello again
    i am following your tutorial it is genius !
    my nextcloud instalation has problem when i try to send test mail it say A problem occurred while sending the email. Please revise your settings. (Error: Connection could not be established with host mail.xysysy.com [ #0])
    do you know how to resolve it ?
    my instalation is on the ubuntu 17.10 and pgsl with php7.2
    thank you for all !

  28. aytac says:

    hello many many thanks for your best tutorial
    i would like to ask you somethings about nextcloud installations
    1) nextcloud web server for the 100 users which is your prefer ? (apache or nginx )
    2) database postgres or Mariadb
    3) is it ok ubuntu 17.10 server ?
    many thanks for your answer

  29. stefano says:

    thank you, you are the best

  30. Claes says:

    Hi,
    I followed your guide and everything i setup and working, except for mounting shares using “SMB / CIFS” under “External storages” in Nextcloud from my file server running Windows…
    How do I configure it?

    • Hi Claes, do you have php-smbclient installed? Check: php -m
      If yes, you may choose it in Nextclouds external storage app as your preferred storage provider and configure the necessary credentials.
      If not please install php-smbclient by issuing
      sudo -s
      apt install php-smbclient -y

      Cheers, Carsten
      Cheers, Carsten

      • Michael Seyfert says:

        Hi Carsten,
        erst einmal ganz herzlichen Dank für diese großartige Anleitung. Nach meinem Update von Xenial auf Bionic kann NC die SMB/CIFS-Freigaben nicht mehr einbinden. Ich habe dann nach deiner Anleitung auf NC15 aktualisiert (mit Ausnahme von MySQL -> Oracle), das Problem bleibt bestehen. php-smbclient ist nach wie vor installiert, die App ‘External Storage’ auch, Benutzer dürfen externen Speicher einbinden und an der config im Benutzer-Backend habe ich nichts geändert, bzw. ich habe einmal die credentials neu eingegeben, um Fehler hierbei auszuschließen.
        Im Protokoll von NC bekomme ich folgende Fehlermeldungen:

        [webdav] Fatal: SabreDAVExceptionServiceUnavailable: Storage with mount id 1 is not available at <>
        0. /var/www/nextcloud_15.0.0/3rdparty/sabre/dav/lib/DAV/Tree.php line 76
        getChild(“BSB”)
        1. /var/www/nextcloud_15.0.0/3rdparty/sabre/dav/lib/DAV/Server.php line 967
        getNodeForPath(“files/michael/BSB”)
        2. /var/www/nextcloud_15.0.0/3rdparty/sabre/dav/lib/DAV/Server.php line 1666
        getPropertiesIteratorForPath(“files/michael/BSB”, [“{DAV:}resource … “], 1)
        3. /var/www/nextcloud_15.0.0/3rdparty/sabre/dav/lib/DAV/CorePlugin.php line 355
        generateMultiStatus(Generator {}, false)
        4. <>
        httpPropFind(SabreHTTPReque … “}, SabreHTTPResponse {})
        5. /var/www/nextcloud_15.0.0/3rdparty/sabre/event/lib/EventEmitterTrait.php line 105
        call_user_func_array([SabreDAVCorePlugin {},”httpPropFind”], [SabreHTTPRequ … }])
        6. /var/www/nextcloud_15.0.0/3rdparty/sabre/dav/lib/DAV/Server.php line 479
        emit(“method:PROPFIND”, [SabreHTTPRequ … }])
        7. /var/www/nextcloud_15.0.0/3rdparty/sabre/dav/lib/DAV/Server.php line 254
        invokeMethod(SabreHTTPReque … “}, SabreHTTPResponse {})
        8. /var/www/nextcloud_15.0.0/apps/dav/lib/Server.php line 298
        exec()
        9. /var/www/nextcloud_15.0.0/apps/dav/appinfo/v2/remote.php line 35
        exec()
        10. /var/www/nextcloud_15.0.0/remote.php line 163
        require_once(“/var/www/nextcl … p”)

        UND

        [no app in context] Error: OCPFilesStorageNotAvailableException: at <>
        0. /var/www/nextcloud_15.0.0/lib/private/Files/Storage/Wrapper/Availability.php line 461
        checkAvailability()
        1. /var/www/nextcloud_15.0.0/lib/private/Files/Storage/Wrapper/Wrapper.php line 582
        getMetaData(“”)
        2. /var/www/nextcloud_15.0.0/lib/private/Files/Cache/Scanner.php line 112
        getMetaData(“”)
        3. /var/www/nextcloud_15.0.0/lib/private/Files/Cache/Scanner.php line 150
        getData(“”)
        4. /var/www/nextcloud_15.0.0/lib/private/Files/Cache/Scanner.php line 336
        scanFile(“”, 3, -1, null, true)
        5. /var/www/nextcloud_15.0.0/lib/private/Files/Utils/Scanner.php line 245
        scan(“”, true, 3)
        6. /var/www/nextcloud_15.0.0/apps/files/lib/Command/Scan.php line 145
        scan(“/michael”, true, null)
        7. /var/www/nextcloud_15.0.0/apps/files/lib/Command/Scan.php line 201
        scanFiles(“michael”, “/michael”, SymfonyComponen … {}, false, true, false)
        8. /var/www/nextcloud_15.0.0/3rdparty/symfony/console/Command/Command.php line 255
        execute(SymfonyComponen … {}, SymfonyComponen … {})
        9. /var/www/nextcloud_15.0.0/core/Command/Base.php line 166
        run(SymfonyComponen … {}, SymfonyComponen … {})
        10. /var/www/nextcloud_15.0.0/3rdparty/symfony/console/Application.php line 946
        run(SymfonyComponen … {}, SymfonyComponen … {})
        11. /var/www/nextcloud_15.0.0/3rdparty/symfony/console/Application.php line 248
        doRunCommand(OCAFilesCommandScan {}, SymfonyComponen … {}, SymfonyComponen … {})
        12. /var/www/nextcloud_15.0.0/3rdparty/symfony/console/Application.php line 148
        doRun(SymfonyComponen … {}, SymfonyComponen … {})
        13. /var/www/nextcloud_15.0.0/lib/private/Console/Application.php line 213
        run(SymfonyComponen … {}, SymfonyComponen … {})
        14. /var/www/nextcloud_15.0.0/console.php line 96
        run()
        15. /var/www/nextcloud_15.0.0/occ line 11
        require_once(“/var/www/nextcloud_15.0.0/console.php”)

        Ich habe im web keine weitere Lösung dazu finden können. Hast du noch eine Idee?

        • blockiert hier ufw oder eine andere firewall an der destination? Einfach mal lokal
          ufw status verbose und auch mal php - m
          aufrufen um die Module zu überprüfen.

          Ansonsten bitte auch die nginx logs
          /var/logs/nginx überprüfen.

          Ggf. bitte bei Nextcloud ein Ticket öffnen. Danke.

          • Michael Seyfert says:

            Ach, ufw hatte ich noch gar nicht aktiviert. php -m zeigt mir libsmbclient an.
            Ich habe apache installiert, aus den Fehlermeldungen werde ich auch nicht schlau.
            Dann mache ich mal ein Ticket auf. Trotzdem nochmal vielen Dank!

          • Michael Seyfert says:

            Hallo Carsten, ich habe das Problem wohl eingegrenzt. Wenn ich in der sshd_config PasswordAuthentication auf yes setze, funktioniert zumindest das Einbinden per SFTP (nicht aber SMB/CIFS). Aber das ist ja eine große Sicherheitseinbuße. Mit public oder private key (RSA) habe ich es nicht hinbekommen. Ein Ticket bei Github hatte ich bisher nicht geöffnet. Ich werde mich wieder melden, wenn das Problem gelöst ist.

          • Michael Seyfert says:

            Moin Carsten,
            ich hab’s hinbekommen 🙂 Beim Einbinden des externen Speichers (SMB/CIFS) hatte ich bisher keine Domain eingetragen (nur ‘Host’, ‘Share’, ‘Benutzer’ und ‘Passwort’ sind obligatorisch). Dies ist aber offenkundig nach dem Update auf Ubuntu Bionic notwendig geworden.
            Danke, danke noch einmal!!

  31. ErAzOr says:

    @Carsten
    Hi Carsten. Vielen Dank für die Anleitung.

    Haben mal ne generelle Frage zu Apache:
    Nginx bietet ja das Modul ngx_cache_purge, welches die Generierung von Thumbnails beschleunigen soll.
    Gibt es analog dazu auch ein entsprechendes Modul für Apache? Oder ist es mit Apache nicht erforderlich, da entsprechende Funktion bereits Bestandteil ist?.
    Grüße ErAzOr

    • Vielen Dank! Ein explizites Modul ist mir nicht bekannt – ich bin auf diesem Gebiet leider noch “blank”. Über Informationen dazu wäre ich dankbar 😉 Viele Grüße, Casten

  32. Nextclouder says:

    Thanks for the fast response and update, I delete 000-default in sites-enabled and default-ssl in sites-available, the only file left is /etc/apache2/sites-available/001-nextcloud.conf which has my name.dedyn.io, the domain is working, I get the Apache2 welcome page on port 80.

    Certbot is unhappy and doesn’t pick up the vhost in /etc/apache2/sites-available/001-nextcloud.conf:

    # certbot –apache
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Plugins selected: Authenticator apache, Installer apache
    No names were found in your configuration files. Please enter in your domain
    name(s) (comma and/or space separated) (Enter ‘c’ to cancel):

    This is my 001-nextcloud.conf:

    ServerName .dedyn.io

    ServerAdmin webmaster@dedyn.io
    DocumentRoot /var/www/html/nextcloud

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    Thanks again for your fantastic blog, just trying to follow along and running in little hiccups ..

    • Hi, did you change the vhost (001-nextcloud.conf) properly? LE would pick up the ServerName from the vhost – this is definitivley wrong: ServerName .dedyn.io
      You have to substitute the hostname and mail:
      your.dedyn.io to e.g. nextcloud.yourdomain.com
      webmaster@dedyn.io to e.g. webmaster@yourdomain.com

      assuming your dyndns would be “yourdomain.com”.

      Certbot is unhappy and doesn’t pick up the vhost in /etc/apache2/sites-available/001-nextcloud.conf:
      You have to create a link (e.g. ln -s) or a2ensite 001-nextcloud.conf first. Apache2 won’t use vhosts in sites-available.
      Cheers, Carsten

  33. Nextclouder says:

    I made it to “certbot –apache” then I get the error apache2: Syntax error on line 225 of /etc/apache2/apache2.conf: Could not open configuration file /etc/apache2/sites-enabled/000-default.conf: No such file or directory

    Do we first need to enabled the 001-nextcloud.conf from sites-available to the sites-enabled folder? Also is it possible that the apache2 package is missing in the apt install commands above? I had to manually install it in addition to copy & pasting ..

    • Hi.
      No, it isn’t missised, it will be installed by issuing “libapache2-mod-php7.2” …
      Please remove the defaults vhosts:
      rm /etc/apache2/sites-available/000-default.conf
      rm /etc/apache2/sites-enabled/000-default.conf
      service apache2 restart

      and before issuing certbot aou have to a2ensite 000-nextcloud.conf.
      Thank you very much for your feedback and your hint! I already updated the guide Cheers, Carsten

Leave a Reply

Your email address will not be published. Required fields are marked *