In this article we will setup a web server with Apache/MariaDB/PHP on Ubuntu 20.04. Most of the packages we will install will be from the default repositories.
1st thing we will do is, update our system and enable firewall with few specific ports we need.
Note: Words highlighted in bold within code snippets are pointers or need to be changed.
apt update
apt upgrade
ufw allow 22
ufw allow 80
ufw allow 443
ufw enable
Let’s install all the base packages of Apache, MariaDB and PHP. Modify to remove or add any package of your choice.
apt install vim apache2 mariadb-server libapache2-mod-php php php-gmp php-bcmath php-gd php-json php-mysql php-curl php-mbstring php-intl php-imagick php-xml php-zip bzip2 zip unzip php-imagick imagemagick php-fpm php-fileinfo php-apcu
Enable Apache modules:
a2enmod ssl rewrite headers proxy proxy_http deflate cache proxy_wstunnel http2 proxy_fcgi env expires
Enable and start Apache:
systemctl enable apache2
systemctl start apache2
At this point if you want to enable and use http2 for you applications, click on the button below to setup php-fpm. The article is generic but at that time was written for Nextcloud setup.
There are some basic changes you can make to php.ini. If you use http2, php.ini location is /etc/php/7.4/fpm/php.ini
, otherwise it is /etc/php/7.4/apache2/php.ini
.
vim /etc/php/7.4/apache2/php.ini
output_buffering = off (line 215)
max_execution_time = 120 (line 388)
memory_limit = 512M (line 409)
post_max_size = 100M (line 694)
upload_max_filesize = 100M (line 846)
date.timezone = Europe/Berlin (line 962)
These are the changes I would make initially. You can go through php.ini and make changes according to your needs.
Database server setup
We are done with the basic setup of PHP. Now let’s setup our database server. The 1st thing we would do is secure our database server with the likes of setting up root password, removing test database and user, remove remote access etc.
/usr/bin/mysql_secure_installation
Login to database server with:
mysql -u root -p
Create a database and assign a user to it:
create database DATABASE CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
grant all on DATABASE.* to 'DBUSER'@'localhost' identified by 'PASSWORD';
flush privileges;
If you want to use a database management tool, I would recommend Adminer. It’s simple, light and only one file.
cd /var/www/html
wget https://github.com/vrana/adminer/releases/download/v4.8.1/adminer-4.8.1-en.php
Creating a virtual host
I personally create virtual hosts with Apache, that way you have more control over the sites the server serve in the long run. Location for Apache virtual hosts is /etc/apache2/sites-available
.
Enable virtual host
a2ensite DOMAIN.com
Disable virtual host
a2dissite DOMAIN.com
Don’t forget to restart Apache afterwards.
A simple block for port 80 would look like this.
<VirtualHost *:80>
ServerName DOMAIN.com
ServerAlias www.DOMAIN.com
DocumentRoot /var/www/html/DOMAIN.com
<Directory "/var/www/html/DOMAIN.com">
AllowOverride All
Options -Indexes +FollowSymLinks
</Directory>
ErrorLog /var/log/apache2/DOMAIN-error.log
CustomLog /var/log/apache2/DOMAIN-requests.log combined
</VirtualHost>
A block with 443, and redirection from port 80(http).
Note: do not use the 443 block if you haven’t have any SSL certificate yet.
<VirtualHost *:80>
ServerName DOMAIN.com
ServerAlias www.DOMAIN.com
DocumentRoot /var/www/html/DOMAIN.com
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
<Directory "/var/www/html/DOMAIN.com">
AllowOverride All
Options -Indexes +FollowSymLinks
</Directory>
ErrorLog /var/log/apache2/DOMAIN-error.log
CustomLog /var/log/apache2/DOMAIN-requests.log combined
</VirtualHost>
<VirtualHost *:443>
ServerName DOMAIN.com
ServerAlias www.DOMAIN.com
DocumentRoot /var/www/html/DOMAIN.com
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
<Directory "/var/www/html/DOMAIN.com">
AllowOverride All
Options -Indexes +FollowSymLinks
</Directory>
ErrorLog /var/log/apache2/DOMAIN-error.log
CustomLog /var/log/apache2/DOMAIN-requests.log combined
SSLEngine on
SSLCertificateKeyFile /etc/letsencrypt/live/DOMAIN.com/privkey.pem
SSLCertificateFile /etc/letsencrypt/live/DOMAIN.com/fullchain.pem
</VirtualHost>
You can always check your SSL setup and ciphers with sites like ssllabs.com.
Certbot installation and getting a certificate
Click the following button to install certbot and get a certificate. Use the web root method to renew the certificates without a worry of expiration.