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
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!