Table of contents

A walktrough of the steps I executed to set up my server. More data and resources can be found in this Jar item.

A huge shoutout to my friend Claudio, who helped me a lot to understand and perform the most tricky parts.

General knowledge

Resources, apps, tutorials and several knowledge sources are mentioned here.

System configuration and environment setup

update Ubuntu (-y parameter is used to accept by default any question)

sudo apt update -y && sudo apt upgrade -y

remove debris

sudo apt autoremove -y && sudo apt autoclean -y

Add a limited user

It’s always better not to work and setup stuff straight from root user, it’s easy to mess everything up and very risky if you’re not 100% sure of what you’re doing (for me, most of the time).

add user

adduser tommi # “tommi”, in this case, is the username

grant that user sudo permissions

adduser -aG tommi sudo

Firewall configuration

Enable default configuration

ufw allow OpenSSH

enable firewall

ufw enable

check if everything is working

ufw status

first things firts:

sudo ufw allow 'Apache'

configure SSH Authentication Key-pair

create ssh folder to store allowed keys

mkdir -p ~/.ssh && sudo chmod -R 700 ~/.ssh/

on local device:

scp ~/.ssh/ xplosionmind@

NOTE: substitute with the server’s IP address and xplosionmind with both root user and limited user

Change default SSH port

Changing the default SSH port is useful to prevent randomized attacks which attempt to get access to the server from port 22, the default one.

Enable the new SSH port from the firewall. In this case, the process I’ll be following configures port 5522

sudo ufw allow 5522/tcp

Open the SSH configuration file /etc/ssh/sshd_config

sudo vim /etc/ssh/sshd_config

In this file, replace #Port 22 with Port 5522

after this, disable connections from port 22

sudo ufw deny 22

restart ssh

sudo systemctl restart ssh

Install git

install git

apt install git

Install zsh

install zsh

apt install zsh

set zsh as default shell

chsh -s /usr/bin/zsh root

install zsh syntax highlighting

apt install zsh-syntax-highlighting

install oh-my-zsh

sh -c "$(curl -fsSL"

enable zsh syntax highlighting

echo "source /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" >> ~/.zshrc

Nextcloud configuration



Firstly, it’s necessary to create the folder where Nextcloud interface, thus public application files, will be stored.

In this case, I configured a directory which is named exactly as the domain where the content it’s hosting will be found, for simplicity.

sudo mkdir /var/www/

then, permissions can be changed, such that Nextcloud itself can handle this data, once installed. As you can see, these permissions must be set -R recursively.

sudo chown -R $USER:$USER /var/www/
sudo chmod -R 755 /var/www/

make the (private) directory where all of nextcloud data will be stored, and change its permissions, too

mkdir /home/xplosionmind/nextcloud-data
sudo chown -R www-data:www-data /home/xplosionmind/nextcloud-data/

Apache configuration file

This is the essential content of an Apache configuration fil for nextcloud. It should be placed in /etc/apache2/sites-available/

create the configuration file by running

sudo vim /etc/apache2/sites-available/

then, add this content

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

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

Install MariaDB

sudo apt install mariadb-server

Basic database configuration

sudo mysql_secure_installation

log in MariaDB

sudo mariadb

Create a new database for Nextcloud (in MariaDB):

mysql> CREATE DATABASE nextcloud;

Create a new Nextcloud user

mysql> GRANT ALL ON nextcloud.* TO 'user_name'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;

Install PHP

Install PHP modules

sudo apt install php libapache2-mod-php php-mysql

install Nextcloud dependencies

sudo apt install php-curl php-dom php-gd php-json php-xml php-mbstring php-zip

adjust PHP.ini

sudo vim /etc/php/7.4/apache2/php.ini


memory_limit = 1024M # based on how much RAM the server has
upload_max_filesize = 16G # max size of uploaded files
post_max_size = 16G # something similar to the above
date.timezone = Europe/Rome # or your timezone

Install Nextcloud

download Nextcloud and place it in the virtual host directory

sudo cd /var/www/ && sudo wget

extract the downloaded package


Install Let’s Encrypt

Certbot will be use to establish a secure connection to the instance. To make things simple, it’s the one which makes an unencrypted http:// connection magically become an encrypted https:// connection

sudo apt install certbot python3-certbot-apache

Enable port 443 instead of port 80

sudo ufw allow 'Apache Full'
sudo ufw delete allow 'Apache'

Generate TLS certificate

sudo certbot --apache -d -d

Enable HTTP/2, and rewrite module

sudo apt install php7.4-fpm
sudo a2enmod proxy_fcgi
sudo a2enconf php7.4-fpm
sudo a2dismod php7.4
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo service apache2 restart
sudo a2enmod http2
sudo service apache2 restart

Enable HSTS

add in

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

to enable what has just been inserted, headers abilitation must be performed

sudo a2enmod headers

then, enable .htaccess

sudo vim /etc/apache2/sites-available/

paste in <VirtualHost *:443>

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

restart apache

systemctl restart apache2

Set the domain and complete setup

  • point the chosen domain and subdomain to the server IP address
  • wait for the domain to propagate (it could take up to 48 hours)
  • go to, where you should get this page:
Nextcloud first setup page
Nextcloud first setup page

Don’t insert any data in the dialogue page above until connection is encrypted with https://. To obtain a SSL Certificate, thus an encrypted connection, follow the next step.

Final adjustments

Final adjustments are to be performed from the Nextcloud GUI. The Nextcloud apps I installed are listed here


  • fix this encryption error

Nextcloud cheatsheet

A list of useful commands to perform when needed (often).

Manually install applications

move to the Nextcloud apps folder

cd /var/www/nextcloud/apps

download the application package from Nextcloud apps website

wget # url to the package

extract it (by substituting package_name with the name of the app package)

tar -xvzf package_name.tar.gz

remove compressed package

rm -rf package_name.tar.gz

change permissions for the app’s directory

chown -R www-data:www-data /var/www/nextcloud/apps/app_name
chmod -R 755 /var/www/nextcloud/apps/app-name

Manteinance mode

enable manteinance mode

sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --on

disable manteinance mode

sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --off

Install Jitsi Meet

installation guide

allow firewall for ports 100000 to 200000

sudo ufw allow in 10000:20000/udp

Jitsi requires the Java Runtime Environment. Install OpenJDK JRE 8.

NOTE: as of right now, Jitsi Meet needs JRE 8, not a newer version!

sudo apt install -y openjdk-8-jre-headless

check if installation went the right way and if the right version is installed

java -version

setup Java Runtime

sudo echo "JAVA_HOME=$(readlink -f /usr/bin/java | sed "s:bin/java::")" | sudo tee -a /etc/profile
sudo source /etc/profile

download Jitsi Meet and add it to apt downloadable list

wget -qO - | sudo apt-key add -
echo "deb stable/"  | sudo tee -a /etc/apt/sources.list.d/jitsi-stable.list

install Jitsi Meet

sudo apt install -y jitsi-meet

run and enable certbot

sudo sed -i 's/\.\/certbot-auto/certbot/g' /usr/share/jitsi-meet/scripts/
sudo ln -s /usr/bin/certbot /usr/sbin/certbot
sudo /usr/share/jitsi-meet/scripts/

If something around here doesn’t work, no worries: just repeat the command, it should get fixed by itself

last tweaks should be done in here

sudo vim /etc/apache2/conf-enabled/security.conf

There are a few very nice things, such as hiding the “Jitsi” watermark from calls, which can be improved by editing Jitsi’s css file. Here’s a customizations guide.

suggest edit

share this post