Software & Configuration

Stack LEMP (Linux + Nginx + MySQL + PHP)

How to install and configure a complete LEMP stack to host PHP websites

The LEMP stack (Linux, Nginx, MariaDB, PHP) is the most common combination for hosting PHP websites like WordPress, Laravel, Joomla and many others.


Fast installation (Debian/Ubuntu)

# Update the system
apt update && apt upgrade -y

# Install Nginx, MariaDB and PHP
apt install nginx mariadb-server php php-fpm php-mysql php-cli php-common \
  php-curl php-gd php-mbstring php-xml php-zip php-bcmath php-intl -y

# Start and enable services
systemctl enable --now nginx
systemctl enable --now mariadb
systemctl enable --now php8.2-fpm   # or the installed PHP version

Check the installed PHP version

php -v
php-fpm8.2 -v

# See the PHP-FPM .sock file (needed for Nginx)
ls /run/php/

Database configuration

mysql_secure_installation
mysql -u root -p
CREATE DATABASE my_site CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'db_user'@'localhost' IDENTIFIED BY 'secure_password';
GRANT ALL PRIVILEGES ON my_site.* TO 'db_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Nginx configuration with PHP-FPM

Create the site configuration:

mkdir -p /var/www/mysite
chown -R www-data:www-data /var/www/mysite
nano /etc/nginx/sites-available/mysite
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/mysite;
    index index.php index.html;

    access_log /var/log/nginx/mysite.access.log;
    error_log  /var/log/nginx/mysite.error.log;

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

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    }

    location ~ /\.ht {
        deny all;
    }

    # Limit upload to 64MB (align with php.ini)
    client_max_body_size 64M;
}

Enable the site:

ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

PHP configuration

nano /etc/php/8.2/fpm/php.ini

Recommended parameters:

upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 120
memory_limit = 256M
max_input_vars = 3000
date.timezone = Europe/Rome
systemctl restart php8.2-fpm

Install WordPress (example)

cd /var/www/mysite
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz --strip-components=1
rm latest.tar.gz
chown -R www-data:www-data /var/www/mysite
find /var/www/mysite -type d -exec chmod 755 {} \;
find /var/www/mysite -type f -exec chmod 644 {} \;

Then go to http://example.com to complete the guided installation.


SSL with Certbot

apt install certbot python3-certbot-nginx -y
certbot --nginx -d example.com -d www.example.com

See the complete guide: SSL with Certbot


Verify everything works

# Test Nginx
nginx -t

# Active services
systemctl status nginx
systemctl status mariadb
systemctl status php8.2-fpm

# Create a PHP test page
echo "<?php phpinfo(); ?>" > /var/www/mysite/info.php
# Go to http://example.com/info.php - remember to delete it after testing!
rm /var/www/mysite/info.php

On this page