LAMP (Linux, Apache, MariaDB/MySQL, PHP) is the classic stack behind WordPress and most PHP applications. Installing it yourself on a VPS gives full control with minimal overhead, at the cost of handling security and updates yourself.
Before you start
- A fresh AlmaLinux 9 or Ubuntu 24.04 VPS with at least 1 GB RAM.
- Root or sudo access over SSH.
- A domain with an A record pointing to the server IP.
Prepare the server
Update the system. AlmaLinux:
dnf -y updateUbuntu:
apt update && apt -y full-upgradeInstall Apache
AlmaLinux:
dnf -y install httpd && systemctl enable --now httpdUbuntu:
apt -y install apache2 && systemctl enable --now apache2Open the firewall. AlmaLinux:
firewall-cmd --permanent --add-service=http --add-service=https && firewall-cmd --reloadUbuntu:
ufw allow OpenSSH && ufw allow 'Apache Full' && ufw enableInstall MariaDB
AlmaLinux: dnf -y install mariadb-server; Ubuntu: apt -y install mariadb-server. Then:
systemctl enable --now mariadb
mariadb-secure-installationSet a root password (or keep socket authentication), remove anonymous users and the test database, and disallow remote root login. More: secure MariaDB.
Install PHP with PHP-FPM
AlmaLinux 9 (use the module stream for a newer PHP, for example 8.2):
dnf -y module enable php:8.2
dnf -y install php php-fpm php-mysqlnd php-gd php-xml php-mbstring php-intl php-zip php-curl php-opcache
systemctl enable --now php-fpmUbuntu 24.04 (PHP 8.3):
apt -y install php-fpm php-mysql php-gd php-xml php-mbstring php-intl php-zip php-curl
a2enmod proxy_fcgi setenvif && a2enconf php8.3-fpm && systemctl reload apache2Need several versions? See PHP from Remi or PHP from the ondrej PPA.
Create a virtual host
Create the site folder and give your user ownership:
mkdir -p /var/www/example.com/publicCreate /etc/httpd/conf.d/example.com.conf (AlmaLinux) or /etc/apache2/sites-available/example.com.conf (Ubuntu):
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public
<Directory /var/www/example.com/public>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>On Ubuntu enable it with a2ensite example.com && a2enmod rewrite. Test and reload: apachectl configtest && systemctl reload httpd (or apache2).
Add free SSL
Install certbot and issue a certificate; see Let's Encrypt with certbot on Apache.
Hardening
- Hide versions:
ServerTokens ProdandServerSignature Off. - Set
expose_php = Offand sensiblememory_limitandupload_max_filesizeinphp.ini. - Enable automatic security updates and install Fail2Ban.
- On AlmaLinux keep SELinux enforcing and allow web writes only where needed with
chcon -t httpd_sys_rw_content_t.
Verify
echo '<?php phpinfo();' > /var/www/example.com/public/info.phpOpen http://example.com/info.php, confirm the Server API is FPM/FastCGI, then delete the file.
Troubleshooting
- 403 Forbidden: wrong permissions or SELinux context on the document root.
- PHP downloads instead of running: the FPM handler is not enabled; check the
a2enconfstep or/etc/httpd/conf.d/php.conf. - Can't connect to database: create a dedicated DB user; see create a MySQL user.
