Install Apache with MariaDB and PHP 7 Running Under PHP-FPM

This tutorial will get you started with a basic LAMP stack. There are countless tweaks and customizations possible from this base configuration. This tutorial will walk you through setting up Apache, MariaDB (MySQL Clone) and PHP-FPM. It is designed to be used in a shared environment or where you need to maintain user isolation. Each user will have their web root located in ~/username/www. This was tested on Ubuntu 16.04.

Install Apache 2

$ sudo apt install apache2

Install MariaDB

$ sudo apt install mariadb-server mariadb-client

Configure and secure MariaDB

$ 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

Install PHP 7 with some extra modules and install mod_fastcgi

$ sudo apt install php7.0-fpm php7.0-mysql php7.0-cli php7.0-gd php7.0-xml php7.0-mcrypt libapache2-mod-fastcgi

Disable mpm_prefork in favor of mpm_event.

$ sudo a2dismod mpm_prefork

Enable a few Apache modules

$ sudo a2enmod actions fastcgi alias mpm_event

Restart apache

$ sudo systemctl restart apache2

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:

user1.conf

<VirtualHost *:80>
  DocumentRoot "/home/user1/www"
  ServerName user1.example.com
  # Other directives here
    <IfModule mod_fastcgi.c>
      AddHandler php7-fcgi .php
      Action php7-fcgi /php7-fcgi virtual
      Alias /php7-fcgi /usr/lib/cgi-bin/php7-fcgi
      FastCgiExternalServer /usr/lib/cgi-bin/php7-fcgi -socket /var/run/php/php7.0-fpm-user1.sock -pass-header Authorization
    </IfModule>
</VirtualHost>

NOTE: You may need to change the first argument “/usr/lib/cgi-bin/php7-fcgi” to something different if you get errors.

user2.conf

<VirtualHost *:80>
    DocumentRoot "/home/user2/www"
    ServerName user2.example.com
    # Other directives here
      <IfModule mod_fastcgi.c>
        AddHandler php7-fcgi .php
        Action php7-fcgi /php7-fcgi-user2 virtual
        Alias /php7-fcgi-user2 /usr/lib/cgi-bin/php7-fcgi-user2
        FastCgiExternalServer /usr/lib/cgi-bin/php7-fcgi-user2 -socket /var/run/php/php7.0-fpm-user2.sock -pass-header Authorization
      </IfModule>
</VirtualHost>

Now we need to make a change to our apache2.conf file. Find the section:

<Directory /var/www/>
  Options Indexes FollowSymLinks
  AllowOverride None
  Require all granted
</Directory>

Below it add:

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

<Directory /usr/lib/cgi-bin/>
  Options Indexes FollowSymLinks
  AllowOverride All
  Require all granted
</Directory>

This will give us the ability to load pages from /home/username/www as well as the /usr/lib/cgi-bin/ directory required by FPM.

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

user1.conf

[user1]
user = user1
group = user1
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
listen = /var/run/php/php7.0-fpm-user1.sock
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

user2.conf

[user2]
user = user2
group = user2
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
listen = /var/run/php/php7.0-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.0-fpm