How to Install LEMP on CentOS Stream 9 or EL8
If you’ve ever tried to spin up a website on a fresh CentOS machine and ended up wrestling with broken packages, this guide is for you. We’ll walk through installing the whole LEMP stack—Linux, Nginx, MariaDB (or MySQL), and PHP‑FPM—on both CentOS Stream 9 and EL8 without the usual “It’s not working” headaches.
Installing EPEL and Base Packages
First thing: get the Extra Packages for Enterprise Linux repo. On Stream 9 it’s a single command; on EL8 you need to add the epel-release package manually.
# Stream 9 dnf install -y epel-release # EL8 yum install -y epel-release
Nginx lives in EPEL, and without it you’ll be stuck with an older, unmaintained version that breaks with newer system libraries.
Pulling Nginx from the Right Repo
The default CentOS repo ships a very old Nginx that won’t play nice with PHP‑FPM on Stream 9.
dnf install -y nginx
On EL8, you can also use the official Nginx repo if you prefer newer releases, but the EPEL copy is fine for most sites.
Setting Up MariaDB (or MySQL)
CentOS 9 ships with MariaDB by default; EL8 still uses the older mariadb-server from the base repos. If you need MySQL instead, be prepared to add Oracle’s repo first.
# MariaDB on both releases dnf install -y mariadb-server systemctl enable --now mariadb # MySQL alternative (EL8 only) yum install -y https://dev.mysql.com/get/mysql80-community-release-el8-1.noarch.rpm dnf module enable mysql:8.0 dnf install -y mysql-community-server systemctl enable --now mysqld
I’ve seen folks get stuck trying to start MySQL on EL8 without enabling the module; it’s a quick fix once you remember that command.
Installing PHP‑FPM
LEMP isn’t complete without PHP‑FPM. On Stream 9, the default repos have php-fpm 8.x ready to go.
dnf install -y php php-fpm php-mysqlnd
On EL8 you’ll end up with PHP 7.4 unless you enable the remi-php80 stream first:
yum install -y https://rpms.remirepo.net/enterprise/remi-release-8.rpm dnf module reset php dnf module enable php:remi-php80 dnf install -y php-fpm php-mysqlnd
Skipping the module reset on EL8 will leave you with an outdated PHP that may choke on modern frameworks.
Configuring Nginx to Use PHP‑FPM
Edit /etc/nginx/conf.d/default.conf (or create a new file) and point it at the PHP socket:
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.php index.html;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Why the socket? It’s faster than TCP and eliminates port‑conflict headaches when you have multiple PHP workers.
Enabling Firewall Rules
If firewalld is running, make sure HTTP traffic is allowed:
firewall-cmd --permanent --add-service=http firewall-cmd --reload
A common pitfall on EL8 is forgetting to reload after adding the rule; you’ll think Nginx works but your browser can’t reach it.
Starting and Testing the Stack
systemctl enable --now nginx php-fpm curl http://localhost
You should see “Welcome to nginx!” or your index page. If PHP isn’t processed, double‑check that fastcgi_pass points to /run/php-fpm/www.sock.
Common Gotchas and Quick Fixes
- Missing fastcgi_param SCRIPT_FILENAME: Nginx will return 404 for PHP files.
- SELinux denial on EL8: Run restorecon -Rv /usr/share/nginx/html if you see “Permission denied” errors.
- MariaDB not starting: Check /var/log/mariadb/mariadb.log; often it’s a missing InnoDB file after a clean install.
Wrapping Up (and Keeping Your Stack Happy)
That’s the whole LEMP stack in under 30 minutes, with all the quirks of CentOS Stream 9 and EL8 sorted out. The real trick is remembering to enable the right modules for PHP on EL8 and not assuming the default Nginx will work on Stream 9.