A LAMP stack (Linux, Apache, MariaDB, PHP) is the classic foundation for WordPress, Laravel and most PHP applications. In this guide you will build it step by step on a fresh VPS Linux Infrawire running Ubuntu 24.04, with a dedicated virtual host and a firewall that only exposes what is needed.
📋 Prerequisites
- A KVM VPS running Ubuntu 24.04 (the IP and the root password are available in your client area)
- SSH access as root, or as a user with
sudorights - A domain
example.comwhose A (and AAAA) records point toVPS_IP
All commands below assume you are root. Prefix them with sudo otherwise.
1. Update the system
Bashapt update && apt upgrade -y
2. Install Apache
Bashapt install -y apache2 systemctl enable --now apache2 apache2 -v
The service starts immediately and is enabled at boot.
3. Install MariaDB
MariaDB is available in the Ubuntu repositories and is a drop-in replacement for MySQL. If you prefer Oracle MySQL, install mysql-server instead, but never install both on the same machine.
Bashapt install -y mariadb-server systemctl enable --now mariadb mysql_secure_installation
In the wizard, keep the unix_socket authentication for root, set a strong password if asked, remove anonymous users, disallow remote root login and remove the test database. Then create a database and a dedicated user for your application:
Bashmariadb
SQL1CREATE DATABASE appdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 2CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'STRONG_PASSWORD'; 3GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'localhost'; 4FLUSH PRIVILEGES; 5EXIT;
4. Install PHP 8.3
Ubuntu 24.04 ships PHP 8.3 in its default repositories, so no extra PPA is required.
Bashapt install -y php libapache2-mod-php php-mysql php-cli php-curl php-gd php-mbstring php-xml php-zip php-intl php -v
The libapache2-mod-php package switches Apache to the prefork MPM automatically and loads the PHP module.
5. Create a virtual host and enable mod_rewrite
Bashmkdir -p /var/www/example.com/public_html chown -R www-data:www-data /var/www/example.com nano /etc/apache2/sites-available/example.com.conf
Apache1<VirtualHost *:80> 2 ServerName example.com 3 ServerAlias www.example.com 4 DocumentRoot /var/www/example.com/public_html 5 6 <Directory /var/www/example.com/public_html> 7 AllowOverride All 8 Require all granted 9 </Directory> 10 11 ErrorLog ${APACHE_LOG_DIR}/example.com-error.log 12 CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined 13</VirtualHost>
AllowOverride All lets .htaccess files work, which pretty URLs in WordPress or Laravel rely on. Now enable the module and the site, and disable the default page:
Basha2enmod rewrite a2ensite example.com.conf a2dissite 000-default.conf apache2ctl configtest systemctl reload apache2
configtest must answer Syntax OK before you reload.
6. Configure the firewall
Allow SSH first, otherwise you will lock yourself out when the firewall is enabled.
Bashufw allow OpenSSH ufw allow 'Apache Full' ufw enable ufw status
The Apache Full profile opens ports 80 and 443. Do not open port 3306: MariaDB only needs to listen locally.
7. Test PHP, then remove the test file
Bashecho '<?php phpinfo();' > /var/www/example.com/public_html/info.php curl -sI http://example.com/info.php | head -n 1
You should get HTTP/1.1 200 OK. Open http://example.com/info.php in a browser to see the PHP configuration page. A phpinfo() page discloses versions, paths and modules, so delete it immediately:
Bashrm /var/www/example.com/public_html/info.php
Check the other components as well:
Bashapache2ctl -M | grep -E 'rewrite|php' php -m | grep -E 'mysqli|pdo_mysql' systemctl is-active apache2 mariadb
🛠️ Troubleshooting
The default Apache page still appears. The default site is still enabled or DNS has not propagated yet. Run a2dissite 000-default.conf, reload Apache, and test with curl -I -H 'Host: example.com' http://VPS_IP/.
403 Forbidden. Check that the directory has Require all granted, that www-data can read the files (ls -ld /var/www/example.com/public_html) and read the log in /var/log/apache2/example.com-error.log.
The browser downloads the PHP file instead of running it. The PHP module is not loaded. Run apache2ctl -M | grep php, then systemctl restart apache2. If nothing appears, reinstall libapache2-mod-php.
Rewrite rules are ignored (404 on pretty URLs). Confirm that a2enmod rewrite was run and that your <Directory> block contains AllowOverride All.
🎉 Your LAMP stack is up: Apache, MariaDB and PHP 8.3 are ready to host your first site.