NGINX, MySQL and PHP-FPM on Ubuntu 20.04

$ sudo apt install nginx php7.4-fpm php7.4-mysql php7.4-cli php7.4-gd php7.4-xml php7.4-zip php7.4-mbstring php7.4-curl

Optionally install MariaDB (a popular MySQL fork)

$ sudo apt install mariadb-server mariadb-client php7.4-mysql

If you installed MariaDB, run the mysql_secure_installation script:

$ sudo mysql_secure_installation

You will be asked the following:

Enter current password for root (enter for none): 
Set root password? [Y/n] y  
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  

Make sure NGINX, PHP-FPM and MariaDB start automatically

$ sudo systemctl enable nginx
$ sudo systemctl enable php7.4-fpm
$ sudo systemctl enable mariadb

Set up your system users and create a directory to hold their websites. We’ll start with two but you can add more later

$ sudo useradd user1
$ sudo mkdir -p /home/user1/www; chown user1:user1 /home/user1/www; chmod +x /home/user1
$ sudo useradd user2
$ sudo mkdir -p /home/user2/www; chown user2:user2 /home/user2/www; chmod +x /home/user2
Create an NGINX virtual host configuration file for your domains. For this example, I will use user1.example.com and user2.example.com

In /etc/nginx/conf.d, create two files.

/etc/nginx/sites-available/user1.example.com.conf

server {
    server_name  user1.example.com;
    root /home/user1/www;

     # Load configuration files for the default server block
     include /etc/nginx/default.d/*.conf;

     location / {
        index   index.html index.htm index.php;
     }

     error_page 404 /404.html;
     location = /404.html {
        root    /usr/share/nginx/html;
    }

    # redirect server error pages to the static page /50x.html
    error_page  500 502 503 504 /50x.html;
    location = /50x.html {
        root    /usr/share/nginx/html;
    }

    location ~ [^/]\.php(/|$) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        if (!-f $document_root$fastcgi_script_name) {
            return 404;
        }

    fastcgi_pass        unix:/var/run/php/user1.socket;
    fastcgi_index       index.php;
    fastcgi_param       SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
    }
}

/etc/nginx/sites-available/user2.example.com.conf

server {
    server_name  user2.example.com;
    root /home/user2/www;

     # Load configuration files for the default server block
     include /etc/nginx/default.d/*.conf;

     location / {
        index   index.html index.htm index.php;
     }

     error_page 404 /404.html;
     location = /404.html {
        root    /usr/share/nginx/html;
    }

    # redirect server error pages to the static page /50x.html
    error_page  500 502 503 504 /50x.html;
    location = /50x.html {
        root    /usr/share/nginx/html;
    }

    location ~ [^/]\.php(/|$) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        if (!-f $document_root$fastcgi_script_name) {
            return 404;
        }

    fastcgi_pass        unix:/var/run/php/user2.socket;
    fastcgi_index       index.php;
    fastcgi_param       SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
    }
}

Create a symlink to /etc/nginx/sites-enabled so both site configurations will be loaded.

$ sudo ln -s /etc/nginx/sites-available/user1.example.com.conf /etc/nginx/sites-enabled/
$ sudo ln -s /etc/nginx/sites-available/user2.example.com.conf /etc/nginx/sites-enabled/

Reload NGINX to load our changes

$ sudo systemctl reload nginx

Now we need to set up our individual PHP-FPM pools.

/etc/php/7.4/fpm/pool.d/user1.conf

[user1]

 user = user1
 group = user1
 listen.owner = www-data
 listen.group = www-data
 listen.mode = 0660

 listen = /var/run/php/user1.socket
 pm = dynamic
 pm.max_children = 5
 pm.start_servers = 2
 pm.min_spare_servers = 1
 pm.max_spare_servers = 3

/etc/php/7.4/fpm/pool.d/user2.conf

[user2]

 user = user2
 group = user2
 listen.owner = www-data
 listen.group = www-data
 listen.mode = 0660

 listen = /var/run/php/user2.socket
 pm = dynamic
 pm.max_children = 5
 pm.start_servers = 2
 pm.min_spare_servers = 1
 pm.max_spare_servers = 3

Reload php-fpm to load our changes

$ sudo systemctl reload php7.4-fpm

Allow http and https through the firewall

$ sudo ufw allow http
$ sudo ufw allow https