Select Page

Install and Configure PHP 7.4

As of this writing, the Raspbian 10 repository allows installing PHP 7.3. We want 7.4 instead so let’s add the source to Ondřej Surý‘s PHP packages:

sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
echo "deb https://packages.sury.org/php/ buster main" | sudo tee /etc/apt/sources.list.d/php.list
sudo apt update

Now we can install the latest available PHP 7.4 and the necessary modules for Nextcloud:

sudo apt install php-fpm php-curl php-cli php-mysql php-gd php-common php-xml php-json php-intl php-pear php-imagick php-dev php-common php-mbstring php-zip php-soap php-bz2 php7.4-bcmath php7.4-gmp php7.4-opcache php7.4-apcu php7.4-redis -y

In the main php.ini file, uncomment the date.timezone line by removing the preceding ; and change the value with your own. Uncomment also the cgi.fix_pathinfo line and change the value to 0.

sudo nano /etc/php/7.4/fpm/php.ini
798c798
< ;cgi.fix_pathinfo = 1
---
> cgi.fix_pathinfo=0
962c962
< ;date.timezone = America/Denver
---
> date.timezone = Europe/London

Save and exit (CTRL+X, press Y to confirm and then Enter).

Do the same in the CLI’s php.ini:

sudo nano /etc/php/7.4/cli/php.ini

Next, let’s add a pool configuration file:

sudo nano /etc/php/7.4/fpm/pool.d/nextcloud.conf
[nextcloud]
user = www-data
group = www-data

listen.owner = www-data
listen.group = www-data
listen = /run/php/nextcloud.sock
listen.allowed_clients = 127.0.0.1

pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35

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

php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/sessions

php_value[max_execution_time] = 3600
php_value[memory_limit] = 7G
php_value[post_max_size] = 7G
php_value[upload_max_filesize] = 7G
php_value[max_input_time] = 3600
php_value[max_input_vars] = 2000
php_value[date.timezone] = Europe/London

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

Restart PHP and set the service to start automatically after a server reboot:

sudo systemctl restart php7.4-fpm && sudo systemctl enable php7.4-fpm

Install and Configure MariaDB Server

In this step, we will install the latest MariaDB version and create a new database for the Nextcloud installation. The latest MariaDB packages are available on the repository by default so let’s install using the command below:

sudo apt install mariadb-server -y

After the installation is complete, enable the service to launch every time the system reboots:

sudo systemctl enable mariadb

Next, we will configure the MariaDB root password using the mysql_secure_installation shell script:

sudo mysql_secure_installation

Press Enter and set a password for the root user. Type Y for the subsequent questions unless you want to do differently:

Enter current password for root (enter for none):
Set root password? [Y/n]
Remove anonymous users? [Y/n]
Disallow root login remotely? [Y/n]
Remove test database and access to it? [Y/n]
Reload privilege tables now? [Y/n]

Create a User and Database on MariaDB for NextCloud

sudo mysql
CREATE DATABASE nextcloud;
GRANT ALL PRIVILEGES ON nextcloud.* TO [email protected]'localhost' IDENTIFIED BY 'CHANGEwithYOURpassword';
FLUSH PRIVILEGES;
EXIT

Let’s Encrypt certificate via Cloudflare DNS

I prefer DNS-01 challenge over HTTP-01 and as I’m also behind Cloudflare, I’m going to use the certbot-dns-cloudflare plugin on top of the certbot instructions for NGINX with snapd to generate an SSL certificate.

sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare

Create a Cloudflare API Token with an Edit zone DNS template and choose to include the desired specific zone. E.g.:
Cloudflare API Token for Certbot

Create a /root/.cloudflare.ini file and add your token in it. E.g.:

# Cloudflare API token used by Certbot
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567

Restrict permissions:

sudo chmod 600 /root/.cloudflare.ini

Issue the SSL certificate with the command below and enter an email address to be informed if the certificate doesn’t renew automatically (i.e. there’s an issue) and answer the questions:

sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /root/.cloudflare.ini -d nextcloud.oviliz.com

Do a --dry-run renewal to verify that certbot remembers now to use the DNS challenge:

sudo certbot renew --dry-run

Install Nextcloud

sudo wget https://download.nextcloud.com/server/releases/latest.zip -P /var/www/
sudo unzip /var/www/latest.zip -d /var/www/
sudo chown -R www-data:www-data /var/www/nextcloud
sudo nano /etc/nginx/sites-available/nextcloud.oviliz.com
upstream php-handler {
    #server 127.0.0.1:9000;
    server unix:/run/php/nextcloud.sock;
}

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

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name nextcloud.oviliz.com;

    # 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.oviliz.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/nextcloud.oviliz.com/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 7G;
    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|.+\/richdocumentscode_arm64\/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;
        # Raise timeout values.
        # This is especially important when the Nextcloud setup runs into timeouts (504 gateway errors)
        fastcgi_read_timeout 600;
        fastcgi_send_timeout 600;
        fastcgi_connect_timeout 600;
    }

    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|mp4|webm)$ {
        try_files $uri /index.php$request_uri;
        # Optional: Don't log access to other assets
        access_log off;
    }
}
sudo ln -s /etc/nginx/sites-available/nextcloud.oviliz.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

Now, access the URL [https://(chosenDomain)/] with the web browser and configure Administrative user account as well as the database connection details as previously created. Filled the admin user and database information, complete the installation and wait until is done.

Install Redis

sudo apt install redis-server
sudo nano /var/www/nextcloud/config/config.php

Configure Nextcloud to use APCu and Redis memcaches:

   'memcache.local' => '\OC\Memcache\APCu',
  'memcache.distributed' => '\OC\Memcache\Redis',
  'memcache.locking' => '\OC\Memcache\Redis',
  'redis' => [
     'host'     => '/var/run/redis/redis-server.sock',
     'port'     => 0,
     'dbindex'  => 0,
     'password' => 'secret',
     'timeout'  => 1.5,
  ],

Update the redis configuration in /etc/redis/redis.conf accordingly: uncomment Unix socket options and ensure the “socket” and “port” settings match your Nextcloud configuration.
Be sure to set the right permissions on redis.sock so that your webserver can read and write to it. For this you typically have to add the webserver user to the redis group:

sudo usermod -a -G redis www-data

Finally, restart Redis, NGINX and PHP-FPM:

sudo systemctl restart redis-server nginx php7.4-fpm
Share This