Guide to Installing and Configuring Nextcloud on Fedora 32

Nextcloud is an open-source software suite designed for storing and synchronizing your data across multiple devices, offering you the functionality of your own Dropbox-like environment. In addition to file storage, Nextcloud provides features like Calendar, Contacts, Task scheduling, media streaming, and more, making it a comprehensive solution for your data management needs.

With apps available for Windows, Linux, MacOS, as well as mobile applications for Android and iOS, Nextcloud enables seamless file synchronization across a variety of devices, allowing you to access your data wherever you go.

In this guide, we will walk through the process of installing and configuring Nextcloud on a Fedora 32 based server. We will set up an Nginx web server, along with PHP 7.4 and MariaDB to get your Nextcloud instance up and running.

Prerequisites

  • A server running Fedora 32.
  • A non-root sudo user.
  • Ensure all packages are up-to-date.
    $ sudo dnf update
    
  • Essential packages:
    $ sudo dnf install wget curl bzip2 nano unzip policycoreutils-python-utils -y
    

    Note: Some packages may already be installed on your system.

Configure Firewall

We begin by configuring the firewall on your Fedora server, which uses Firewalld as its default firewall solution.

Verify that Firewalld is running:

$ sudo firewall-cmd --state
running

Review the current allowed services/ports:

$ sudo firewall-cmd --permanent --list-services

The expected output should display services like the one below:

dhcpv6-client mdns ssh

Enable HTTP and HTTPS services:

$ sudo firewall-cmd --permanent --add-service=http
$ sudo firewall-cmd --permanent --add-service=https

Recheck the firewall service list:

$ sudo firewall-cmd --permanent --list-services

You should now see:

dhcpv6-client http https mdns ssh

Reload the firewall configuration:

$ sudo systemctl reload firewalld

Install PHP

While Fedora 32 comes with PHP 7.4 by default, we will install the REMI repository to ensure we have the latest PHP packages.

First, add the REMI repository:

$ sudo dnf -y install https://rpms.remirepo.net/fedora/remi-release-32.rpm

Next, enable the remi repository and disable the remi-modular repository:

$ sudo dnf config-manager --set-enabled remi
$ sudo dnf config-manager --set-disabled remi-modular

Install PHP 7.4 along with necessary extensions:

$ sudo dnf install php-fpm php-cli php-gd php-mbstring php-intl php-mysqlnd php-imagick php-zip php-json php-process php-xml php-bcmath php-gmp php-ftp php-smbclient php-opcache

Verify PHP installation:

$ php --version
PHP 7.4.11 (cli) (built: Sep 29 2020 10:17:06) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.11, Copyright (c), by Zend Technologies

Configure PHP

Edit the PHP configuration for PHP-FPM by opening the /etc/php-fpm.d/www.conf file:

$ sudo nano /etc/php-fpm.d/www.conf

Change the user/group settings from apache to nginx:

...
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
; RPM: apache user chosen to provide access to the same directories as httpd
user = nginx
; RPM: Keep a group allowed to write in log dir.
group = nginx
...

Uncomment the following PHP environment variables:

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

Also, uncomment the opcache configuration line:

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

Save changes by pressing Ctrl + X and confirm with Y.

Edit the PHP Opcache configuration file /etc/php.d/10-opcache.ini:

$ sudo nano /etc/php.d/10-opcache.ini

Adjust the Opcache settings as displayed:

opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=1
opcache.save_comments=1

Save and close the file by pressing Ctrl + X, followed by Y.

Update PHP’s file upload and memory limit settings:

$ sudo cp /etc/php.ini /etc/php.ini.bak
$ sudo sed -i "s/memory_limit = 128M/memory_limit = 512M/" /etc/php.ini
$ sudo sed -i "s/post_max_size = 8M/post_max_size = 100M/" /etc/php.ini
$ sudo sed -i "s/upload_max_filesize = 2M/upload_max_filesize = 100M/" /etc/php.ini

Adjust file permissions on the PHP directories for the Nginx user:

$ sudo setfacl -R -m u:nginx:rwx /var/lib/php/opcache/
$ sudo setfacl -R -m u:nginx:rwx /var/lib/php/session/
$ sudo setfacl -R -m u:nginx:rwx /var/lib/php/wsdlcache/

Enable and start PHP-FPM:

$ sudo systemctl enable php-fpm
$ sudo systemctl start php-fpm

Install Nginx

Fedora 32 comes with the latest stable version of Nginx.

Install Nginx:

$ sudo dnf install nginx -y

Verify the Nginx installation:

$ nginx -v
nginx version: nginx/1.18.0

Start and enable Nginx:

$ sudo systemctl start nginx
$ sudo systemctl enable nginx

Visit your server’s IP address in a web browser. You should see the default Nginx page:

Fedora Default Nginx Page

Install MariaDB

MariaDB is used as a database management system, serving as a direct replacement for MySQL with compatible commands.

Fedora 32 includes MariaDB 10.4 by default. Install MariaDB:

$ sudo dnf install mariadb-server

Verify the MariaDB installation:

$ mysql --version
mysql  Ver 15.1 Distrib 10.4.14-MariaDB, for Linux (x86_64) using  EditLine wrapper

Enable and start the MariaDB service:

$ sudo systemctl enable mariadb
$ sudo systemctl start mariadb

Run the secure installation script to configure MariaDB:

$ sudo mysql_secure_installation

Press Enter to select the default options, such as disallowing remote root login and removing test databases.

Enter current password for root (enter for none): [PRESS ENTER]
Switch to unix_socket authentication [Y/n] [PRESS ENTER]
Change the root password? [Y/n] [ANSWER n]
Remove anonymous users? [Y/n] [PRESS ENTER]
Disallow root login remotely? [Y/n] [PRESS ENTER]
Remove test database and access to it? [Y/n] [PRESS ENTER]
Reload privilege tables now? [Y/n] [PRESS ENTER]

When logging into MySQL, use:

$ sudo mysql

Enter your root password if prompted.

Configure MariaDB

Log into the MySQL shell to start creating a database and user for Nextcloud:

$ sudo mysql

Create a new MySQL user for Nextcloud:

mysql> CREATE USER 'nextuser'@'localhost' IDENTIFIED BY 'yourpassword';

Create the Nextcloud database:

mysql> CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

Grant necessary privileges to the new user:

mysql> GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextuser'@'localhost';

Exit the MySQL Shell:

mysql> exit

Download and Setup Nextcloud

Proceed to download and arrange the Nextcloud directories:

$ wget https://download.nextcloud.com/server/releases/latest.tar.bz2
$ tar -jxvf latest.tar.bz2
$ sudo mv nextcloud /var/www/html/

Create a data directory:

$ sudo mkdir /var/www/html/nextcloud/data
$ sudo chown -R nginx:nginx /var/www/html/nextcloud

Install SSL

Use Let’s Encrypt to install SSL certificates, beginning with Certbot installation:

$ sudo dnf install certbot

Stop Nginx to allow Certbot to operate properly:

$ sudo systemctl stop nginx

Generate SSL certificates and set Diffie-Hellman Parameters:

$ export LDOMAIN="nextcloud.example.com"
$ export LEMAIL="email@example.com"
$ sudo certbot certonly --standalone -d $LDOMAIN --preferred-challenges http --agree-tos -n -m $LEMAIL --keep-until-expiring 
$ sudo systemctl start nginx
$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Setup a cron job for automatic SSL renewal. Edit the cron file:

$ sudo EDITOR=nano crontab -e

Add the following line to the bottom of the file to automate certificate renewal:

25 2 * * * /usr/bin/certbot renew --quiet --pre-hook "systemctl stop nginx" --post-hook "systemctl start nginx"

Save the file with Ctrl + X and confirm with Y.

Configure SELinux/Permissions

Setting up SELinux with the correct file permissions is crucial for Nextcloud operation. Use these commands to configure SELinux:

Ensure to adjust paths if your installation directory differs:

$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/html/nextcloud/data(/.*)?'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/html/nextcloud/config(/.*)?'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/html/nextcloud/apps(/.*)?'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/html/nextcloud/.user.ini'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/html/nextcloud/3rdparty/aws/aws-sdk-php/src/data/logs(/.*)?'

$ sudo restorecon -Rv '/var/www/html/nextcloud/'

To enable updates via Nextcloud’s web interface, execute:

$ sudo setsebool -P httpd_unified on

Configure Nginx for Nextcloud

Let’s set up and configure Nginx to serve Nextcloud. We’ll assume your desired domain is http://nextcloud.example.com.

Create directories for server configuration:

$ sudo mkdir /etc/nginx/sites-available
$ sudo mkdir /etc/nginx/sites-enabled

Edit the Nginx configuration file /etc/nginx/nginx.conf:

$ sudo nano /etc/nginx/nginx.conf

Add the following below the line include /etc/nginx/conf.d/*.conf:

include /etc/nginx/sites-enabled/*.conf;
server_names_hash_bucket_size 64;

Save with Ctrl + X and confirm with Y.

Create a new configuration for Nextcloud at /etc/nginx/sites-available/nextcloud.conf:

$ sudo nano /etc/nginx/sites-available/nextcloud.conf

Insert the following configuration, replacing the example domain with your actual domain:

upstream php-handler {
    #server 127.0.0.1:9000;
    server unix:/run/php-fpm/www.sock;
}

server {
    listen 80;
    listen [::]:80;
    server_name nextcloud.example.com;
    # enforce https
    return 301 https://$server_name:443$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name nextcloud.example.com;
	
	access_log /var/log/nginx/nextcloud.access.log;
    error_log /var/log/nginx/nextcloud.error.log;

    # 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/letsencrypt/live/nextcloud.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/nextcloud.example.com/privkey.pem;
	ssl_protocols TLSv1.2 TLSv1.3;
	ssl_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
    ssl_session_tickets off;
	ssl_ciphers 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;
    ssl_prefer_server_ciphers off;
	ssl_dhparam /etc/ssl/certs/dhparam.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/html/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 100M;
    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 build 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\/.+|.+\/richdocumentscode\/proxy)\.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_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|mp4|webm)$ {
        try_files $uri /index.php$request_uri;
        # Optional: Don't log access to other assets
        access_log off;
    }
}

Save with Ctrl + X and confirm with Y.

Link this configuration to the sites-enabled directory:

$ sudo ln -s /etc/nginx/sites-available/nextcloud.conf /etc/nginx/sites-enabled/

Test the Nginx configuration:

$ sudo nginx -t

Reload Nginx if the test is successful:

$ sudo systemctl reload nginx

Install Nextcloud

You can configure Nextcloud either via the command line or the graphical interface. This guide will take the command line approach.

Navigate to the Nextcloud directory:

$ cd /var/www/html/nextcloud

Run the installation command:

$ sudo -u nginx php occ  maintenance:install --database "mysql" --database-name "nextcloud"  --database-user "nextuser" --database-pass "yourpassword" --admin-user "admin" --admin-pass "password"

This command is executed as the nginx user because it owns write permissions on the Nextcloud folder.

Edit the trusted domains configuration by opening /var/www/html/nextcloud/config/config.php:

$ sudo nano config/config.php

Add your server IP address and the domain nextcloud.example.com to the trusted_domains array:

'trusted_domains' =>
  array (
    0 => 'localhost',
    1 => '167.172.35.56',
    2 => 'nextcloud.example.com',
  ),

Save and exit with Ctrl + X, confirming with Y when prompted.

Access your Nextcloud installation via your web browser at https://nextcloud.example.com. You should see the login screen:

Nextcloud Login Page

Enter your administrative login details. Explore the introductory banners, set your location preferences, and once done, you should see a screen resembling this:

Nextcloud Homepage

Conclusion

This tutorial has guided you through installing Nextcloud on a Fedora 32 server. If you have any questions or run into issues, please leave a comment below.

Frequently Asked Questions (FAQ)

1. What is the advantage of using Nextcloud over other cloud services?

Nextcloud allows complete control over your data by hosting it on your server, ensuring privacy and security, unlike third-party cloud providers.

2. Why use Let’s Encrypt for SSL certificates?

Let’s Encrypt offers free SSL certificates, helping you secure your website with encrypted connections at no cost.

3. Can I use a different web server instead of Nginx?

Yes, you can use Apache as an alternative web server for Nextcloud. However, configuration steps will differ, so ensure compatibility with Nextcloud’s requirements.

4. What should I do if I encounter issues during installation?

Double-check the steps, ensuring all commands are correctly executed, and consult Nextcloud’s documentation or community forums for further support.

5. Is it necessary to configure SELinux for Nextcloud?

Configuring SELinux is essential for maintaining security on Fedora systems, ensuring Nextcloud operates with proper permissions and access control.\nContact Nextcloud community forums for help if you face SELinux-specific issues.