LEMP Stack · 15 min read · Oct 21, 2025

Cómo instalar LEMP Stack (Nginx, PHP y MariaDB) en Debian 12

El stack LEMP de Linux es un paquete de software popular para el desarrollo y alojamiento de aplicaciones web. Consiste en cuatro componentes clave: Linux, Nginx (pronunciado “Engine-X”), MySQL o MariaDB (una base de datos relacional) y PHP (un lenguaje de programación web popular). En esta configuración, Linux es el sistema operativo, y Nginx es el servidor web que maneja las solicitudes HTTP y sirve contenido estático como imágenes y archivos .css. MySQL, o en nuestro caso, MariaDB se utiliza como sistema de base de datos. PHP es el lenguaje de scripting utilizado para generar contenido web e interactuar dinámicamente con la base de datos. Estos componentes forman un entorno robusto y escalable para construir y desplegar sitios web y aplicaciones web.

Esta guía te enseñará a instalar un stack LEMP en un servidor Debian 12 (bookworm) lanzado hace unos días. También aprenderás a instalar aplicaciones como phpMyAdmin.

Prerrequisitos

  • Un servidor que ejecute Debian 12.
  • Un usuario no root con privilegios sudo.
  • Un nombre de dominio completamente calificado (FQDN) como example.com apuntando al servidor.
  • El Firewall sin complicaciones (UFW) está habilitado y en funcionamiento.
  • Todo está actualizado. $ sudo apt update && sudo apt upgrade
  • Algunos paquetes que tu sistema necesita. $ sudo apt install wget curl nano ufw software-properties-common dirmngr apt-transport-https gnupg2 ca-certificates lsb-release debian-archive-keyring unzip -y Algunos de estos paquetes pueden ya estar instalados en tu sistema.

Paso 1 - Configurar el Firewall

El primer paso antes de instalar cualquier paquete es configurar el firewall para permitir conexiones HTTP y HTTPS.

Verifica el estado del firewall.

$ sudo ufw status

Deberías ver algo como lo siguiente.

Estado: activo

Para                         Acción      Desde
--                         ------      ----
OpenSSH                    PERMITIR       En cualquier lugar
OpenSSH (v6)               PERMITIR       En cualquier lugar (v6)

Permitir puertos HTTP y HTTPS.

$ sudo ufw allow http
$ sudo ufw allow https

Verifica el estado nuevamente para confirmar.

$ sudo ufw status
Estado: activo

Para                         Acción      Desde
--                         ------      ----
OpenSSH                    PERMITIR       En cualquier lugar
80/tcp                     PERMITIR       En cualquier lugar
443/tcp                    PERMITIR       En cualquier lugar
OpenSSH (v6)               PERMITIR       En cualquier lugar (v6)
80/tcp (v6)                PERMITIR       En cualquier lugar (v6)
443/tcp (v6)               PERMITIR       En cualquier lugar (v6)

Paso 2 - Instalar PHP

Debian 12 viene con PHP 8.2 por defecto. Puedes instalarlo ejecutando el siguiente comando.

$ sudo apt install php-fpm php-cli php-mysql php-mbstring php-xml php-gd

Hemos instalado las extensiones MySQL, CLI, GD, Mbstring y XML de PHP. Puedes instalar cualquier extensión adicional según tus requisitos.

Para mantenerte siempre en la última versión de PHP o si deseas instalar múltiples versiones de PHP, agrega el repositorio PHP de Ondrej.

Primero, importa la clave GPG del repositorio PHP de Sury.

$ sudo curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg

Agrega el repositorio PHP de Ondrej Sury.

$ sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'

Actualiza la lista de repositorios del sistema.

$ sudo apt update   

Ahora, puedes instalar cualquier versión de PHP.

$ sudo apt install php8.1-fpm php8.1-cli

Verifica la versión de PHP instalada.

$ php --version
PHP 8.2.7 (cli) (compilado: Jun  9 2023 19:37:27) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.7, Copyright (c) Zend Technologies
    con Zend OPcache v8.2.7, Copyright (c), de Zend Technologies

Paso 3 - Instalar MariaDB

Debian 12 no viene con MySQL por defecto y aún no han lanzado un paquete oficial para ello. Por lo tanto, utilizaremos MariaDB para ello. MariaDB tampoco tiene un paquete oficial para Debian 12, pero Debian lo incluye. Por lo tanto, instálalo usando el siguiente comando.

$ sudo apt install mariadb-server

Verifica la versión de MySQL.

$ mysql --version
mysql  Ver 15.1 Distrib 10.11.3-MariaDB, para debian-linux-gnu (x86_64) usando  EditLine wrapper

Ejecuta el script de instalación segura de MariaDB.

$ sudo mysql_secure_installation

Se te pedirá la contraseña de root. Presiona Enter porque no hemos establecido ninguna contraseña para ello.

NOTA: ¡SE RECOMIENDA EJECUTAR TODAS LAS PARTES DE ESTE SCRIPT PARA TODOS LOS SERVIDORES MariaDB EN USO DE PRODUCCIÓN!  ¡LEA CADA PASO CUIDADOSAMENTE!

Para poder iniciar sesión en MariaDB y asegurarla, necesitaremos la contraseña actual del usuario root. Si acabas de instalar MariaDB y no has establecido la contraseña de root aún, simplemente presiona enter aquí.

Ingresa la contraseña actual para root (presiona enter si no hay):

A continuación, se te preguntará si deseas cambiar al método de autenticación de socket Unix. El plugin unix_socket te permite usar tus credenciales del sistema operativo para conectarte al servidor MariaDB. Dado que ya tienes una cuenta de root protegida, ingresa n para continuar.

OK, se utilizó la contraseña con éxito, avanzando...

Establecer la contraseña de root o usar el unix_socket asegura que nadie pueda iniciar sesión en el usuario root de MariaDB sin la autorización adecuada.

Ya tienes tu cuenta de root protegida, así que puedes responder 'n' con seguridad.

Cambiar a autenticación unix_socket [Y/n] n

A continuación, se te preguntará si deseas cambiar tu contraseña de root. En Debian 12, la contraseña de root está estrechamente vinculada al mantenimiento automático del sistema, por lo que debe dejarse sola. Escribe n para continuar.

 ... omitiendo.

Ya tienes tu cuenta de root protegida, así que puedes responder 'n' con seguridad.

¿Cambiar la contraseña de root? [Y/n] n

A continuación, se te harán ciertas preguntas para mejorar la seguridad de MariaDB. Escribe Y para eliminar usuarios anónimos, deshabilitar inicios de sesión remotos de root, eliminar la base de datos de prueba y recargar las tablas de privilegios.

 ... omitiendo.

Por defecto, una instalación de MariaDB tiene un usuario anónimo, lo que permite a cualquiera iniciar sesión en MariaDB sin tener que tener una cuenta de usuario creada para ellos.  Esto está destinado solo para pruebas y para hacer que la instalación sea un poco más fluida.  Debes eliminarlos antes de pasar a un entorno de producción.

¿Eliminar usuarios anónimos? [Y/n] y
 ... ¡Éxito!

Normalmente, solo se debe permitir que root se conecte desde 'localhost'.  Esto asegura que alguien no pueda adivinar la contraseña de root desde la red.

¿Deshabilitar el inicio de sesión remoto de root? [Y/n] y
 ... ¡Éxito!

Por defecto, MariaDB viene con una base de datos llamada 'test' a la que cualquiera puede acceder.  Esto también está destinado solo para pruebas y debe eliminarse antes de pasar a un entorno de producción.

¿Eliminar la base de datos de prueba y el acceso a ella? [Y/n] y
 - Eliminando la base de datos de prueba...
 ... ¡Éxito!
 - Eliminando privilegios sobre la base de datos de prueba...
 ... ¡Éxito!

Recargar las tablas de privilegios asegurará que todos los cambios realizados hasta ahora surtan efecto de inmediato.

¿Recargar tablas de privilegios ahora? [Y/n] y
 ... ¡Éxito!

Limpiando...

¡Todo listo!  Si has completado todos los pasos anteriores, tu instalación de MariaDB ahora debería estar segura.

¡Gracias por usar MariaDB!

Puedes ingresar a la consola de MariaDB escribiendo sudo mysql o sudo mariadb en la línea de comandos.

Paso 4 - Configurar MariaDB

Inicia sesión en la consola de MariaDB.

$ sudo mysql

Crea una base de datos de muestra.

MariaDB> CREATE DATABASE exampledb;

Crea una cuenta de usuario SQL.

MariaDB> CREATE USER 'exampleuser'@'localhost' IDENTIFIED BY 'YourPassword2!';

Concede todos los privilegios sobre la base de datos al usuario.

MariaDB> GRANT ALL PRIVILEGES ON exampledb.* TO 'exampleuser'@'localhost';

Dado que no estamos modificando el usuario root, debes crear otro usuario SQL para realizar tareas administrativas que empleen autenticación por contraseña. Elige una contraseña fuerte para este.

MariaDB> GRANT ALL ON *.* TO 'navjot'@'localhost' IDENTIFIED BY 'Yourpassword32!' WITH GRANT OPTION;

Recarga los privilegios de usuario.

MariaDB> FLUSH PRIVILEGES;

Sal de la consola.

MariaDB> exit

Iniciemos sesión nuevamente en la consola de MySQL usando el usuario recién creado.

$ sudo mysql -u exampleuser -p

Crea una tabla de prueba.

MariaDB> CREATE TABLE exampledb.name_list ( sno INT AUTO_INCREMENT, content VARCHAR(255), PRIMARY KEY(sno) );

Inserta datos de prueba.

MariaDB> INSERT INTO exampledb.name_list (content) VALUES ("Navjot");

Repite el comando anterior varias veces para agregar más entradas. Ejecuta el siguiente comando para verificar el contenido de la tabla.

MariaDB> SELECT * FROM exampledb.name_list;

Recibirás la siguiente salida.

+-----+---------+
| sno | content |
+-----+---------+
|   1 | Navjot  |
|   2 | Adam    |
|   3 | Josh    |
|   4 | Peter   |
+-----+---------+
4 filas en el conjunto (0.00 seg)

Sal de la consola de MySQL.

MariaDB> exit

Paso 5 - Instalar Nginx

Debian 12 viene con una versión más antigua de Nginx. Para instalar la última versión, necesitas descargar el repositorio oficial de Nginx.

Importa la clave de firma de Nginx.

$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
    | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

Agrega el repositorio para la versión estable de Nginx.

$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/debian `lsb_release -cs` nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list

Actualiza los repositorios del sistema.

$ sudo apt update

Instala Nginx.

$ sudo apt install nginx

Verifica la instalación. En sistemas Debian, el siguiente comando solo funcionará con sudo.

$ sudo nginx -v
nginx version: nginx/1.24.0

Inicia Nginx.

$ sudo systemctl start nginx

Verifica el estado del servicio.

$ sudo systemctl status nginx
? nginx.service - nginx - servidor web de alto rendimiento
     Cargado: cargado (/lib/systemd/system/nginx.service; habilitado; preset: habilitado)
     Activo: activo (en ejecución) desde Thu 2023-06-15 16:33:46 UTC; hace 1s
       Docs: https://nginx.org/en/docs/
    Proceso: 2257 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (código=salió, estado=0/ÉXITO)
   PID principal: 2258 (nginx)
      Tareas: 2 (límite: 1108)
     Memoria: 1.8M
        CPU: 6ms
     CGroup: /system.slice/nginx.service
             ??2258 "nginx: proceso maestro /usr/sbin/nginx -c /etc/nginx/nginx.conf"
             ??2259 "nginx: proceso trabajador"

Paso 6 - Configurar PHP-FPM

Abre php.ini para editar.

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

Para establecer los tamaños de carga de archivos, cambia los valores de las variables upload_max_filesize y post_max_size.

upload_max_filesize = 50M
...
post_max_size = 50M

Configura el límite de memoria de PHP según los recursos y requisitos de tu servidor.

memory_limit = 256M

Guarda el archivo presionando Ctrl + X y ingresando Y cuando se te pida.

También puedes usar los siguientes comandos para hacer las ediciones sin necesidad de abrir el archivo.

$ sudo sed -i 's/post_max_size = 8M/post_max_size = 50M/' /etc/php/8.2/fpm/php.ini
$ sudo sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 50M/' /etc/php/8.2/fpm/php.ini
$ sudo sed -i 's/memory_limit = 128M/memory_limit = 256M/' /etc/php/8.2/fpm/php.ini

Abre el archivo /etc/php/8.0/fpm/pool.d/www.conf.

$ sudo nano /etc/php/8.2/fpm/pool.d/www.conf

Necesitamos establecer el usuario/grupo Unix de los procesos PHP en nginx. Encuentra las líneas user=www-data y group=www-data en el archivo y cámbialas a nginx.

...
; Usuario/grupo Unix de los procesos
; Nota: El usuario es obligatorio. Si no se establece el grupo, se utilizará el grupo del usuario predeterminado
;       será utilizado.
user = nginx
group = nginx
...

Además, encuentra las líneas listen.owner=www-data y listen.group=www-data en el archivo y cámbialas a nginx.

listen.owner = nginx
listen.group = nginx

Guarda el archivo presionando Ctrl + X y ingresando Y cuando se te pida.

Reinicia el proceso PHP-FPM.

$ sudo systemctl restart php8.2-fpm

Paso 7 - Instalar phpMyAdmin

Descarga el archivo comprimido de phpMyAdmin para el idioma inglés. Obtén el enlace para la última versión desde la página de descarga de phpMyAdmin.

$ wget https://files.phpmyadmin.net/phpMyAdmin/5.2.1/phpMyAdmin-5.2.1-english.tar.gz

Crea un directorio público para el sitio.

$ sudo mkdir /var/www/html/example.com -p

Extrae el archivo comprimido en el directorio público.

$ sudo tar -xzf phpMyAdmin-5.2.1-english.tar.gz -C /var/www/html/example.com

Cambia al directorio público.

$ cd /var/www/html/example.com

Cambia el nombre del directorio extraído a algo poco claro para mejorar la seguridad.

$ sudo mv phpMyAdmin-5.2.1-english sm175

Paso 8 - Configurar phpMyAdmin

Copia el archivo de configuración de muestra.

$ sudo cp sm175/config.sample.inc.php sm175/config.inc.php

Abre el archivo de configuración para editar.

$ sudo nano sm175/config.inc.php

Encuentra la línea $cfg['blowfish_secret'] = ''; e ingresa una cadena aleatoria de 32 caracteres para la autenticación basada en cookies.

Puedes usar el generador de blowfish en línea de phpSolved o hacerlo a través de la línea de comandos.

Copia el valor y pégalo como se muestra.

$cfg['blowfish_secret'] = 'Tc/HfLPBOAPxJ-rhQP}HJoZEK69c3j:m';

Guarda el archivo presionando Ctrl + X y ingresando Y cuando se te pida.

Cambia la propiedad del sitio y de phpMyAdmin al servidor Nginx.

$ sudo chown -R nginx:nginx /var/www/html/example.com

Elimina el directorio de configuración de phpMyAdmin.

$ sudo rm -rf /var/www/html/example.com/sm175/setup

Paso 9 - Configurar Opcache

Opcache es el sistema de caché de PHP. Funciona guardando el bytecode de script precompilado en la memoria, por lo que cada vez que un usuario visita una página, se carga más rápido. Opcache está instalado por defecto. Para verificar, revisa la versión de PHP.

$ php --version
PHP 8.2.7 (cli) (compilado: Jun  9 2023 19:37:27) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.7, Copyright (c) Zend Technologies
    con Zend OPcache v8.2.7, Copyright (c), de Zend Technologies

Esto nos dice que Opcache está instalado y disponible. En caso de que no aparezca aquí, puedes instalarlo manualmente ejecutando el siguiente comando.

$ sudo apt install php-opcache

Para cambiar la configuración de Opcache, abre el archivo /etc/php/8.2/fpm/conf.d/10-opcache.ini para editar.

$ sudo nano /etc/php/8.2/fpm/conf.d/10-opcache.ini

La siguiente configuración debería ayudarte a comenzar a usar Opcache y se recomienda generalmente para un buen rendimiento. Puedes habilitarlo agregando las siguientes líneas al final.

opcache.enable_cli=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60

Guarda el archivo presionando Ctrl + X y ingresando Y cuando se te pida.

Reinicia PHP-FPM.

$ sudo systemctl restart php8.2-fpm

Paso 10 - Instalar Certbot para SSL

Necesitamos instalar Certbot para generar certificados SSL gratuitos ofrecidos por Let’s Encrypt.

Puedes instalar Certbot usando el repositorio de Debian o obtener la última versión usando la herramienta Snapd. Usaremos la versión de Snapd.

Debian 12 no viene con Snapd instalado. Instala el paquete Snapd.

$ sudo apt install snapd

Ejecuta los siguientes comandos para asegurarte de que tu versión de Snapd esté actualizada.

$ sudo snap install core
$ sudo snap refresh core

Instala Certbot.

$ sudo snap install --classic certbot

Usa el siguiente comando para asegurarte de que el comando Certbot pueda ejecutarse creando un enlace simbólico al directorio /usr/bin.

$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

Verifica si Certbot está funcionando correctamente.

$ certbot --version
certbot 2.6.0

Paso 11 - Probar un sitio de demostración

Crear el sitio

Crea y abre una página de prueba para editar.

$ sudo nano /var/www/html/example.com/index.php

Pega el siguiente código en él.

Lista de Miembros
    "; foreach($db->query("SELECT content FROM $table") as $row) { echo "
  1. " . $row['content'] . "
  2. "; } echo "
"; } catch (PDOException $e) { print "Error!: " . $e->getMessage() . "
"; die(); }

Guarda el archivo presionando Ctrl + X y ingresando Y cuando se te pida.

Crear un Certificado SSL

Ejecuta el siguiente comando para generar un Certificado SSL.

$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d example.com

El comando anterior descargará un certificado en el directorio /etc/letsencrypt/live/example.com en tu servidor.

Genera un certificado de grupo Diffie-Hellman.

$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096

Verifica el servicio programador de renovación de Certbot.

$ sudo systemctl list-timers

Encontrarás snap.certbot.renew.service como uno de los servicios programados para ejecutarse.

NEXT                        LEFT          LAST                        PASSED        UNIT                      ACTIVATES
.....
Sun 2023-02-26 06:32:00 UTC 9h left       Sat 2023-02-25 18:04:05 UTC 2h 59min ago  snap.certbot.renew.timer  snap.certbot.renew.service
Sun 2023-02-26 06:43:20 UTC 9h left       Sat 2023-02-25 10:49:23 UTC 10h ago       apt-daily-upgrade.timer   apt-daily-upgrade.service
Sun 2023-02-26 09:00:06 UTC 11h left      Sat 2023-02-25 20:58:06 UTC 5min ago      apt-daily.timer           apt-daily.service

Haz una prueba del proceso para verificar si la renovación de SSL está funcionando bien.

$ sudo certbot renew --dry-run

Si no ves errores, estás listo. Tu certificado se renovará automáticamente.

Configurar Nginx

Crea y abre el archivo /etc/nginx/conf.d/example.conf para editar.

$ sudo nano /etc/nginx/conf.d/example.conf

Pega el siguiente código en él.

server {
    listen       443 ssl http2;
    listen       [::]:443 ssl http2;
    server_name  example.com;

    access_log  /var/log/nginx/example.com.access.log;
    error_log   /var/log/nginx/example.com.error.log;

    ssl_certificate      /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key  /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;

    ssl_session_timeout  5m;
    ssl_session_cache shared:MozSSL:10m;
    ssl_session_tickets off;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;

    root /var/www/html/example.com;

    index index.php index.html;

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

    # Pasar scripts PHP al servidor FastCGI
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock; #depende de las versiones de PHP
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

# forzar HTTPS
server {
    listen       80;
    listen       [::]:80;
    server_name  example.com;
    return 301   https://$host$request_uri;
}

Guarda el archivo presionando Ctrl + X y ingresando Y cuando se te pida.

Abre el archivo /etc/nginx/nginx.conf para editar.

$ sudo nano /etc/nginx/nginx.conf

Agrega la siguiente línea antes de la línea include /etc/nginx/conf.d/*.conf;.

server_names_hash_bucket_size  64;

Guarda el archivo presionando Ctrl + X y ingresando Y cuando se te pida.

Verifica tu configuración de Nginx.

$ sudo nginx -t

Si no ves errores, significa que estás listo para continuar. Inicia el servidor Nginx.

$ sudo systemctl start nginx

Carga tu sitio web visitando https://example.com en tu navegador y verás la siguiente página.

Salida del sitio de prueba LEMP

Puedes acceder a tu instalación de phpMyAdmin visitando la URL https://example.com/sm175 en tu navegador. Puedes ingresar tu usuario administrativo o el usuario creado anteriormente para iniciar sesión.

Conclusión

Esto concluye nuestro tutorial donde aprendiste a configurar un stack LEMP en un servidor Debian 12 y crear un sitio de demostración. Si tienes alguna pregunta, publícalas en los comentarios a continuación.

Share: X/Twitter LinkedIn

Recibe nuevas publicaciones en tu bandeja de entrada.

No spam. Cancela la suscripción en cualquier momento.