Setup LAMP stack (Apache, MariaDB, PHP) on Ubuntu 22.04

In this article we will setup/install LAMP stack (Apache, MariaDB, PHP) on Ubuntu 22.04 including SSL via Certbot and basic firewall with UFW. If you would like to know more about Ubuntu 22.04, check this article.

To start with we will update the system first.

apt update && apt upgrade

Next we will enable only specific ports and disable everything else via UFW firewall.

ufw default allow outgoing
ufw default deny incoming
ufw allow 22
ufw allow 80
ufw allow 443
ufw enable
ufw status

LAMP stack installation

Ubuntu 22.04 comes with pretty much all the latest stable packages for Apache, MariaDB and PHP. So we don’t need to add any extra PPA.

This will install all the required packages and modules we may need in the future.

apt install apache2 mariadb-server libapache2-mod-php8.1 php8.1 php8.1-gmp php8.1-bcmath php8.1-gd php-json php8.1-mysql php8.1-curl php8.1-mbstring php8.1-intl php8.1-imagick php8.1-xml php8.1-zip php8.1-fpm php8.1-redis php8.1-apcu php8.1-opcache php8.1-memcache php8.1-memcached php8.1-ldap bzip2 zip unzip imagemagick vim ffmpeg redis-server

Next is to enable Apache modules.

a2enmod ssl rewrite headers proxy proxy_http deflate cache proxy_wstunnel http2 proxy_fcgi env expires

We will use PHP FPM. This will enable us to use http2 when needed.

a2enconf php8.1-fpm
a2dismod php8.1
a2dismod mpm_prefork
a2enmod mpm_event
systemctl restart apache2

Enable them at boot time.

systemctl enable apache2
systemctl enable mariadb
systemctl enable php8.1-fpm

PHP configuration

As we will be using PHP FPM, we will modify php.ini at fpm dir.

vim /etc/php/8.1/fpm/php.ini

* Line numbers are for guidance only

** For timezone check out PHP timezone manual.

output_buffering = off (line 226)
max_execution_time = 180 (line 409)
memory_limit = 512M (line 430)
post_max_size = 200M (line 698)
upload_max_filesize = 200M (line 850)
date.timezone = Europe/London (line 968)

opcache.enable=1 (line 1767)
opcache.enable_cli=1 (line 1770)
opcache.memory_consumption=128 (line 1773)
opcache.interned_strings_buffer=8 (line 1776)
opcache.max_accelerated_files=10000 (line 1780)
opcache.revalidate_freq=1 (line 1798)
opcache.save_comments=1 (line 1805)

Save and restart PHP FPM.

systemctl restart php8.1-fpm

Database setup

Run the following script to secure the database server.

/usr/bin/mysql_secure_installation
mariadb-intial-configuration-ubuntu-22-04-server

You can login to the database server and create databases, assign users to them. Example commands are listed below.

mysql -u root -p

create database MY_DATABASE CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
grant all on MY_DATABASE.* to 'db_user'@'localhost' identified by 'PASSWORD';

flush privileges;
exit

Apache vhost

Create a vhost file in /etc/apache2/sites-available/

cd /etc/apache2/sites-available
vim my-domain.conf

Paste the following in it.

<VirtualHost *:80>
	ServerName DOMAIN.COM
	ServerAlias DOMAIN.COM
	DocumentRoot /var/www/html

	<Directory "/var/www/html">
		AllowOverride All
		Options -Indexes +FollowSymLinks
	</Directory>

	ErrorLog /var/log/apache2/DOMAIN.COM-error.log
</VirtualHost>

Enable the virtual host and restart Apache.

a2dissite 000-default.conf
a2ensite my-domain.conf

apachectl -t
systemctl restart apache2

This will get you going with a simple web server with web root as /var/www/html.

SSL certificate

You can either use your own certificates provided by your vendor or just use Certbot to get one for free.

* Make sure your domain is pointed to the server IP.

Install Certbot and get a certificate for web root.

snap install certbot --classic
certbot certonly --webroot -w /var/www/html -d DOAMIN.COM

Check the link below for renewals and other details.

Apache vhost 443 block

Once you have the certificates retrieved, your will need to add a 443 block section to my-domain.conf file.

<VirtualHost *:443>
	ServerName DOMAIN.COM
	DocumentRoot /var/www/html

	SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4
	SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
	SSLHonorCipherOrder On
	Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
	Header always set X-Frame-Options DENY
	Header always set X-Content-Type-Options nosniff

    Protocols h2 http/1.1

	<Directory "/var/www/html">
		AllowOverride All
		Options -Indexes +FollowSymLinks
	</Directory>

    ErrorLog /var/log/apache2/DOMAIN.COM-error.log

	SSLEngine on
	SSLCertificateKeyFile /etc/letsencrypt/live/DOMAIN.COM/privkey.pem
	SSLCertificateFile /etc/letsencrypt/live/DOMAIN.COM/fullchain.pem
</VirtualHost>

This will also enable http2 on your server.

To redirect from http to https automatically add the following lines to port 80 block section after DocumentRoot /var/www/html.

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

Finally check the configuration and restart Apache.

apachectl -t
systemctl restart apache2

Along the lines we also installed Redis server available at localhost:6379 and opcache/memcache/apcu.

Hope this was helpful in setting up your server. Happy coding!