How to Install Nextcloud 19 on Debian 10

This article describes how to manually install Nextcloud on a Debian server.

It is based on the general Nextcloud documentation:

Descriptions below are altered to work on the following OS and servers:

  • Debian 10.x (Buster)
  • MariaDB 10.3
  • Apache 2.4
  • PHP 7.3
  • Nextcloud 19.x

You can find general instructions for installing a Linux Apache MySQL PHP-Webserver here → Installationsanleitung (german only)

The installed server will work on a virtual host which will respond to a subdomain of your domain, e.g. There is also the alternative conf to install nextcloud in a subfolder of an existing server, but this is not the prime target of this how to (and therefore not

For some statements you need root permissions. Either use SUDO or login as root.

Operating System

Install Debian


Default install from USB stick.

Suifficient: Auto partitioning. Better: create small partitions for system and swap and a big one for /var

Disable Power Saving and Hibernation

If the operation system should not attempt any type of suspend or hybernation, the appropriate targets need to be disabled at the systemd level:

systemctl mask

Reboot or restart service:

systemctl restart systemd-logind.service

For more information see Energiespareinstellungen_(Debian)#Disable_Suspend_and_Hibernation



Install and Configure MariaDB

apt-get install mariadb-client mariadb-server

In order to prevent data loss using multiple user access the transaction_isolation needs to be READ-COMMITTED.

In order to enable Emoji support (UTF8 4-byte) the innodb_file_format needs to be barracuda and innodb_file_per_table needs to be active.

Create a new file named /etc/mysql/conf.d/nextcloud.cnf with following content:


Restart MariaDB Server:

systemctl restart mariadb

How to check variables: MariaDB_(Debian)#Transaction_Isolation_Level_und_Binary_Logging_konfigurieren

Install and Configure Apache Webserver

apt-get install apache2

Install and Configure PHP

PHP will be utilized from apache via FPM (FastCGI Process Manager) for performance reasons:

apt-get install php 
apt-get install php-fpm libapache2-mod-fcgid
apt-get install php-apcu php-bcmath php-bz2 php-curl php-gd php-gmp php-json php-mbstring php-mysql php-imagick php-intl php-xml php-zip ffmpeg

The following modules are part of libapache2-mod-php7.3 which will be automatically installed with php:

bcmath bz2 calendar Core ctype date dba dom ereg exif fileinfo filter ftp gettext hash iconv libxml mhash openssl pcre Phar posix Reflection session shmop SimpleXML soap sockets SPL standard sysvmsg sysvsem sysvshm tokenizer wddx xmlreader xmlwriter zlib

Activate additional Apache Modules:

a2enmod rewrite headers env dir mime setenvif

Modules env, dir, mime and setenvif are probably active by default.

Install and Configure PHP-FPM

PHP will be utilized from apache via FPM (FastCGI Process Manager) for performance reasons:

apt-get install php-fpm libapache2-mod-fcgid

Disable Apache PHP Module and enable proxy modules and php7.3-fpm configuration:

a2dismod php7.3
a2enmod proxy proxy_fcgi
a2enconf php7.3-fpm

PHP-FPM resets by default system environment variables (See default value of clear_env parameter in www.conf). Therefore environment variables need to be set according to system variables.

First, check current content of PATH variable:

printenv PATH

All paths have to be added to /etc/php/7.3/fpm/pool.d/www.conf. Uncomment existing lines like this and add contents of PATH variable from above to env[PATH]:

env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

Uncomment the following line in for security reasons in order to allow local access only to PHP-FPM:

listen.allowed_clients =

Create file /etc/php/7.3/fpm/conf.d/99-nextcloud.ini with following content:

memory_limit = 512M


As memory_limit is 512M at least needed as this is the minimum for installing Colabora Online Developer Edition (CODE).

opcache.enable_cli is needed for cronjobs (see below).


systemctl restart php7.3-fpm
systemctl restart apache2

Check PHP Configuration

Create new file phpinfo.php with following content:


Open the file using http://localhost/phpinfo.php

Check contents of the following variables:

Variable Expected Value
Server API FPM/FastCGI
memory_limit 512M
APCu Support Enabled
Opcode Caching Up and Running
opcache.enable On
opcache.enable_cli On

Create Virtual Host for Subdomain

This how to is based on avirtual host for running nextcloud on a subdomain. Create a new subdirectory for Nextcloud:

mkdir /var/www/nextcloud

Create a new apache config file: /etc/apache2/sites-available/nextcloud.conf

<VirtualHost *:80>
  DocumentRoot /var/www/nextcloud

  <Directory /var/www/nextcloud/>
    Require all granted
    AllowOverride All
    Options FollowSymLinks MultiViews

    <IfModule mod_dav.c>
      Dav off

Replace DocumentRoot and ServerName with your actual path and servername.

If you want to run Nextcloud from a subdirectory you will need a different nextcloud.conf:

Alias /nextcloud "/var/www/nextcloud/"

<Directory /var/www/nextcloud/>
  Require all granted
  AllowOverride All
  Options FollowSymLinks MultiViews

  <IfModule mod_dav.c>
    Dav off

See this documentation for further instructions:

Activate site and reload configuration:

a2ensite nextcloud
systemctl reload apache2

Install and Configure Let's Encrypt

apt-get install certbot python-certbot-apache

Activate certbot and alter config files for Apache:

certbot --apache

For higher security allow certbot to add redirection of unencrypted traffic to HTTPS to your configuration.

Certbot creates a config file similar to that at /etc/apache2/sites-available/nextcloud-le-ssl.conf:

<IfModule mod_ssl.c>
  <VirtualHost *:443>
    DocumentRoot /var/www/nextcloud
    <Directory /var/www/nextcloud/>
      Options +FollowSymlinks
      AllowOverride All

      <IfModule mod_dav.c>
        Dav off

      SetEnv HOME /var/www/nextcloud
      SetEnv HTTP_HOME /var/www/nextcloud

    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/
    SSLCertificateKeyFile /etc/letsencrypt/live/


Download and Uncompress Nextcloud

Download archive from to /var/www (use current version):



tar -xjf nextcloud-19.0.2.tar.bz2

Set directory ownership to www-data:

chown -R www-data:www-data /var/www/nextcloud/

Create Data Directory

A good practice is to configure the data directory outside of the webroot. It must be owned by the HTTP user, i.e.:

mkdir /var/opt/nextcloud
chown www-data:www-data /var/opt/nextcloud

Create Database

Create database user and database with UTF8MB4 character set and according collation in order to enable Emojis. Also grant permissions to the database user:

CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY 'password';
CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
GRANT ALL PRIVILEGES on nextcloud.* to 'nextcloud'@'localhost';
FLUSH privileges; 

The step kann be omitted as the installation wizard automatically create a database and a database user. In that case the user will be named the same as the given admin user but it will get a prefix "oc_".

Run Installation Wizard

Open in your browser and go to the following URL:

Enter credentials for new admin account.

Open Storage & Database Tab and specify data folder, database user, password and database name you created above.

You can deactivate the checkbox "Install recommended apps" for performance reasons of if you don't want to install Talk, Mail or OnlyOffice. All apps can also be installed or uninstalled by the administrator from the web administration backend.

Configure Trusted Domains

Parameter 'trusted_domains' should contain actual server name. Check /var/www/nextcloud/config/config.php:

'trusted_domains' => 
array (
  0 => '',


While at it also check parameter 'overwrite.cli.url':

'overwrite.cli.url' => '',

Administrative or User Settings

Set name, email address, language and locale, SMTP server credentials:

  • Login with user
  • Click on user name and go to settings
  • On tab "Personal info" enter name, email address, language and locale
  • On tab "Basic settings" enter email server settings and sent test email

Security Hardening

Enable HTTP Strict Transport Security

In order to instruct browsers to not allow any connection to the Nextcloud instance using HTTP the HTTP Strict Transport Security header should be set.

This can be done by adding the following bold printed lines between to /etc/apache2/sites-available/nextcloud-le-ssl.conf:

<IfModule mod_ssl.c>
  <VirtualHost *:443>
    DocumentRoot /var/www/nextcloud
    <Directory /var/www/nextcloud/>
      Options +FollowSymlinks
      AllowOverride All
      <IfModule mod_dav.c>
        Dav off
      SetEnv HOME /var/www/nextcloud
      SetEnv HTTP_HOME /var/www/nextcloud
    <IfModule mod_headers.c>
      Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/
    SSLCertificateKeyFile /etc/letsencrypt/live/



See Iptables (Debian)



apt-get install fail2ban

Create filter file /etc/fail2ban/filter.d/nextcloud.conf with following content:

_groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
failregex = ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
            ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error.
datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"

Create jail file /etc/fail2ban/jail.d/nextcloud.conf in order to define how to handle failed authentication attempts:

backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = nextcloud
maxretry = 3
bantime = 86400
findtime = 43200
logpath = /path/to/data/directory/nextcloud.log

Restart fail2ban service and check status:

systemctl restart fail2ban
fail2ban-client status nextcloud


More details: Fail2Ban_(Debian)

Performance Tuning


From admin web access:

  • Deactivate unneeded apps like
    • User Account Migration
    • First Run Wizard
  • Deactivate Share API

Background Jobs with Cron

Nextcloud requires some tasks to be done on a regular basis. By default this will be done on every action a user does when logged in the web frontend. A better solution for that is to use cron in order to execute a script periodically, i.e. every five minutes.

Create file /etc/cron.d/nextcloud with following content:

# /etc/cron.d/nextcloud: Housekeeping cronjobs for Nextcloud
# m h dom mon dow user     command
*/5 * *   *   *   www-data php -f /var/www/nextcloud/cron.php


  • Filename mustn't contain the word "cron"
  • File mustn't contain empty lines

After creating cron job:

  • Login to web access with admin account
  • Click on user name
  • Click on settings
  • Open tab basic settings
  • Change radio button in section background jobs to Cron

Memory Caching

Activate APCu by adding the following line to /var/www/nextcloud/config/config.php:

 'memcache.local' => '\OC\Memcache\APCu',

Enable HTTP2

HTTP/2 provides major speed improvements when multiple request and most clients already provice HTTP/2 support. Sources:

Disable prefork MPM (Multi-Processing Module) and enable event MPM. Also enable SSL and HTTP2 modules:

sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo a2enmod ssl
sudo a2enmod http2

Add protocols to either global configuration or in the Nextcloud virtual host configuration file /etc/apache2/sites-available/nextcloud-le-ssl.conf (created in previous step by Let's encrypt):

<IfModule mod_ssl.c>
  <VirtualHost *:443>
    DocumentRoot /var/www/nextcloud
    <Directory /var/www/nextcloud/>
      Options +FollowSymlinks
      AllowOverride All

      <IfModule mod_dav.c>
        Dav off

      SetEnv HOME /var/www/nextcloud
      SetEnv HTTP_HOME /var/www/nextcloud

    <IfModule mod_headers.c>
      Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"

    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/
    SSLCertificateKeyFile /etc/letsencrypt/live/

    Protocols h2 http/1.1

Restart Apache Webserver:

systemctl restart apache2

Check in Firefox and Chrome:

  • Open Developer Tools with F12
  • Go to Network Pane
  • Show Column Protocol.
  • Reload page
  • Check value in Protocol column. Expected Value: HTTP/2.0 (in Firefox) or h2 (in Chrome)


The default configuration may lead to excessive load times in the web interface. The following configuration is based on a machine with 4 GB RAM and 1 GB MySQL cache.

Alter following lines in /etc/php/7.3/fpm/pool.d/www.conf:

pm = dynamic
pm.max_children = 120
pm.start_servers = 12
pm.min_spare_servers = 6
pm.max_spare_servers = 18


Pre-Generating Gallery Previews

Normally gallery previews will be generated at the moment of browsing through a directory containing pictures. By default in Nextcloud 19 a max preview (Filename "*-max.jpg") as well as a crop preview (Filename 256-256-crop.jpg") will be generated at browsing time. This takes some time.

The previews can be pre-generated as follows:

Install and activate the app Preview Generator:

Set sizes and quality for the preview generator in order to prevent it from creating a lot more different sizes which would not be created by Nextcloud by default:

sudo -u www-data php /var/www/nextcloud/occ config:app:set previewgenerator squareSizes --value="256"
sudo -u www-data php /var/www/nextcloud/occ config:app:set previewgenerator widthSizes  --value="256"
sudo -u www-data php /var/www/nextcloud/occ config:app:set previewgenerator heightSizes --value="256"
sudo -u www-data php /var/www/nextcloud/occ config:app:set preview jpeg_quality --value="60"

Default values for max size doesn't need to be specified as it has a default value of 4096 (see config.sample.php). It can be defined otherwhise in config.php.

Now create initial previews (this can take some time):

sudo -u www-data php /var/www/nextcloud/occ preview:generate-all -vvv

Update of previews takes place via a cron job. The following definition creates it once a night but you could also repeat it every couple of minutes. This could lead to problems when adding a large amount of new files as they would also need some time to be generated.

Add following line to /etc/cron.d/nextcloud from above:

# /etc/cron.d/nextcloud: Housekeeping cronjobs for Nextcloud
# m h dom mon dow user     command
*/5 * *   *   *   www-data php -f /var/www/nextcloud/cron.php
21  2 *   *   *   www-data php /var/www/nextcloud/occ preview:pre-generate


Uploading of Big Files

If uploads of big files fail check this:

Previews Not Generated

If created preview files seem not to be used perhaps it helps to update the file database:

sudo -u www-data php /var/www/nextcloud/occ files:scan-app-data

Or delete preview folder and generate previews from scratch.