Moodle, NGINX, php-fpm, Ubuntu 16.04

First steps, ensure everything on the server is up to date:

sudo apt update && sudo apt upgrade

Then make sure that your hostname is set so you'll be able to access your server over the web, update external DNS records so that LetEncrypt can be used with a free certificate. e.g. ensure that you log into your DNS/domain admin service and make sure your server: moodle.example.com is pointing to your actual server. Without this LetsEncrypt won't be able to run later on.

Install nginx, PHP and LetsEncrypt Client

Install Nginx

sudo apt install nginx

Install php with the extra modules required for Moodle

sudo apt-get install php-fpm php-curl php-gd php-xmlrpc php-intl php-xml php-zip php-soap php-mbstring

Install LetEncrypt Client to secure traffic and login information

sudo apt install letsencrypt

Configure PHP-FPM

Edit PHP-FPM config as per Moodle instructions

sudo nano /etc/php/7.0/fpm/pool.d/www.conf

Uncomment / add the line

security.limit_extensions = .php

Configure nginx

Copy /etc/nginx/site-available/default to a new folder

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/moodle

Edit this config file with sudo nano /etc/nginx/sites-available/moodle - remove all mentions of default_site in the top section, enter /var/www/moodle as the server location and enter your server name.

Remove the comments on the PHP section so it reads as below:

location ~ [^/]\.php(/|$) {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

Enable the site, test the config file, and restart nginx

sudo ln -s /etc/nginx/sites-available/moodle /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

Configure LetsEncrypt

Now the site is running a Certificate can be requested from LetEncrypt. Run sudo letsencrypt certonly --webroot -w /var/www/moodle -d moodle.example.com

Note the keychain location - something like: /etc/letsencrypt/live/moodle.example.com/fullchain.pem

Edit sudo nano /etc/nginx/snippets/ssl-moodle.example.com.conf

Add the following lines

ssl_certificate /etc/letsencrypt/live/moodle.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/moodle.example.com/privkey.pem;

Now edit sudo nano /etc/nginx/snippets/ssl-params.conf and paste in the following:

# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable preloading HSTS for now.  You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

ssl_dhparam /etc/ssl/certs/dhparam.pem;

Adjust the /etc/nginx/site-available/moodle file as follows;

server {
        listen 80;
        listen [::]:80;
        server_name YOUR_SERVER_NAME;
        return 301 https://$server_name$request_uri;
}
server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        include snippets/ssl-moodle.example.com.conf;
        include snippets/ssl-params.conf;

        root /var/www/moodle;
        index index.html index.htm index.nginx-debian.html index.php;
        
        location / {
                First attempt to serve request as file, then
                as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }

        location ~ [^/]\.php(/|$) {
                include snippets/fastcgi-php.conf;
                fastcgi_split_path_info  ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        }

Get Moodle

Navigate to /var/www with cd /var/www

[I had to move .well-known out of the moodle folder first in order to get git to work - this was then moved back afterwards]

sudo git clone -b MOODLE_32_STABLE git://git.moodle.org/moodle.git

Install Postgres

sudo apt-get install postgresql postgresql-contrib php-pgsql

Use psql to create a new user for Postgres

sudo su - postgres
psql

Create the Moodle database user

CREATE USER moodle WITH PASSWORD 'password';
CREATE DATABASE moodle WITH OWNER moodle;
GRANT ALL PRIVILEGES ON DATABASE moodle to moodle;
\q

Get moodle using git

sudo git clone -b MOODLE_32_STABLE git://git.moodle.org/moodle.git

Create moodledata and cache folder and set permissions for Nginx (www-data)

sudo mkdir /var/moodledata
sudo mkdir /var/cache/moodle
sudo chown www-data:www-data /var/moodledata    
sudo chown www-data:www-data /var/cache/moodle

Set permissions on Moodle directory

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

Navigate to your server address and Moodle should be running... follow through the install instructions and that should be it!