Nextcloud

Installing your own Nextcloud instance in 2024

published on

Note: This post is an updated version of Create your own Nextcloud instance with Apache.

We will be installing Nextcloud using Apache again but this post contains new information and includes extra configuration in places.

Install and setup needed packages

The first thing we need to do is to install some packages which will be needed by software we install later. We can do this by running the following commands:

sudo apt install lsb-release ca-certificates apt-transport-https software-properties-common language-pack-en-base unzip zip curl
sudo add-apt-repository ppa:ondrej/php
sudo add-apt-repository ppa:ondrej/apache2
sudo apt update

Let's install PHP 8.2

PHP 8.2 is recommended by Nextcloud and so this is the version that we will install. Enter the following commands to install PHP and a few useful tools:

sudo apt install php8.2-{common,cli,bz2,zip,curl,intl,mysql,snmp,memcached,imagick,gd,imap}
sudo apt install php8.2-{ldap,soap,tidy,xml,gmp,pspell,mbstring,opcache,fpm,ssh2,imap}
sudo apt install php8.2-{redis,apcu,mcrypt,smbclient,bcmath}
sudo apt install ghostscript imagemagick ffmpeg
sudo systemctl enable php8.2-fpm

Configure PHP for use with Nextcloud

We now need to configure PHP with appropriate settings for a Nextcloud installation.

Edit /etc/php/8.2/fpm/pool.d/www.conf and add or update the following lines:

listen = /run/php/php8.2-fpm.sock
listen.owner = www-data
listen.mode = 0660
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

Now edit /etc/php/8.2/fpm/php.ini and /etc/php/8.2/cli/php.ini with the below settings. Where these don't already exist you will need to add them. Also make sure to change the time zone to the one that you live in.

output_buffering = 0
expose_php = off
max_execution_time = 3600
max_input_time = 3600
max_input_vars = 1000
memory_limit = 512M
post_max_size = 16G
upload_tmp_dir = /var/tempfiles/
upload_max_filesize = 16G
allow_url_fopen = Off
apc.enable_cli=1
date.timezone = Europe/London
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=10000
opcache.validate_timestamps = 0
opcache.revalidate_freq=60
opcache.save_comments=1

Now run the following three commands to create the temporary upload directory and make your changes active:

sudo mkdir /var/tempfiles
sudo chown www-data:www-data /var/tempfiles
sudo systemctl restart php8.2-fpm

Now install Redis

We will use Redis as a cache to help speed up some parts of Nextcloud. Run sudo apt install redis-server to install it.

Now we need to configure it. We do this by editing /etc/redis/redis.conf and modifying the following lines:

bind 127.0.0.1 ::1
supervised systemd
maxmemory 256mb'
maxmemory-policy allkeys-lru

Now run the following commands to finish setting up Redis and activating your changes:

sudo usermod -a -G redis www-data
sudo mkdir -p /var/log/redis
sudo chown redis:redis /var/log/redis
sudo systemctl enable redis-server
sudo systemctl restart redis.service

Install MariaDB

We now move on to installing and setting up a database for Nextcloud to use. Do so by running sudo apt install mariadb-server.

Next, secure your MariaDB installation by running sudo mysql_secure_installation. At this first run the root password won't already be set.

Edit /etc/mysql/mariadb.conf.d/50-server.cnf and edit or update the following two lines:

bind-address 127.0.0.1
local-infile=0

Next create the database that Nextcloud will use by running sudo mysql -u [root user] -p and entering the following commands at the MySQL prompt:

CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'nc'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nc'@'localhost';
FLUSH PRIVILEGES;
exit

Also make sure to replace the password above with something secure and hard to guess.

Installing the Apache web server

It is now time to install Apache. Run the following two commands:

sudo apt-get install apache2 apache2-utils libapache2-mod-fcgid
sudo a2enmod mime http2 rewrite deflate expires headers ssl setenvif dir env proxy_fcgi

Edit /etc/apache2/conf-enabled/security.conf and add or modify the following lines:

ServerTokens Prod
ServerSignature Off
TraceEnable Off
Header unset ETag
FileETag None
Header unset Server
Header always unset X-Powered-By
Header unset X-CF-Powered-By
Header unset X-Pingback

Now edit /etc/apache2/apache2.conf and add or modify the following lines:

Timeout 120
KeepAlive On
KeepAliveTimeout 5
HostnameLookups off
ProxyRequests Off
ProxyVia Off
#Only allow proxies from local network
<Proxy "*">
  Order Deny,Allow
  Deny from all
  Allow from 192.168.0
</Proxy>

Finally, run the following commands to activate your new configuration:

sudo a2enconf php8.2-fpm
sudo systemctl restart php8.2-fpm
sudo a2dissite 000-default.conf
sudo systemctl restart apache2
sudo systemctl enable apache2

Installing Nextcloud

It is now time to install the files that make up Nextcloud. This is as simple as running the following commands which will download files, move them to the place we want them and then delete copies we don't need any more.

cd ~
wget https://download.nextcloud.com/server/releases/latest.zip
unzip latest.zip
sudo mkdir /var/www/nextcloud
sudo cp -r nextcloud /var/www
sudo chown -R www-data:www-data /var/www/nextcloud
sudo chmod -R 755 /var/www/nextcloud
sudo rm -r nextcloud
sudo rm latest.zip

Create the Apache virtual host file

This will provide the configuration Apache needs to serve your site to visitors.

Edit /etc/apache2/sites-available/nextcloud.conf and add the following lines:

 

<VirtualHost *:80>
        ServerAdmin email_address
ServerName [domain] (make sure to set up a subdomain called cloud in your DNS settings)
DocumentRoot /var/www/nextcloud
        Protocols h2 http/1.1
 
        DirectoryIndex index.php
 
        SetEnv TZ Europe/London
        AddDefaultCharset UTF-8
        DefaultLanguage en
        FileETag none
 
        #if using Cloudflare or other proxy then uncomment the following line
        #RemoteIPHeader CF-Connecting-IP
 
        ProxyRequests Off
        ProxyVia Off
 
        <Proxy "*">
          Require ip 192.168.0
        </Proxy>
 
<Directory /var/www/nextcloud>
                Require all granted
AllowOverride All
Options -Indexes +FollowSymLinks +MultiViews
</Directory>
 
        <FilesMatch "\.php$">
          SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
        </FilesMatch>
 
ErrorLog /var/log/apache2/nextcloud-error.log
CustomLog /var/log/apache2/nextcloud-access.log combined
    </VirtualHost>
# intermediate configuration
SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite          ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
SSLHonorCipherOrder     off
SSLSessionTickets       off
SSLUseStapling On
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
 
Make sure to add your own email address, domain and time zone.
 
Finally, activate your new configuration by running the following two commands:
 
sudo a2ensite nextcloud.conf
sudo systemctl restart apache2
 

Secure your site with an SSL certificate

 
Running the following set of commands will create an SSL certificate to secure your site. Make sure to replace the domain below with your actual domain name.
 
sudo apt install snapd
sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot -d [domain] --apache
 

Update your Apache virtual host

 
Add the following lines to your existing Apache virtual host configuration files:
 
Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains"
Header set X-Content-Type-Options nosniff
Header set X-Frame-Options SAMEORIGIN
Header set Referrer-Policy: no-referrer
Header set X-XSS-Protection "1; mode=block"
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure
Header set X-Permitted-Cross-Domain-Policies "none"

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://[domain]%{REQUEST_URI}
 
Activate these changes by running sudo systemctl restart apache2.
 

Initial Nextcloud setup

Run the following three commands to create the directory where we are going to store the Nextcloud data then visit your domain in a browser to setup Nextcloud. When it comes to stating where your data should be stored enter /var/www/ncdata.

sudo mkdir /var/www/ncdata
sudo chown -R www-data:www-data /var/www/ncdata
sudo chmod -R 755 /var/www/ncdata

When you have finished with the online installer run sudo chown www-data:www-data /var/www/nextcloud/.htaccess.

Next edit /var/www/nextcloud/config/config.php and add or edit the following lines (usually in the $CONFIG array):

     'overwrite.cli.url' => 'https://[domain]/',
      'htaccess.RewriteBase' => '/',
      'trusted_domains' =>
        array (
         0 => 'localhost',
         1 => '[domain name]',
         2 => '[IPv4 address]',
         3 => '[IPv6 address including brackets]',
       ),
    Add the following lines
      'memcache.local' => '\OC\Memcache\APCu',
      'memcache.distributed' => '\OC\Memcache\Redis',
      'memcache.locking' => '\OC\Memcache\Redis',
      'redis' => [
         'host'     => 'localhost',
         'port'     => 6379,
       ],
    'default_phone_region' => 'GB',
    'filelocking.enabled' => true,
      );

Change the default_phone_region to point to the one in which you reside.

Now run the following commands:

cd /var/www/nextcloud
sudo -u www-data php occ maintenance:update:htaccess
sudo systemctl restart redis.service

Run crontab -u www-data -e to create a cron job and add the following at the end of the file:

*/5  *  *  *  * php -f /var/www/nextcloud/cron.php

Finally, run sudo -u www-data php occ config:system:set maintenance_window_start --type=integer --value=1 to setup a maintenance window.

Setup a firewall

If you haven't already got a firewall setup then use the following commands to do so. If you have simply choose the commands that will get you the same result.

sudo apt install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw logging low
sudo ufw allow [ssh port]
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable

Make sure to use your own SSH port.

Secure your installation with fail2ban

Whilst this step is optional it is recommended to help secure your Nextcloud installation.

With fail2ban already installed edit /etc/fail2ban/filter.d/nextcloud.conf and add the following lines:

[Definition]
_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)?"

Now edit /etc/fail2ban/jail.d/nextcloud.local and add the following lines:

[nextcloud]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = nextcloud
maxretry = 3
bantime = 86400
findtime = 43200
logpath = /var/log/apache2/nextcloud-access.log

Finally, run sudo systemctl restart fail2ban to activate your changes.

Final steps

By this point you should have Nextcloud installed and in a useable state.

Before using Nextcloud to store your files, contacts and calendars it is a good idea to work through the user and email settings.

Once you have done this your installation is ready for you to use.