Knowledge Base / Servers & VPS

Installing Nginx + PHP + MySQL on Ubuntu (LEMP Stack)

Last updated: 23 September 2026

LEMP = Linux + Engine-X (Nginx) + MariaDB/MySQL + PHP. This guide installs the full stack to run a PHP site on a clean Ubuntu 22.04/24.04 server: Nginx, PHP-FPM, MariaDB, a virtual host (server block) and Let's Encrypt SSL.

First complete the First VPS Setup and Ubuntu Server Security steps (sudo user, UFW, SSH). Run the commands as a normal user with sudo.

1. Nginx

sudo apt update
sudo apt install nginx -y
sudo systemctl enable --now nginx

If UFW already allows 80,443/tcp, opening the server's IP in a browser shows the Nginx welcome page.

2. MariaDB

sudo apt install mariadb-server -y
sudo systemctl enable --now mariadb
sudo mysql_secure_installation

In the mysql_secure_installation questions: Y for unix_socket auth for root, remove anonymous users, disable remote root login, remove the test database, reload privilege tables.

A database and user for the application

sudo mysql
CREATE DATABASE app_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'A_STRONG_PASSWORD';
GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

3. PHP-FPM

sudo apt install php-fpm php-mysql php-mbstring php-xml php-curl php-zip php-gd php-intl php-bcmath -y

Check the version (typically 8.3 on Ubuntu 24.04):

php -v
systemctl status php8.3-fpm
If you need a specific PHP version, add the ondrej/php PPA: sudo add-apt-repository ppa:ondrej/php then sudo apt install php8.2-fpm ...

4. A server block for the site

sudo mkdir -p /var/www/yoursite.com/public
sudo chown -R $USER:www-data /var/www/yoursite.com

/etc/nginx/sites-available/yoursite.com:

server {
    listen 80;
    server_name yoursite.com www.yoursite.com;
    root /var/www/yoursite.com/public;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}
sudo ln -s /etc/nginx/sites-available/yoursite.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Test

echo "<?php phpinfo();" | sudo tee /var/www/yoursite.com/public/info.php

http://yoursite.com/info.php should show the PHP info page. Delete it after testing: sudo rm /var/www/yoursite.com/public/info.php

5. DNS

Point your domain's A record at the server's IP address:

yoursite.com.      A     203.0.113.10
www.yoursite.com.  A     203.0.113.10

Wait for propagation (until dig yoursite.com +short returns the IP).

6. Free SSL (Let's Encrypt)

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yoursite.com -d www.yoursite.com

Certbot obtains the certificate, updates the Nginx config to HTTPS and adds a redirect. Auto-renewal is set up via certbot.timer; test:

sudo certbot renew --dry-run

Details: What is an SSL Certificate?

7. Tighten the settings

Typical settings in /etc/php/8.3/fpm/php.ini:

upload_max_filesize = 32M
post_max_size = 32M
memory_limit = 256M
max_execution_time = 60
date.timezone = Europe/Istanbul
sudo systemctl restart php8.3-fpm

Common problems

  • 502 Bad Gateway: the PHP version in the fastcgi_pass path does not match the installed version. Run ls /run/php/ to see the correct socket.
  • 403 Forbidden: the root directory is wrong or the permissions are off. www-data must be able to read.
  • PHP file downloads instead of running: the location ~ \.php$ block is missing, or nginx -t reports an error.
  • certbot "DNS problem": the A record has not propagated yet; verify with dig and try again.
At Arcnar: If you do not want to deal with server administration, the Web Hosting category (coming soon) offers this stack ready-made. On a Compute plan you have full control — the steps in this guide apply directly.

Frequently asked questions

What is the difference between LEMP and LAMP?
In LAMP the web server is Apache, in LEMP it is Nginx (Engine-X). Nginx is more efficient for static content and high concurrency and runs PHP via PHP-FPM. Both do the same job; LEMP is more common in modern setups.
Why do I get a 502 Bad Gateway error in Nginx?
Almost always related to PHP-FPM: the PHP version in the fastcgi_pass socket path in the server block does not match the installed version, or the php-fpm service is not running. Run `ls /run/php/` to see the correct socket name and update the config.
How do I install a specific PHP version?
The Ubuntu repository usually offers a single version. For a different version, add the ondrej/php PPA: `sudo add-apt-repository ppa:ondrej/php` then `sudo apt install php8.2-fpm php8.2-mysql` and so on. Multiple versions can be installed side by side.
Do I have to delete the phpinfo() test file?
Yes. The phpinfo() output publicly reveals your PHP version, installed extensions, file paths and configuration details; this is valuable reconnaissance for an attacker. Delete the file as soon as testing is done.

Was this article helpful?