Overview
LAMP stands for Linux, Apache, MySQL, and PHP. It’s the foundation most PHP-based applications — WordPress, Laravel, Joomla, Magento — expect to run on. LAMP installation on an Ubuntu server is one of the most common first tasks after spinning up a new VPS, and it’s also one of the most common sources of silent failures when steps get skipped or done out of order.
This guide covers a clean LAMP install on Ubuntu 22.04 LTS (Jammy) and Ubuntu 24.04 LTS (Noble). The commands are the same for both unless noted. If you’re on Ubuntu 20.04, the process is nearly identical, but that release hits end-of-life in April 2025, so I’d recommend upgrading before you build on it.
If you don’t have a server yet, our VPS SSD Hosting plans start at $5.83/mo and come with Ubuntu pre-installed — you can be at the command line in under five minutes.
Prerequisites
- A server or VPS running Ubuntu 22.04 or 24.04 (fresh install preferred)
- Root or sudo access via SSH
- A non-root user with sudo privileges (running everything as root is fine for testing, but not for production)
- A domain name pointed at your server’s IP if you want to test virtual hosts — DNS propagation can take up to 48 hours, though it’s usually under an hour
- Basic comfort with a terminal and a text editor like
nanoorvim
Step-by-Step Instructions
Step 1: Update your package index
Always do this before installing anything. Ubuntu’s package cache can be days or weeks old on a fresh server, and installing from a stale cache causes version mismatches that are annoying to debug later.
sudo apt update && sudo apt upgrade -y
The -y flag auto-confirms prompts. If this is a production server and you want to review changes before applying them, drop the -y and read through what’s being upgraded.
Step 2: Install Apache
sudo apt install apache2 -y
Once installed, Apache starts automatically. Verify it’s running:
sudo systemctl status apache2
You should see active (running) in green. If your server has a firewall (UFW) enabled, you’ll need to allow HTTP and HTTPS traffic, otherwise nothing will reach Apache from outside:
sudo ufw allow in "Apache Full"
sudo ufw status
Open a browser and navigate to your server’s IP address. You should see the Apache2 Ubuntu Default Page. If you see a connection timeout instead, the firewall rule above is almost always the reason.
Step 3: Install MySQL
sudo apt install mysql-server -y
Ubuntu 22.04 installs MySQL 8.0 by default. Ubuntu 24.04 also ships MySQL 8.0 from the default repos. After installation, run the security script — this is not optional if you care about security at all:
sudo mysql_secure_installation
You’ll be asked several questions. Here’s what I’d recommend:
- VALIDATE PASSWORD component — Enable it (
Y). Choose policy level 1 (MEDIUM) for most use cases. - Remove anonymous users — Yes.
- Disallow root login remotely — Yes, unless you have a specific reason to allow remote root login (you probably don’t).
- Remove test database — Yes.
- Reload privilege tables — Yes.
📝 Note: On MySQL 8.0, the root user uses auth_socket authentication by default, which means you log in with sudo mysql — not a password. This trips up a lot of people who expect to set a root password during setup and then can’t figure out why it won’t accept it.
Step 4: Create a dedicated MySQL database and user
Don’t use the root account for your application. Create a separate user with only the permissions it needs. Log into MySQL first:
sudo mysql
Then run the following SQL, replacing the placeholders with your actual values:
CREATE DATABASE myappdb;
CREATE USER 'myappuser'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON myappdb.* TO 'myappuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
⚠ Warning: GRANT ALL PRIVILEGES gives that user full control over the specified database only — not the whole server. Never grant GRANT ALL PRIVILEGES ON *.* to an application user.
Step 5: Install PHP
Ubuntu 22.04 ships PHP 8.1. Ubuntu 24.04 ships PHP 8.3. For most modern PHP apps either is fine, but always check your application’s documented requirements before installing.
sudo apt install php libapache2-mod-php php-mysql -y
The three packages here are: the PHP interpreter itself, the Apache PHP module that lets Apache process .php files, and the PHP-MySQL extension your app needs to talk to the database. Skipping php-mysql is a very common mistake — everything looks installed, but your app throws database connection errors.
You’ll likely also need some common PHP extensions depending on your application:
sudo apt install php-curl php-xml php-mbstring php-zip php-gd php-intl -y
Verify the PHP version and confirm Apache picked it up:
php -v
php -m | grep -E "mysqli|pdo_mysql"
Step 6: Restart Apache and validate the setup
Restart Apache to load the PHP module:
sudo systemctl restart apache2
Now create a PHP info file to confirm Apache is serving PHP correctly:
sudo nano /var/www/html/info.php
Add this single line:
<?php phpinfo(); ?>
Save and close (Ctrl+X, then Y, then Enter). Navigate to http://your-server-ip/info.php in a browser. You should see the full PHP info page showing your PHP version, loaded modules, and configuration.
⚠ Warning: Delete this file when you’re done testing. Leaving info.php publicly accessible exposes your PHP configuration, installed modules, and server paths to anyone who knows the URL.
sudo rm /var/www/html/info.php
Step 7: Configure Apache virtual hosts (optional but recommended)
If you’re hosting a real site, you’ll want a virtual host config instead of dumping files into /var/www/html. Create a config for your domain:
sudo nano /etc/apache2/sites-available/yourdomain.com.conf
Paste in this template, adjusting the domain and document root:
<VirtualHost *:80>
ServerName yourdomain.com
ServerAlias www.yourdomain.com
DocumentRoot /var/www/yourdomain.com/public_html
ErrorLog ${APACHE_LOG_DIR}/yourdomain.com-error.log
CustomLog ${APACHE_LOG_DIR}/yourdomain.com-access.log combined
</VirtualHost>
Create the document root directory, enable the site, and reload Apache:
sudo mkdir -p /var/www/yourdomain.com/public_html
sudo a2ensite yourdomain.com.conf
sudo systemctl reload apache2
Common Issues & Troubleshooting
Apache shows the default Ubuntu page instead of my site
The default site (000-default.conf) takes priority if it’s still enabled. Disable it:
sudo a2dissite 000-default.conf
sudo systemctl reload apache2
If that doesn’t fix it, double-check your ServerName directive matches the domain you’re requesting, and that DNS is actually pointing to your server’s IP.
PHP files download instead of executing in the browser
Apache is serving .php files as plain text instead of passing them to PHP. This means libapache2-mod-php either isn’t installed or the module isn’t loaded. Check:
apache2ctl -M | grep php
If you see nothing, the module isn’t active. Reinstall and restart:
sudo apt install --reinstall libapache2-mod-php
sudo systemctl restart apache2
ERROR 1698 (28000): Access denied for user ‘root’@’localhost’
This is annoyingly common and the error message isn’t clear about the real cause. MySQL 8.0 authenticates the root user via the system socket, not a password. You need to prefix your MySQL command with sudo:
sudo mysql -u root
If you genuinely need password-based root login (for a legacy app or a tool that doesn’t support socket auth), you can switch the auth plugin, but socket auth is safer and I’d leave it as-is unless you have a real reason to change it.
MySQL service won’t start after install
Check the actual error, not just the systemctl status:
sudo journalctl -u mysql -n 50 --no-pager
The most common culprits on VPS servers are a full /var partition (check with df -h) or a port conflict if something else is already on 3306 (check with sudo ss -tlnp | grep 3306).
mod_rewrite rules not working (.htaccess ignored)
If your app uses .htaccess for URL rewriting (WordPress does, Laravel does), Apache needs mod_rewrite enabled and the directory must allow overrides. Enable the module:
sudo a2enmod rewrite
sudo systemctl restart apache2
Then in your virtual host config, make sure you have AllowOverride All set for your document root directory. Without it, Apache silently ignores your .htaccess file entirely — no error, just broken URLs.
FAQ
Frequently Asked Questions
Does LAMP work on Ubuntu 24.04?
Yes. The installation process in this guide works on both Ubuntu 22.04 and 24.04. The main difference is the default PHP version — 22.04 ships PHP 8.1, while 24.04 ships PHP 8.3. Check your application’s PHP requirements before installing to make sure it supports the version your Ubuntu release provides.
Do I need LAMP if I'm using managed WordPress hosting?
No. Managed WordPress hosting (like our managed plans at Host & Tech) handles the entire server stack for you — Apache or Nginx, PHP, and MySQL are all pre-configured and maintained. LAMP installation is only necessary if you’re setting up your own unmanaged VPS or dedicated server.
How do I install a specific PHP version on Ubuntu instead of the default?
You’ll need to add the Ondrej PHP PPA, which maintains multiple PHP versions for Ubuntu. Run sudo add-apt-repository ppa:ondrej/php, then sudo apt update, and install your target version with something like sudo apt install php8.2 libapache2-mod-php8.2 php8.2-mysql. You can then switch the active PHP version using sudo update-alternatives --config php.
Can I use Nginx instead of Apache in a LAMP stack?
If you swap Apache for Nginx, it’s technically a LEMP stack (Linux, Nginx, MySQL, PHP). Nginx handles high-concurrency traffic more efficiently than Apache in many scenarios, but it doesn’t natively support .htaccess files — so if your app relies on them, you’ll need to convert those rules to Nginx server block syntax. For a straightforward LAMP setup, Apache is the easier starting point.
How do I add HTTPS/SSL to my LAMP server?
Use Certbot with the Let’s Encrypt certificate authority — it’s free and handles renewal automatically. Install it with sudo apt install certbot python3-certbot-apache -y, then run sudo certbot --apache -d yourdomain.com. Certbot will modify your Apache virtual host config and set up auto-renewal. Make sure port 443 is open in your firewall before running it.