How to Install Linux, Nginx, MySQL, PHP (LEMP) Stack on Ubuntu: Complete Guide
The LEMP stack — an acronym for Linux, Nginx, MySQL, and PHP — is one of the most widely adopted web server configurations for powering dynamic websites and high-performance web applications. By combining the rock-solid stability of Linux, the blazing speed of Nginx, the robust data management capabilities of MySQL, and the versatility of PHP, the LEMP stack delivers a powerful, scalable, and resource-efficient hosting environment.
Whether you're deploying a personal blog, a business website, or a complex enterprise application, a properly configured LEMP stack gives you better scalability, faster page load times, and efficient memory management — especially under high-traffic conditions.
If you need a reliable foundation to run this stack, AlexHost's VPS Hosting provides high-performance Linux-based virtual servers with full root access, giving you complete control over every component of your LEMP environment. Pair that with an SSL Certificate to secure your application from day one.
In this comprehensive guide, we'll walk you through every step of installing and configuring the full LEMP stack on an Ubuntu server — from initial system preparation to testing your live PHP environment.
Table of Contents
- Prerequisites
- Update Your System
- Install Nginx
- Install MySQL
- Install PHP
- Configure Nginx to Process PHP
- Create and Test a PHP Info File
- Conclusion
1. Prerequisites
Before you begin, make sure you have the following in place:
- A server running Ubuntu 18.04, 20.04, or 22.04 LTS
- A user account with sudo privileges
- SSH access or direct terminal access to your server
- A registered domain name (optional but recommended for production deployments — you can register one via AlexHost Domain Registration)
> Pro Tip: For a clean, isolated environment with guaranteed resources, a VPS Hosting plan is the ideal starting point for any LEMP deployment.
2. Update Your System
Before installing any packages, it's critical to refresh your package index and apply all pending updates. This ensures you're working with the latest, most secure versions of all software.
Open your terminal and run:
sudo apt update && sudo apt upgrade -yThis command updates the local package database and upgrades all installed packages to their latest available versions.
3. Install Nginx
Nginx (pronounced "engine-x") is a high-performance, event-driven web server and reverse proxy. Unlike Apache, Nginx handles concurrent connections with minimal memory consumption, making it the preferred choice for high-traffic environments.
Step 1: Install Nginx
sudo apt install nginx -yStep 2: Start and Enable Nginx
After installation, start the Nginx service and configure it to launch automatically on system boot:
sudo systemctl start nginx
sudo systemctl enable nginxStep 3: Verify Nginx Is Running
Check the service status to confirm Nginx is active:
sudo systemctl status nginxYou should see output indicating the service is active (running). You can also open a web browser and navigate to your server's IP address:
http://your_server_ipIf Nginx is running correctly, you'll be greeted by the default "Welcome to nginx!" page.
Step 4: Configure the Firewall (If Applicable)
If you have UFW (Uncomplicated Firewall) enabled, allow HTTP and HTTPS traffic:
sudo ufw allow 'Nginx Full'
sudo ufw status4. Install MySQL
MySQL is a powerful, open-source relational database management system (RDBMS) that serves as the data backbone for most dynamic web applications, including WordPress, Joomla, and custom PHP applications.
Step 1: Install MySQL Server
sudo apt install mysql-server -yStep 2: Secure the MySQL Installation
Once installed, run the built-in security hardening script. This script helps you set a strong root password, remove anonymous users, disable remote root login, and delete the test database:
sudo mysql_secure_installationYou will be prompted with a series of questions. The recommended responses for a production server are:
| Prompt | Recommended Answer |
|---|---|
| Set up VALIDATE PASSWORD component? | Yes |
| Password validation policy level | 2 (STRONG) |
| Remove anonymous users? | Yes |
| Disallow root login remotely? | Yes |
| Remove test database? | Yes |
| Reload privilege tables? | Yes |
Step 3: Verify MySQL Is Running
sudo systemctl status mysqlStep 4: Log In to MySQL (Optional Verification)
sudo mysql -u root -pEnter your root password when prompted. Type exit to leave the MySQL shell.
5. Install PHP
PHP (Hypertext Preprocessor) is the server-side scripting language that processes dynamic content and communicates with MySQL to serve data-driven web pages. When using Nginx, PHP is handled through PHP-FPM (FastCGI Process Manager), which processes PHP requests independently of the web server for improved performance.
Step 1: Install PHP-FPM and the MySQL Extension
sudo apt install php-fpm php-mysql -yYou may also want to install commonly used PHP extensions for broader application compatibility:
sudo apt install php-curl php-gd php-mbstring php-xml php-xmlrpc php-zip -yStep 2: Configure PHP-FPM for Security
Open the PHP-FPM configuration file. Replace 8.1 with your installed PHP version (check with php -v):
sudo nano /etc/php/8.1/fpm/php.iniLocate the cgi.fix_pathinfo directive and set it to 0 to prevent a critical security vulnerability:
cgi.fix_pathinfo=0> Why this matters: If cgi.fix_pathinfo is set to 1, PHP will attempt to execute the nearest file it can find if the requested PHP file does not exist. This behavior can be exploited by attackers to execute arbitrary code.
Save and close the file (Ctrl+X, then Y, then Enter).
Step 3: Restart PHP-FPM
Apply the configuration changes by restarting the PHP-FPM service:
sudo systemctl restart php8.1-fpm6. Configure Nginx to Process PHP
By default, Nginx does not know how to handle PHP files. You need to create a server block (the Nginx equivalent of an Apache virtual host) that instructs Nginx to pass PHP requests to PHP-FPM for processing.
Step 1: Create the Web Root Directory
Create the directory where your website files will be stored:
sudo mkdir -p /var/www/your_domain
sudo chown -R www-data:www-data /var/www/your_domain
sudo chmod -R 755 /var/www/your_domainReplace your_domain with your actual domain name or a descriptive project name.
Step 2: Create a New Nginx Server Block
Create a new Nginx configuration file for your site:
sudo nano /etc/nginx/sites-available/your_domainAdd the following configuration block. Read the inline comments carefully — they explain what each directive does:
server {
listen 80;
listen [::]:80;
server_name your_domain www.your_domain; # Replace with your domain or server IP
root /var/www/your_domain; # Document root — where your files live
index index.php index.html index.htm; # Default files to serve
# Handle all requests; return 404 if file not found
location / {
try_files $uri $uri/ =404;
}
# Pass PHP scripts to PHP-FPM for processing
location ~ .php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; # Adjust PHP version as needed
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# Deny access to hidden files (e.g., .htaccess)
location ~ /.ht {
deny all;
}
}> Important: Replace your_domain with your actual domain name and adjust php8.1-fpm.sock to match your installed PHP version.
Step 3: Enable the Server Block
Create a symbolic link from sites-available to sites-enabled to activate the configuration:
sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/To avoid a potential hash bucket memory problem, it's also good practice to open the main Nginx configuration and ensure the server_names_hash_bucket_size directive is uncommented:
sudo nano /etc/nginx/nginx.confFind and uncomment:
server_names_hash_bucket_size 64;Step 4: Test the Nginx Configuration
Before restarting Nginx, always test the configuration for syntax errors:
sudo nginx -tIf the output shows:
nginx: configuration file /etc/nginx/nginx.conf test is successfulYou're good to proceed.
Step 5: Restart Nginx
Apply all changes by restarting the Nginx service:
sudo systemctl restart nginx7. Create and Test a PHP Info File
To confirm that Nginx is correctly passing PHP requests to PHP-FPM, create a simple PHP test file in your document root.
Step 1: Create the PHP Info File
sudo nano /var/www/your_domain/info.phpAdd the following content:
<?php
phpinfo();
?>Save and close the file.
Step 2: Access the PHP Info Page
Open your web browser and navigate to:
http://your_domain/info.phpOr, if you haven't configured a domain yet:
http://your_server_ip/info.phpYou should see the PHP information page — a detailed overview of your PHP installation, loaded modules, configuration values, and environment variables. This confirms that all three components (Nginx, PHP-FPM, and MySQL) are working together correctly.
Step 3: Remove the PHP Info File (Critical Security Step)
Once you've confirmed everything is working, delete the info.php file immediately. This file exposes sensitive server configuration details that could be exploited by malicious actors:
sudo rm /var/www/your_domain/info.php8. Next Steps: Harden and Optimize Your LEMP Stack
With your LEMP stack up and running, consider the following additional steps to prepare your server for production:
Enable HTTPS with a Free SSL Certificate
Secure your site with TLS/SSL encryption using Certbot and Let's Encrypt:
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d your_domain -d www.your_domainAlternatively, explore AlexHost SSL Certificates for premium, commercially validated certificates that provide higher trust levels for business and e-commerce applications.
Optimize Nginx Performance
Add the following directives to your Nginx configuration to improve performance:
# Enable Gzip compression
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
# Enable browser caching for static assets
location ~* .(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}Set Up a Dedicated MySQL User
Avoid using the root MySQL account for your applications. Create a dedicated database user with limited privileges:
CREATE DATABASE your_app_db;
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON your_app_db.* TO 'app_user'@'localhost';
FLUSH PRIVILEGES;Consider a Control Panel for Easier Management
If you prefer a graphical interface for managing your LEMP stack, Nginx virtual hosts, databases, and email accounts, consider deploying a control panel. AlexHost offers VPS with cPanel and a range of other VPS Control Panels to simplify server administration without sacrificing performance or control.
9. Conclusion
You have successfully installed and configured a complete LEMP stack (Linux, Nginx, MySQL, PHP) on your Ubuntu server. Here's a quick recap of what you accomplished:
- ✅ Nginx installed, started, and configured as your web server
- ✅ MySQL installed and secured with the hardening script
- ✅ PHP-FPM installed with security-focused configuration
- ✅ Nginx server block configured to route PHP requests to PHP-FPM
- ✅ PHP processing verified via the
phpinfo()test page
This stack gives you a production-ready foundation for hosting virtually any PHP-based application — from WordPress and Laravel to custom-built platforms. The combination of Nginx's event-driven architecture and PHP-FPM's process management makes it particularly well-suited for high-concurrency workloads.
For the best performance and reliability, host your LEMP stack on a purpose-built Linux environment. AlexHost's VPS Hosting plans offer SSD-backed storage, guaranteed RAM, full root access, and 24/7 technical support — everything you need to run a fast, secure, and scalable web application.
Remember to keep all components regularly updated, monitor your server logs, and implement a firewall and intrusion detection system as part of your ongoing security posture.
