A LEMP stack — Linux, Nginx, MySQL (or MariaDB), and PHP — is the standard modern web server stack for hosting PHP applications such as WordPress, Laravel, Drupal, and Magento. Compared to the traditional LAMP stack, Nginx handles concurrent requests more efficiently under high load due to its event-driven non-blocking architecture, making it the preferred choice for high-traffic deployments. This guide covers installing and configuring all four LEMP components on RHEL 9: the OS (already in place), Nginx for HTTP, MariaDB for the database layer, and PHP 8.3 via PHP-FPM. Each component is tested, a test PHP page is created, and a sample virtual host is configured to serve a PHP application.
Prerequisites
- RHEL 9 with sudo/root access
- Internet access for package installation
Step 1 — Install Nginx
dnf install -y nginx
systemctl enable --now nginx
firewall-cmd --permanent --add-service=http --add-service=https
firewall-cmd --reload
# Verify
curl -s http://localhost | grep -o "[^<]*"
Step 2 — Install and Secure MariaDB
dnf install -y mariadb-server
systemctl enable --now mariadb
# Run the security wizard
mysql_secure_installation
# Prompts: set root password, remove anonymous users, disallow remote root login, remove test DB
# Create a database and user for your application
mysql -u root -p <<'SQL'
CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'myapp_user'@'localhost' IDENTIFIED BY 'StrongDBPassword';
GRANT ALL PRIVILEGES ON myapp.* TO 'myapp_user'@'localhost';
FLUSH PRIVILEGES;
SQL
Step 3 — Install PHP 8.3 with PHP-FPM
dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm
dnf module enable -y php:remi-8.3
dnf install -y php php-fpm php-mysqlnd php-xml php-mbstring php-gd php-opcache php-json php-intl php-zip
php -v
systemctl enable --now php-fpm
Step 4 — Configure PHP-FPM for Nginx
# /etc/php-fpm.d/www.conf — verify these settings
[www]
user = nginx
group = nginx
listen = /run/php-fpm/www.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
systemctl restart php-fpm
Step 5 — Configure Nginx Virtual Host
# /etc/nginx/conf.d/example.com.conf
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ .php$ {
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /.ht {
deny all;
}
}
mkdir -p /var/www/example.com
chown -R nginx:nginx /var/www/example.com
nginx -t && systemctl reload nginx
Step 6 — Test the LEMP Stack
# Create a PHP info page (REMOVE in production)
echo '' > /var/www/example.com/info.php
# Test
curl http://example.com/info.php | grep -o "PHP Version [0-9.]*"
# Create a database connectivity test
cat > /var/www/example.com/dbtest.php <<'PHP'
<?php
$db = new PDO('mysql:host=localhost;dbname=myapp', 'myapp_user', 'StrongDBPassword');
echo "DB connection: OKn";
PHP
curl http://example.com/dbtest.php
rm -f /var/www/example.com/info.php /var/www/example.com/dbtest.php
Conclusion
The LEMP stack on RHEL 9 provides a production-ready PHP application hosting environment. Nginx efficiently handles concurrent HTTP connections, MariaDB provides a robust relational database, and PHP 8.3 with PHP-FPM delivers fast, isolated PHP execution. This stack is the foundation for deploying WordPress, Laravel, Symfony, and most other PHP-based web applications.
Next steps: How to Set Up a LAMP Stack on RHEL 9, How to Secure Nginx with Let’s Encrypt and Certbot on RHEL 9, and How to Configure Nginx FastCGI Caching on RHEL 9.