Nextcloud is a free (open source) dropbox-like software, a fork of the ownCloud project. Nextcloud is written in PHP and JavaScript, it supports many database systems like MySQL/MariaDB, PostgreSQL, Oracle database and SQLite.

To keep your files in sync between desktop and server, Nextcloud offers applications for Windows, Linux and Mac desktops and a mobile application for Android and iOS.

In this tutorial, we show you how to install Nextcloud 17 with the Nginx web server, PHP 7.3 and MariaDB database on a CentOS 8 server. We will install Nextcloud and secure it with a free Let’s Encrypt SSL certificate.

Prerequisite

For this guide, we will install Nextcloud on the CentOS 8 server with 2GB of RAM, 25GB of free space, and 2CPUs.

What we will do:

  • Install Nginx Web Server
  • Install PHP-FPM 7.3
  • Configure PHP-FPM 7.3
  • Install and Configure the MariaDB Database
  • Generate SSL Letsencrypt
  • Download Nextcloud 17
  • Setup Nginx Virtualhost for Nextcloud
  • Setup SELinux for Nextcloud
  • Nextcloud Post-Installation

Step 1 – Install Nginx

First, we will install the Nginx webserver to the CentOS 8 server and open the HTTP and HTTPS port on the firewalld.

Install Nginx from the AppStream repository using the dnf command below.

sudo dnf install nginx

Once the installation is complete, start the nginx service and add it to the system boot.

systemctl start nginx

systemctl enable nginx

Now check the nginx service status using the command below.

systemctl status nginx

You will get the nginx service is up and running on CentOS 8 server.

Next, we will add the HTTP and HTTPS services to the firewalld.

Add the HTTP and HTTPS services to the firewalld using the firewall-cmd command below.

firewall-cmd --add-service=http --permanent

firewall-cmd --add-service=https --permanent

After that, reload the firewalld services.

firewall-cmd --reload

As a result, you’ve successfully installed the Nginx web server and open the HTTP and HTTPS ports on the CentOS 8 server.

Step 2 – Install PHP-FPM

According to the Nextcloud system requirement, it’s recommended to use the PHP 7.2 or PHP 7.3 for its installation.

For this guide, we will be using the PHP 7.3 that can be installed from the REMI repository.

Before going any further, we will enable the ‘PowerTools’ repository and add the EPEL and REMI repositories for CentOS 8 server.

Run the dnf command below.

sudo dnf config-manager --set-enabled PowerTools

sudo dnf install epel-release

sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm

Now check all available repository on the system.

dnf repolist

And you will get the result as below.

You’ve enabled the ‘PowerTools’ repository and added the EPEL and REMI repositories for CentOS 8.

Next, we will enable the PHP 7.3 REMI repository.

Check all available modules for PHP packages.

dnf module list php

Now enable the module of PHP 7.3 REMI repository.

dnf module enable php:remi-7.3

After that, install PHP and PHP-FPM 7.3 packages for Nextcloud using the dnf command below.

sudo dnf install php-fpm php-cli php-devel php-gd php-mysqlnd php-pear php-xml php-mbstring php-pdo php-json php-pecl-apcu php-pecl-apcu-devel php-pecl-imagick-devel php-intl php-opcache php-zip

And you’ve installed PHP and PHP-FPM 7.3 to the CentOS 8 system.

Step 3 – Configure PHP-FPM 7.3

In this step, we will set up the PHP-FPM for Nextcloud deployment.

Edit the ‘php.ini’ configuration using the following command.

vim /etc/php.ini

Uncomment and change the configuration as below.

memory_limit = 512M

date.timezone = Asia/Jakarta

cgi.fixpathinfo = 0

Save and close.

Now edit the PHP opcache configuration ‘/etc/php.d/10-opcache.ini’.

vim /etc/php.d/10-opcache.ini

Change the configuration as below.

opcache.enable=1

opcache.interned_strings_buffer=8

opcache.max_accelerated_files=10000

opcache.memory_consumption=128

opcache.save_comments=1

opcache.revalidate_freq=1

Save and close.

Next, edit the PHP-FPM configuration ‘/etc/php-fpm.d/www.conf’.

vim /etc/php-fpm.d/www.conf

Change the ‘user’ and ‘group’ to ‘nginx’.

user = nginx

group = nginx

Change the ‘listen’ configuration to the sock file as below.

listen = /run/php-fpm/www.sock

Uncomment the PHP environment variable below.

env[HOSTNAME] = $HOSTNAME

env[PATH] = /usr/local/bin:/usr/bin:/bin

env[TMP] = /tmp

env[TMPDIR] = /tmp

env[TEMP] = /tmp

Uncomment the opcache configuration on the last line.

php_value[opcache.file_cache] = /var/lib/php/opcache

Save and close.

Now create a new directory for PHP session and opcache, then change the owner of those directories to ‘nginx’ user and group.

mkdir -p /var/lib/php/{session,opcache}

chown -R nginx:nginx /var/lib/php/{session,opcache}

And you’ve completed the PHP-FPM configuration for Nextcloud installation.

Start the PHP-FPM service and add it to the system boot.

systemctl enable php-fpm

systemctl start php-fpm

Now check the PHP-FPM sock file and the service status.

netstat -pl | grep php

systemctl status php-fpm

And you will get the result as below.

As a result, the PHP-FPM up and running under the sock file ‘/run/php-fpm/www.sock’.

Step 4 – Install and Configure MariaDB

In this step, we will install the MariaDB database server, setup the root password authentication, and create a new database and user for Nextcloud.

Install the MariaDB database using the dnf command below.

sudo dnf install mariadb mariadb-server

Once the installation is complete, start the MariaDB service and add it to the system boot.

systemctl start mariadb

systemctl enable mariadb

And the MariaDB service is up and running.

Next, we will set up the root password authentication using the ‘mysql_secure_installation’ command below.

mysql_secure_installation

Type your root password and type ‘Y’ for the rest configuration.

Set a root password? [Y/n] Y

Remove anonymous users? [Y/n] Y

Remove test database and access to it? [Y/n] Y

Reload privilege tables now? [Y/n] Y

And the MariaDB root password has been configured.

Now log in to the MySQL shell using the mysql command below.

mysql -u root -p

TYPE YOUR ROOT PASSWORD

Now create a new database ‘nextcloud_db’ and create a new user ‘nextclouduser’ with the password ‘nextcloudpassdb’ using the queries below.

create database nextcloud_db;

create user [email protected] identified by 'nextcloudpassdb';

grant all privileges on nextcloud_db.* to [email protected] identified by 'nextcloudpassdb';

flush privileges;

And you’ve created the database and user for Nextcloud installation.

Step 4 – Generate SSL Letsencrypt

In this step, we will generate the SSL letsencrypt using the ‘certbot’. The SSL certificates will be used to secure Nextcloud access.

Install certbot from the EPEL repository using the dnf command below.

sudo dnf install certbot

Once the installation is complete, generate the SSL certificates for the Nextcloud domain name using the command below and make sure to change the domain name and email address with your own.

certbot certonly --webroot --webroot-path /usr/share/nginx/html --agree-tos -m [email protected] -d cloud.hakase-labs.io

Once it’s complete, all generated SSL certificates are located at the ‘/etc/letsencrypt/live/cloud.hakase-labs.io’ directory.

Check it using the following command.

ls -lah /etc/letsencrypt/live/cloud.hakase-labs.io/

And you’ve generated the SSL letsencrypt using the certbot tool.

Step 5 – Download and Install Nextcloud

In this step, we will download the latest version of Nextcloud 17.

Before downloading the nextcloud source code, install the zip package to the system.

sudo dnf install unzip

Now go to the ‘/var/www/’ directory and download the Nextcloud source code using the wget command as below.

cd /var/www/

wget https://download.nextcloud.com/server/releases/nextcloud-17.0.2.zip

Extract the Nextcloud source code using the command below.

unzip nextcloud-17.0.2.zip

And you will get a new directory called ‘nextcloud’.

Now create a new ‘data’ directory for Nextcloud. The ‘data’ directory will be used to store user data.

mkdir -p /var/www/nextcloud/data/

After that, change the owner of ‘nextcloud’ directory to the ‘nginx’ user and group.

sudo chown -R nginx:nginx /var/www/nextcloud

And you’ve downloaded the latest Nextcloud 17 to the ‘/var/www’ directory.

Step 6 – Set up Nginx Virtual Host for Nextcloud

After downloading the Nextcloud source code, we will set up the Nginx virtual host for Nextcloud.

Go to the ‘/etc/nginx/conf.d’ directory and create a new configuration ‘nextcloud.conf’.

cd /etc/nginx/conf.d/

vim nextcloud.conf

Now change the domain name and SSL certificate path with your own and paste the following configuration into it.

upstream php-handler {

 #server 127.0.0.1:9000;

 server unix:/run/php-fpm/www.sock;

}
server {

 listen 80;

 listen [::]:80;

 server_name cloud.hakase-labs.io;

 # enforce https

 return 301 https://$server_name:443$request_uri;

}

server {

 listen 443 ssl http2;

 listen [::]:443 ssl http2;

 server_name cloud.hakase-labs.io;

 # Use Mozilla's guidelines for SSL/TLS settings

 # https://mozilla.github.io/server-side-tls/ssl-config-generator/

 # NOTE: some settings below might be redundant

 ssl_certificate /etc/ssl/nginx/fullchain.pem;

 ssl_certificate_key /etc/ssl/nginx/privkey.pem;

 # Add headers to serve security related headers

 # Before enabling Strict-Transport-Security headers please read into this

 # topic first.

 #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;

 #

 # WARNING: Only add the preload option once you read about

 # the consequences in https://hstspreload.org/. This option

 # will add the domain to a hardcoded list that is shipped

 # in all major browsers and getting removed from this list

 # could take several months.

 add_header Referrer-Policy "no-referrer" always;

 add_header X-Content-Type-Options "nosniff" always;

 add_header X-Download-Options "noopen" always;

 add_header X-Frame-Options "SAMEORIGIN" always;

 add_header X-Permitted-Cross-Domain-Policies "none" always;

 add_header X-Robots-Tag "none" always;

 add_header X-XSS-Protection "1; mode=block" always;

 # Remove X-Powered-By, which is an information leak

 fastcgi_hide_header X-Powered-By;

 # Path to the root of your installation

 root /var/www/nextcloud;

 location = /robots.txt {

 allow all;

 log_not_found off;

 access_log off;

 }

 # The following 2 rules are only needed for the user_webfinger app.

 # Uncomment it if you're planning to use this app.

 #rewrite ^/.well-known/host-meta /public.php?service=host-meta last;

 #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;

 # The following rule is only needed for the Social app.

 # Uncomment it if you're planning to use this app.

 #rewrite ^/.well-known/webfinger /public.php?service=webfinger last;

 location = /.well-known/carddav {

 return 301 $scheme://$host:$server_port/remote.php/dav;

 }

 location = /.well-known/caldav {

 return 301 $scheme://$host:$server_port/remote.php/dav;

 }

 # set max upload size

 client_max_body_size 512M;

 fastcgi_buffers 64 4K;

 # Enable gzip but do not remove ETag headers

 gzip on;

 gzip_vary on;

 gzip_comp_level 4;

 gzip_min_length 256;

 gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;

 gzip_types application/atom xml application/javascript application/json application/ld json application/manifest json application/rss xml application/vnd.geo json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest json application/xhtml xml application/xml font/opentype image/bmp image/svg xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

 # Uncomment if your server is built with the ngx_pagespeed module

 # This module is currently not supported.

 #pagespeed off;

 location / {

 rewrite ^ /index.php;

 }

 location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {

 deny all;

 }

 location ~ ^/(?:.|autotest|occ|issue|indie|db_|console) {

 deny all;

 }

 location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/. |oc[ms]-provider/. ).php(?:$|/) {

 fastcgi_split_path_info ^(. ?.php)(/.*|)$;

 set $path_info $fastcgi_path_info;

 try_files $fastcgi_script_name =404;

 include fastcgi_params;

 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

 fastcgi_param PATH_INFO $path_info;

 fastcgi_param HTTPS on;

 # Avoid sending the security headers twice

 fastcgi_param modHeadersAvailable true;

 # Enable pretty urls

 fastcgi_param front_controller_active true;

 fastcgi_pass php-handler;

 fastcgi_intercept_errors on;

 fastcgi_request_buffering off;

 }

 location ~ ^/(?:updater|oc[ms]-provider)(?:$|/) {

 try_files $uri/ =404;

 index index.php;

 }

 # Adding the cache control header for js, css and map files

 # Make sure it is BELOW the PHP block

 location ~ .(?:css|js|woff2?|svg|gif|map)$ {

 try_files $uri /index.php$request_uri;

 add_header Cache-Control "public, max-age=15778463";

 # Add headers to serve security related headers (It is intended to

 # have those duplicated to the ones above)

 # Before enabling Strict-Transport-Security headers please read into

 # this topic first.

 #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;

 #

 # WARNING: Only add the preload option once you read about

 # the consequences in https://hstspreload.org/. This option

 # will add the domain to a hardcoded list that is shipped

 # in all major browsers and getting removed from this list

 # could take several months.

 add_header Referrer-Policy "no-referrer" always;

 add_header X-Content-Type-Options "nosniff" always;

 add_header X-Download-Options "noopen" always;

 add_header X-Frame-Options "SAMEORIGIN" always;

 add_header X-Permitted-Cross-Domain-Policies "none" always;

 add_header X-Robots-Tag "none" always;

 add_header X-XSS-Protection "1; mode=block" always;

 # Optional: Don't log access to assets

 access_log off;

 }

 location ~ .(?:png|html|ttf|ico|jpg|jpeg|bcmap)$ {

 try_files $uri /index.php$request_uri;

 # Optional: Don't log access to other assets

 access_log off;

 }

}

Save and close.

After that, test the nginx configuration and restart the Nginx service. And make sure there is no error.

nginx -t

systemctl restart nginx

Now the Nginx service will open a new HTTPS port on the system, check it using the following command.

netstat -plntu

And you will get the result as below.

As a result, you’ve added the Nginx virtual host configuration for Nextcloud and enabled the secure HTTPS on top of it.

Step 7 – Set up SELinux for Nextcloud

For this tutorial, we will be using the SELinux on the ‘enforcing’ mode. And we will setup the SELinux for Nextcloud installation.

Install the SELinux management tool using the dnf command below.

sudo dnf install policycoreutils-python-utils

Now execute the following command as root on your server.

semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/data(/.*)?'

semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/config(/.*)?'

semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/apps(/.*)?'

semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/assets(/.*)?'

semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/.htaccess'

semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/.user.ini'
restorecon -Rv '/var/www/nextcloud/'

And the SELinux configuration for Nextcloud has been completed.

Step 8 – Nextcloud Installation Wizard

Now open your web browser and type your Nextcloud domain name on the address bar.

https://cloud.hakase-labs.io/

Now you will get the Nextcloud installation page as below.

Type your admin user and password, then choose the ‘MySQL/MariaDB’ as your database and type details about the database that you’ve created on top.

Now click the ‘Finish Setup’ button and the installation will begin.

Once the installation is complete, you will get the Nextcloud dashboard as below.

As a result, you’ve successfully installed the latest Nextcloud 17 with the Nginx web server, PHP-FPM 7.3, and MariaDB database on the CentOS 8 server.

Reference