Nextcloud on RAID with SSL and Domain (Archived Tutorial)
Archived tutorial on installing Nextcloud with Debian 12, RAID5, and SSL. Outdated practices, kept only for reference.
Disclaimer: This tutorial was written in mid‑2024 as one of my first self‑hosting experiments. Some practices are outdated or insecure. I keep this post online only for historical/reference purposes.
Introduction
This tutorial aimed to install Nextcloud from scratch on a Debian 12 server, configure a RAID5 array for data storage, and secure external access with SSL certificates.
It covers:
- Debian 12 installation and setup
- RAID5 configuration
- Apache and PHP setup
- Nextcloud installation
- DDNS for external access
- SSL certificates via Let’s Encrypt
- Firewall and caching configuration
(Content below remains as originally written in 2024, for archival purposes only.)
1. Install Debian 12
1.1. Download the Debian 12 image
Download the Debian 12 netinstall image from the official website
1.2. Install Debian 12
Burn the image to a USB drive using balenaEtcher or Rufus
Installation
Install the operating system with your preferred options on a different disk from the one you are going to use for RAID 5.
Finally, uncheck the option to install the graphical environment. Only install the base system and the SSH server.
Once the installation is complete, restart the system and log in with the username and password you have set.
2. Mount RAID 5
2.1. Install mdadm
1
apt install mdadm
2.2. Create RAID 5
List the disks
1
fdisk -l
We look at which disks we want to use for RAID 5, in this case sda, sdb, and sdc.
1
mdadm --create /dev/md0 --level=5 --raid-devices=3 /dev/sda /dev/sdb /dev/sdc
Verify that it has been created correctly
1
sudo mdadm --detail /dev/md0
Create a file system
1
mkfs.ext4 /dev/md0
2.3. Mounting the RAID 5
Mount the RAID
1
2
sudo mkdir -p /mnt/raid
sudo mount /dev/md0 /mnt/raid
Configure automatic mounting
1
sudo blkid /dev/md0
This will give us a UUID. Copy it and edit the /etc/fstab file
1
sudo nano /etc/fstab
Add the following line
1
UUID=xxxx
3. Asegurar el servidor
3.1. Cambiar el puerto ssh
1
sudo nano /etc/ssh/sshd_config
Y encontraremos la línea
1
# Port 22
La descomentamos y cambiamos el puerto 22 por el que queramos, por ejemplo 2222
1
Port 2222
Guardamos y reiniciamos el servicio
1
sudo systemctl restart sshd
3.2 instalar UFW
1
sudo apt install ufw
Configuramos el firewall, sustituyendo el puerto 2222 por el que hayamos elegido
1
2
3
4
5
6
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 2222/tcp comment 'SSH'
ufw allow http
ufw allow https
sudo ufw enable
Comprobamos que el firewall está activo
1
2
sudo ufw status
# ufw reload # para recargar la configuración en caso de cambios
3.3 Keygen para ssh
En el cliente ejecutamos el siguiente comando, sustituyendo <client_name>
por el nombre elijamos.
1
ssh-keygen -t rsa -b 4096 -C "<client_name>"
Vamos al archivo donde se ha guardado la clave pública y mandamos la clave al servidor
1
cat ~/.ssh/id_rsa.pub
Manda la clave al servidor
1
scp -P 2222 ~/.ssh/id_rsa.pub <user>@<server_ip>:/home/<user>/.ssh/authorized_keys
Nota: Si no existe el directorio .ssh en el servidor, lo creamos
Desde el servidor hacemos que solo se acepten conexiones ssh con clave
1
sudo nano /etc/ssh/sshd_config
Y cambiamos las siguientes líneas
1
2
#PasswordAuthentication yes
#PermitRootLogin yes
Por
1
2
PasswordAuthentication no
PermitRootLogin no
Reiniciamos el servicio
1
sudo systemctl restart sshd
Ahora cuando intentemos acceder al servidor por ssh, deberia localizar la clave privada y no pedirnos la contraseña.
4. Install Nextcloud
4.1 Apache, MariaDB, and PHP
4.1.1 Install Apache and MariaDB
1
2
sudo apt update
sudo apt install apache2 mariadb-server
Perform a secure installation of MariaDB
1
sudo mariadb-secure-installation
We answer the questions
1
2
3
4
5
6
7
Enter current password for root (enter for none): <root_password>
Switch to unix_socket authentication [Y/n] n
change the root password? [Y/n] n
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
4.1.2 Prepare the database
1
sudo mariadb -u root
1
2
3
4
5
create database nextcloud;
create user ‘nextcloud’@'localhost' identified by ‘<nextcloud_password>’;
grant all privileges on nextcloud.* to ‘nextcloud’@'localhost';
flush privileges;
quit
4.1.3 Install PHP and necessary modules
1
2
3
4
5
6
sudo apt install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt update
sudo apt upgrade
sudo apt install php8.2
sudo apt-get install -y php8.2 libapache2-mod-php8.2 libmagickcore-6.q16-6-extra php8.2-mysql php8. 2-common php8.2-bz2 php8.2-redis php8.2-dom php8.2-curl php8.2-exif php8.2-fileinfo php8.2-bcmath php8.2-gmp php8.2-imagick php8.2-mbstring php8.2-xml php8.2-zip php8. 2-iconv php8.2-intl php8.2-simplexml php8.2-xmlreader php8.2-ftp php8.2-ssh2 php8.2-sockets php8.2-gd php8.2-imap php8.2-soap php8.2-xmlrpc php8.2-apcu php8.2-dev php8.2-cli
4.2 Install Nextcloud
4.2.1 Download Nextcloud
- Go to the Nextcloud website
- Click on COMMUNITY PROJECTS
- In the Archive section, right-click on Get zip file and copy the link address
- Download the file to the server
1
wget https://download.nextcloud.com/server/releases/latest.zip
Unzip the file
1
unzip latest.zip -d /var/www
Note: If you don’t have unzip installed, install it with
sudo apt install unzip
Change the permissions
1
2
cd /var/www
sudo chown -R www-data:www-data nextcloud/
4.2.2 Configure Apache
1
2
3
sudo a2enmod headers env dir mime rewrite
sudo service apache2 restart
systemctl restart apache2 # if the previous command does not work
Edit the Apache configuration file
1
sudo nano /etc/apache2/sites-available/000-default.conf
And add the following lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<VirtualHost *:80>
ServerName tu_dominio.com
DocumentRoot /var/www/nextcloud
<Directory /var/www/nextcloud/>
Require all granted
AllowOverride All
Options FollowSymLinks MultiViews
<IfModule mod_dav.c>
Dav off
</IfModule>
RewriteEngine On
RewriteRule ^/\.well-known/carddav https://%{SERVER_NAME}/remote.php/dav/ [R=301,L]
RewriteRule ^/\.well-known/caldav https://%{SERVER_NAME}/remote.php/dav/ [R=301,L]
RewriteRule ^/\.well-known/host-meta https://%{SERVER_NAME}/public.php?service=host-meta [QSA,L]
RewriteRule ^/\.well-known/host-meta\.json https://%{SERVER_NAME}/public.php?service=host-meta-json [QSA,L]
RewriteRule ^/\.well-known/webfinger https://%{SERVER_NAME}/public.php?service=webfinger [QSA,L]
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Save and restart Apache
1
2
sudo service apache2 restart
sudo systemctl restart apache2 # if the previous command does not work
4.2.3 Configuring Nextcloud
4.2.3.1 Router configuration
First, I recommend assigning a static IP address to the server. This can be done from the router settings. Each router is different, so I cannot provide exact instructions, but in most cases it can be done from the DHCP section.
4.2.3.2 Nextcloud configuration
Access the server’s IP address from a browser and follow the steps to install Nextcloud.
- Set the administrator username and password
- Set the data folder
- Data folder: /mnt/raid/nextcloud/data
- Set the database
- Database account: nextcloud
- Database password: the one you have set
- Database name: nextcloud
- Server: localhost
Note: if you have not created the data folder, do so with
sudo mkdir -p /mnt/raid/nextcloud/data
and make sure that the www-data user has write permissions for the folder with the commandsudo chown -R www-data:www-data /mnt/raid/nextcloud/data
Once the upload is complete, we will tell you to install the recommended applications.
When the process is complete, we can fix some errors that will appear in the administration section.
4.3 Troubleshooting errors
4.3.1 The PHP memory limit is below the recommended value of 512MB.
Edit the PHP configuration file
1
sudo nano /etc/php/8.2/apache2/php.ini
And change the line
1
memory_limit = 128M
To
1
memory_limit = 512M
4.3.2 Set up Cronjob for Nextcloud
1
sudo crontab -u www-data -e
And add the following line
1
*/5 * * * * php -f /var/www/nextcloud/cron.php
4.3.3 No default phone region set
1
sudo nano /var/www/nextcloud/config/config.php
And add the following line with your country code
1
‘default_phone_region’ => ‘ES’,
4.3.4 No memory cache has been configured.
It is highly recommended to configure a cache system. To do this, we will use Redis, which was already installed during the PHP installation process.
We can check that Redis is working with the following command
1
ps ax | grep redis
If we don’t get a result similar to
1
2488834 ? Ssl 1:24 /usr/bin/redis-server 127.0.0.1:6379
We can install Redis with
1
sudo apt install redis-server php8.2-redis
Add the www-data user to the redis group and restart the service
1
2
sudo usermod -a -G redis www-data
sudo service apache2 restart
Edit the Nextcloud configuration file
1
sudo nano /var/www/nextcloud/config/config.php
Add the following lines
1
2
3
4
5
6
7
8
‘filelocking.enabled’ => true,
‘memcache.local’ => ‘\\OC\\Memcache\\APCu’,
‘memcache.locking’ => ‘\\OC\\Memcache\\Redis’,
‘redis’ =>
array (
‘host’ => ‘127.0.0.1’,
‘port’ => 6379,
),
Note: If you encounter errors when uploading and editing files in the future and receive messages such as “file is locked” or similar, try disabling file locking with the following line:
‘filelocking.enabled’ => false,
Save and restart Apache
1
sudo service apache2 restart
4.3.5 Fix php-imagick warning.
1
2
3
sudo apt remove imagemagick-6-common php-imagick
sudo apt autoremove
sudo apt install imagemagick php-imagick
4.3.6 Fix the PHP module ‘apcu’ is not available.
1
sudo -u www-data php --define apc.enable_cli=1 /var/www/nextcloud/occ maintenance:repair
4.3.7 The server does not have a maintenance window configured
1
sudo nano /var/www/nextcloud/config/config.php
And add the following line
1
‘maintenance_window_start’ => ‘4’,
This will set the maintenance window from 4 to 5 a.m.
5. Secure access from outside
5.1 Configure a DDNS
5.1.1 Create a domain in DynDNS
- Create an account at DynDNS
- In the DDNS menu, click sign up
- Option 1: Use Our Domain Name
- Give your domain a name
- Save the domain
Add a task to cron to update the IP
1
crontab -e
Add a line like the following
1
*/15 * * * * wget -O dynulog -4 “https://api.dynu.com/nic/update?hostname=example.dynu.com&myip=10.0.0.0&myipv6=no&username=someusername&password=somepassword”
Add the domain to the Nextcloud configuration
1
sudo nano /var/www/nextcloud/config/config.php
And add the following line
1
2
3
4
5
6
‘trusted_domains’ =>
array (
0 => ‘xxx.xxx.xxx.xxx’,
1 => ‘your_domain.com’,
2 => ‘subdomain.your_domain.com’,
),
Save and restart Apache
1
sudo service apache2 restart
5.2 Configure a port on the router
Once you have configured DDNS, you must configure the router to allow external access.
- Access the router settings
- Find the port forwarding section
- Add a new rule
- Name: Nextcloud
- Protocol: TCP
- External port: 443
- Internal IP: the server’s IP
- Internal port: 443
- Save the configuration
- Add a second rule
- Name: Nextcloud
- Protocol: TCP
- External port: 80
- Internal IP: the server’s IP address
- Internal port: 80
- Save the configuration
- Optionally, you can add a rule for port 2222 (or whichever you chose) to access via SSH from outside.
5.3 SSL (Let’s Encrypt)
To securely access our server from outside, we need an SSL certificate. To do this, we will use Let’s Encrypt.
5.3.1 Install certbot
1
2
3
sudo apt install snapd
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
5.3.2 Obtain a certificate
This command will perform the necessary configuration in Apache and automatically obtain an SSL certificate. It will also configure automatic certificate renewal.
1
sudo certbot --apache
If you have followed everything correctly, your /etc/apache2/sites-available/000-default.conf file should have a configuration similar to this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<VirtualHost *:80>
ServerName your_domain.com
DocumentRoot /var/www/nextcloud
<Directory /var/www/nextcloud/>
Require all granted
AllowOverride All
Options FollowSymLinks MultiViews
<IfModule mod_dav.c>
Dav off
</IfModule>
RewriteEngine On
RewriteRule ^/\.well-known/carddav https://%{SERVER_NAME}/remote.php/dav/ [R=301,L]
RewriteRule ^/\.well-known/caldav https://%{SERVER_NAME}/remote.php/dav/ [R=301,L]
RewriteRule ^/\.well-known/host-meta https://%{SERVER_NAME}/public.php?service=host-meta [QSA,L]
RewriteRule ^/\.well-known/host-meta\.json https://%{SERVER_NAME}/public.php?service=host-meta-json [QSA,L]
RewriteRule ^/\.well-known/webfinger https://%{SERVER_NAME}/public.php?service=webfinger [QSA,L]
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteCond %{SERVER_NAME} =your_domain.com [OR]
RewriteCond %{SERVER_NAME} =your_domain.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
We verify that the certificate renews itself correctly
1
sudo certbot renew --dry-run
and if everything is correct, we should see a message similar to
1
2
3
4
5
6
7
8
9
10
11
12
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/<your_domain>.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Account registered.
Simulating renewal of an existing certificate for <your_domain>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/<your_domain>/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
And with the command systemctl list-timers
, we should see the following line
1
Tue 2024-07-23 00:03:00 CEST 9h left - - snap.certbot.renew.timer snap.certbot.renew.service
This indicates that the certificate renewal will be checked periodically.
6. Conclusions
In this tutorial, we have installed Nextcloud on a server running Debian 12, set up a RAID 5 array to store data securely, and configured secure external access with an SSL certificate.
Now we can securely access our files from anywhere and rest assured that our data is safe.