Apache, MySQL and PHP-FPM on Ubuntu 20.04

Install Apache, MariaDB and PHP with the following command:

$ sudo apt install apache2 php7.4-fpm 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  

Enable a couple of Apache modules

$ sudo a2enmod actions proxy_fcgi

Make sure Apache, PHP-FPM and MariaDB start automatically

$ sudo systemctl enable apache2
$ 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

Since we’re going to have multiple pools, let’s set up a couple of virtual hosts. In /etc/apache2/sites-available create a couple of files named user1.conf and user2.conf. Examples of the two files is below:

/etc/apache2/sites-available/user1.conf

<VirtualHost *:80>
    DocumentRoot "/home/user1/www"
    ServerName user1.example.com

    # Other directives here
     <FilesMatch \.php> # Apache 2.4.10+ can proxy to unix socket
        SetHandler "proxy:unix:/var/run/php/php7.4-fpm-user1.sock|fcgi://localhost/"
    </FilesMatch>
</VirtualHost>

/etc/apache2/sites-available/user2.conf

<VirtualHost *:80>
    DocumentRoot "/home/user2/www"
    ServerName user2.example.com

    # Other directives here
     <FilesMatch \.php>
        SetHandler "proxy:unix:/var/run/php/php7.4-fpm-user2.sock|fcgi://localhost/"
    </FilesMatch>
</VirtualHost>

Now we need to make a change to our /etc/apache2/apache2.conf file. Find the section: <Directory /var/www/> Options Indexes FollowSymLinks AllowOverride None Require all granted

Below it add:

<Directory /home/*/www/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
</Directory>

This will give us the ability to load pages from /home/username/www.

Now we need to set up our individual PHP-FPM pools. In /etc/php/7.4/fpm/pool.d create two files:

/etc/php/7.4/fpm/pool.d/user1.conf - Note: The user name contained in the brackets must match your actual users.

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

listen = /var/run/php/php7.4-fpm-user1.sock
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 - Note: The user name contained in the brackets must match your actual users.

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

listen = /var/run/php/php7.4-fpm-user2.sock
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

Enable our new sites

$ sudo a2ensite user1
$ sudo a2ensite user2

Restart services

$ sudo systemctl restart apache2
$ sudo systemctl restart php7.4-fpm

Allow http and https through the firewall

$ sudo ufw allow http
$ sudo ufw allow https