Instalar una pila LEMP en un VPS Linux con AlmaLinux 9

2 min
Hosting VPS/VDS

Una pila LEMP (Linux, Nginx, MariaDB, PHP-FPM) es una alternativa rápida y ligera a Apache para servir sitios PHP. En AlmaLinux 9 todo viene del repositorio oficial AppStream, pero SELinux y firewalld requieren algo de atención. Esta guía te acompaña en una instalación limpia en tu VPS Linux Infrawire; los mismos pasos sirven para Rocky Linux 9.

📋 Requisitos previos

  • Un VPS KVM con AlmaLinux 9 (la IP y la contraseña root están en tu área de cliente)
  • Acceso SSH como root
  • Un dominio example.com que apunte a VPS_IP

1. Actualizar el sistema e instalar las herramientas

Bash
dnf -y update dnf -y install nano policycoreutils-python-utils

policycoreutils-python-utils aporta semanage, que se usa en la sección de SELinux.

2. Instalar Nginx y abrir el cortafuegos

Bash
dnf -y install nginx systemctl enable --now nginx firewall-cmd --permanent --add-service=http --add-service=https firewall-cmd --reload firewall-cmd --list-services

3. Instalar MariaDB

Bash
dnf -y install mariadb-server systemctl enable --now mariadb mysql_secure_installation

Responde al asistente para definir la contraseña de root, eliminar los usuarios anónimos, prohibir el acceso remoto de root y borrar la base de datos de prueba. Después crea una base de datos y un usuario dedicados:

Bash
mysql -u root -p
SQL
1CREATE DATABASE appdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 2CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'STRONG_PASSWORD'; 3GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'localhost'; 4FLUSH PRIVILEGES; 5EXIT;

4. Instalar PHP 8.3 desde el módulo de AppStream

AppStream ofrece varios flujos de PHP. Elige el que quieras antes de instalar:

Bash
dnf module list php dnf -y module reset php dnf -y module enable php:8.3 dnf -y install php-fpm php-cli php-mysqlnd php-gd php-mbstring php-xml php-intl php-opcache php-pecl-zip php -v

Por defecto, el pool de PHP-FPM se ejecuta como apache. Como Nginx corre como nginx, alinea el pool y los directorios de sesiones:

Bash
sed -i 's/^user = apache/user = nginx/; s/^group = apache/group = nginx/' /etc/php-fpm.d/www.conf chown -R root:nginx /var/lib/php/session /var/lib/php/wsdlcache /var/lib/php/opcache grep -E '^(user|group|listen)' /etc/php-fpm.d/www.conf systemctl enable --now php-fpm

El pool escucha en el socket Unix /run/php-fpm/www.sock.

5. Crear el server block

Bash
mkdir -p /var/www/example.com/public chown -R nginx:nginx /var/www/example.com nano /etc/nginx/conf.d/example.com.conf
Nginx
1server { 2 listen 80; 3 listen [::]:80; 4 server_name example.com www.example.com; 5 root /var/www/example.com/public; 6 index index.php index.html; 7 8 location / { 9 try_files $uri $uri/ /index.php?$query_string; 10 } 11 12 location ~ \.php$ { 13 include fastcgi_params; 14 fastcgi_pass unix:/run/php-fpm/www.sock; 15 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 16 } 17 18 location ~ /\.(?!well-known) { 19 deny all; 20 } 21}
Bash
nginx -t && systemctl reload nginx

6. Configurar SELinux

Mantén SELinux en modo enforcing (getenforce). Los archivos creados bajo /var/www ya reciben la etiqueta httpd_sys_content_t, pero los movidos con mv desde otro sitio conservan la antigua. Reetiquétalos y concede escritura solo a los directorios que la necesitan:

Bash
restorecon -Rv /var/www/example.com mkdir -p /var/www/example.com/public/uploads semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/example.com/public/uploads(/.*)?' restorecon -Rv /var/www/example.com/public/uploads

Activa los booleanos solo si tu aplicación los necesita:

Bash
# PHP se conecta a una base de datos por TCP (servidor remoto o 127.0.0.1) setsebool -P httpd_can_network_connect_db 1 # PHP o Nginx hacen conexiones salientes (APIs, proxy_pass hacia una aplicación) setsebool -P httpd_can_network_connect 1

Una MariaDB local a la que se accede por su socket no necesita ninguno. Para ver qué bloquea SELinux, ejecuta ausearch -m avc -ts recent. Nunca "arregles" un problema con setenforce 0.

7. Probar PHP y borrar el archivo de prueba

Bash
echo '<?php phpinfo();' > /var/www/example.com/public/info.php curl -sI http://example.com/info.php | head -n 1 rm /var/www/example.com/public/info.php

Espera HTTP/1.1 200 OK. La página phpinfo() revela tu configuración, así que elimínala enseguida. Por último, comprueba los servicios:

Bash
systemctl is-active nginx php-fpm mariadb

🛠️ Solución de problemas

502 Bad Gateway. PHP-FPM está detenido o la ruta del socket en fastcgi_pass es incorrecta. Ejecuta systemctl status php-fpm, comprueba ls -l /run/php-fpm/www.sock y lee /var/log/nginx/error.log. Si el registro indica Permission denied en el socket, busca una denegación AVC con ausearch.

403 Forbidden o Permission denied. Revisa el propietario (nginx:nginx) y la etiqueta SELinux con ls -Z /var/www/example.com/public. Debe ser httpd_sys_content_t; si no, ejecuta restorecon -Rv.

"File not found." o página en blanco. La ruta root o la línea SCRIPT_FILENAME es incorrecta. Revisa ambas y luego nginx -t.

No se puede conectar a una base de datos o API externa. SELinux bloquea por defecto las conexiones salientes: activa httpd_can_network_connect_db o httpd_can_network_connect como se indicó antes.


🎉 Nginx, MariaDB y PHP-FPM funcionan en AlmaLinux 9, con SELinux todavía en modo enforcing.

Mantente al día con las últimas ofertas, descuentos y promociones especiales.

Ver promociones

Utilizamos cookies

Utilizamos cookies analíticas para mejorar su experiencia en nuestro sitio. No vendemos datos a terceros. Más información en nuestra política de privacidad.