Tools: Installing the LAMP Stack on Ubuntu 26.04

Tools: Installing the LAMP Stack on Ubuntu 26.04

Install Apache

Install MySQL

Install PHP and PHP-FPM

Configure Firewall Rules

Configure a Virtual Host

Secure with Let's Encrypt SSL

Test the LAMP Stack

Next Steps The LAMP stack — Linux, Apache, MySQL, and PHP — powers a large portion of the web, including WordPress, Laravel, and Drupal. Ubuntu 26.04 ships with PHP 8.5, giving you a modern base to build on. This guide sets up a production-ready stack using Apache with PHP-FPM, secures it with a Let's Encrypt certificate, and verifies the full setup with a PHP page that reads from MySQL. By the end, you'll have a fully operational LAMP server ready to host web applications. Apache is available directly from Ubuntu 26.04's default APT repository. 1. Update the APT package index: 3. Enable and start the service: MySQL is installed from Ubuntu's default repository and secured with the built-in security script before any application connects to it. 1. Install the MySQL server package: 2. Enable and start the service: 3. Run the security script: 4. Set the root password in the MySQL shell: PHP-FPM handles PHP execution through a FastCGI process pool, offering better performance and process isolation compared to the traditional mod_php approach. 1. Install PHP and required extensions: 2. Enable and start PHP-FPM: Open ports 80 and 443 to allow HTTP and HTTPS traffic through the firewall. Virtual hosts allow Apache to serve domain-specific content and are required before issuing an SSL certificate. Replace app.example.com with your actual domain throughout this section. 1. Create the web root directory: 2. Create a test HTML page: 3. Disable the default Apache site: 4. Create the virtual host configuration: 5. Enable the site and reload Apache: Certbot automates certificate issuance and renewal through Let's Encrypt, with an Apache plugin that handles virtual host configuration directly. 1. Install Certbot with the Apache plugin: 2. Generate and install the certificate: Certbot updates the virtual host to redirect HTTP to HTTPS automatically. 3. Test the auto-renewal timer: A dry run without errors confirms automatic renewal is configured correctly. A PHP script that connects to MySQL and retrieves data confirms all three layers of the stack are communicating correctly. 1. Create the test database: 2. Create the PHP test page: 3. Visit the test page: Open https://app.example.com/test.php in a browser. The text LAMP stack is working! confirms Apache, PHP, and MySQL are communicating correctly. 4. Remove the test file: The LAMP stack is now running and serving requests over HTTPS. From here you can: For the full guide with additional tips, visit the original article on Vultr Docs. Templates let you quickly answer FAQs or store snippets for re-use. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse

Command

Copy

$ -weight: 600;">sudo -weight: 500;">apt -weight: 500;">update $ -weight: 600;">sudo -weight: 500;">apt -weight: 500;">update $ -weight: 600;">sudo -weight: 500;">apt -weight: 500;">update $ -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install apache2 -y $ -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install apache2 -y $ -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install apache2 -y $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable apache2 $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start apache2 $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable apache2 $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start apache2 $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable apache2 $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start apache2 $ -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install mysql-server -y $ -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install mysql-server -y $ -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install mysql-server -y $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable mysql $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start mysql $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable mysql $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start mysql $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable mysql $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start mysql $ -weight: 600;">sudo mysql_secure_installation $ -weight: 600;">sudo mysql_secure_installation $ -weight: 600;">sudo mysql_secure_installation $ -weight: 600;">sudo mysql $ -weight: 600;">sudo mysql $ -weight: 600;">sudo mysql mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_strong_password'; mysql> FLUSH PRIVILEGES; mysql> EXIT; mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_strong_password'; mysql> FLUSH PRIVILEGES; mysql> EXIT; mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_strong_password'; mysql> FLUSH PRIVILEGES; mysql> EXIT; $ -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install php php-fpm php-mysql php-cli libapache2-mod-php -y $ -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install php php-fpm php-mysql php-cli libapache2-mod-php -y $ -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install php php-fpm php-mysql php-cli libapache2-mod-php -y $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable php8.5-fpm $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start php8.5-fpm $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable php8.5-fpm $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start php8.5-fpm $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable php8.5-fpm $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start php8.5-fpm $ -weight: 600;">sudo ufw allow 80/tcp $ -weight: 600;">sudo ufw allow 443/tcp $ -weight: 600;">sudo ufw allow 80/tcp $ -weight: 600;">sudo ufw allow 443/tcp $ -weight: 600;">sudo ufw allow 80/tcp $ -weight: 600;">sudo ufw allow 443/tcp $ -weight: 600;">sudo mkdir -p /var/www/app.example.com $ -weight: 600;">sudo chown -R www-data:www-data /var/www/app.example.com $ -weight: 600;">sudo mkdir -p /var/www/app.example.com $ -weight: 600;">sudo chown -R www-data:www-data /var/www/app.example.com $ -weight: 600;">sudo mkdir -p /var/www/app.example.com $ -weight: 600;">sudo chown -R www-data:www-data /var/www/app.example.com $ echo "<h1>Hello from LAMP on Ubuntu 26.04</h1>" | -weight: 600;">sudo tee /var/www/app.example.com/index.html $ echo "<h1>Hello from LAMP on Ubuntu 26.04</h1>" | -weight: 600;">sudo tee /var/www/app.example.com/index.html $ echo "<h1>Hello from LAMP on Ubuntu 26.04</h1>" | -weight: 600;">sudo tee /var/www/app.example.com/index.html $ -weight: 600;">sudo a2dissite 000-default.conf $ -weight: 600;">sudo a2dissite 000-default.conf $ -weight: 600;">sudo a2dissite 000-default.conf $ -weight: 600;">sudo nano /etc/apache2/sites-available/app.example.com.conf $ -weight: 600;">sudo nano /etc/apache2/sites-available/app.example.com.conf $ -weight: 600;">sudo nano /etc/apache2/sites-available/app.example.com.conf <VirtualHost *:80> ServerName app.example.com DocumentRoot /var/www/app.example.com <Directory /var/www/app.example.com> AllowOverride All Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/app.example.com-error.log CustomLog ${APACHE_LOG_DIR}/app.example.com-access.log combined </VirtualHost> <VirtualHost *:80> ServerName app.example.com DocumentRoot /var/www/app.example.com <Directory /var/www/app.example.com> AllowOverride All Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/app.example.com-error.log CustomLog ${APACHE_LOG_DIR}/app.example.com-access.log combined </VirtualHost> <VirtualHost *:80> ServerName app.example.com DocumentRoot /var/www/app.example.com <Directory /var/www/app.example.com> AllowOverride All Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/app.example.com-error.log CustomLog ${APACHE_LOG_DIR}/app.example.com-access.log combined </VirtualHost> $ -weight: 600;">sudo a2ensite app.example.com.conf $ -weight: 600;">sudo apachectl configtest $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart apache2 $ -weight: 600;">sudo a2ensite app.example.com.conf $ -weight: 600;">sudo apachectl configtest $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart apache2 $ -weight: 600;">sudo a2ensite app.example.com.conf $ -weight: 600;">sudo apachectl configtest $ -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart apache2 $ -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install certbot python3-certbot-apache -y $ -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install certbot python3-certbot-apache -y $ -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install certbot python3-certbot-apache -y $ -weight: 600;">sudo certbot --apache -d app.example.com --agree-tos $ -weight: 600;">sudo certbot --apache -d app.example.com --agree-tos $ -weight: 600;">sudo certbot --apache -d app.example.com --agree-tos $ -weight: 600;">sudo certbot renew --dry-run $ -weight: 600;">sudo certbot renew --dry-run $ -weight: 600;">sudo certbot renew --dry-run $ mysql -u root -p $ mysql -u root -p $ mysql -u root -p mysql> CREATE DATABASE lamp_test; mysql> CREATE USER 'lamp_user'@'localhost' IDENTIFIED BY 'secure_password'; mysql> GRANT ALL PRIVILEGES ON lamp_test.* TO 'lamp_user'@'localhost'; mysql> USE lamp_test; mysql> CREATE TABLE greetings (id INT AUTO_INCREMENT PRIMARY KEY, message VARCHAR(255)); mysql> INSERT INTO greetings (message) VALUES ('LAMP stack is working!'); mysql> FLUSH PRIVILEGES; mysql> EXIT; mysql> CREATE DATABASE lamp_test; mysql> CREATE USER 'lamp_user'@'localhost' IDENTIFIED BY 'secure_password'; mysql> GRANT ALL PRIVILEGES ON lamp_test.* TO 'lamp_user'@'localhost'; mysql> USE lamp_test; mysql> CREATE TABLE greetings (id INT AUTO_INCREMENT PRIMARY KEY, message VARCHAR(255)); mysql> INSERT INTO greetings (message) VALUES ('LAMP stack is working!'); mysql> FLUSH PRIVILEGES; mysql> EXIT; mysql> CREATE DATABASE lamp_test; mysql> CREATE USER 'lamp_user'@'localhost' IDENTIFIED BY 'secure_password'; mysql> GRANT ALL PRIVILEGES ON lamp_test.* TO 'lamp_user'@'localhost'; mysql> USE lamp_test; mysql> CREATE TABLE greetings (id INT AUTO_INCREMENT PRIMARY KEY, message VARCHAR(255)); mysql> INSERT INTO greetings (message) VALUES ('LAMP stack is working!'); mysql> FLUSH PRIVILEGES; mysql> EXIT; $ -weight: 600;">sudo nano /var/www/app.example.com/test.php $ -weight: 600;">sudo nano /var/www/app.example.com/test.php $ -weight: 600;">sudo nano /var/www/app.example.com/test.php <?php $conn = new mysqli('localhost', 'lamp_user', 'secure_password', 'lamp_test'); if ($conn->connect_error) { die('Connection failed: ' . $conn->connect_error); } $result = $conn->query('SELECT message FROM greetings'); while ($row = $result->fetch_assoc()) { echo $row['message']; } $conn->close(); ?> <?php $conn = new mysqli('localhost', 'lamp_user', 'secure_password', 'lamp_test'); if ($conn->connect_error) { die('Connection failed: ' . $conn->connect_error); } $result = $conn->query('SELECT message FROM greetings'); while ($row = $result->fetch_assoc()) { echo $row['message']; } $conn->close(); ?> <?php $conn = new mysqli('localhost', 'lamp_user', 'secure_password', 'lamp_test'); if ($conn->connect_error) { die('Connection failed: ' . $conn->connect_error); } $result = $conn->query('SELECT message FROM greetings'); while ($row = $result->fetch_assoc()) { echo $row['message']; } $conn->close(); ?> $ -weight: 600;">sudo rm /var/www/app.example.com/test.php $ -weight: 600;">sudo rm /var/www/app.example.com/test.php $ -weight: 600;">sudo rm /var/www/app.example.com/test.php - Deploy WordPress or Laravel on this stack - Add phpMyAdmin for a browser-based database management interface - Enable mod_rewrite for clean URL support with -weight: 600;">sudo a2enmod rewrite