Cómo instalar la pila LEMP (Nginx, PHP y MariaDB) en Debian 12
La pila Linux LEMP es un popular paquete de software para el desarrollo y alojamiento de aplicaciones web. Consta de cuatro componentes clave: Linux, Nginx (pronunciado «Engine-X»), MySQL o MariaDB (una base de datos relacional) y PHP (un popular lenguaje de programación web). En esta configuración, Linux es el sistema operativo, y Nginx es el servidor web que gestiona las peticiones 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 con la base de datos de forma dinámica. Estos componentes forman un entorno robusto y escalable para construir y desplegar sitios y aplicaciones web.
Esta guía te enseñará a instalar una pila LEMP en un servidor Debian 12 (ratón de biblioteca) publicado hace unos días. También aprenderás a instalar aplicaciones como phpMyAdmin.
Requisitos previos
- Un servidor con Debian 12.
- Un usuario no root con privilegios sudo.
- Un nombre de dominio completo (FQDN) como
example.com
que apunte al servidor. - El cortafuegos sin complicaciones (UFW) está activado y en funcionamiento.
- Todo está actualizado.
$ sudo apt update && sudo apt upgrade
- Pocos paquetes que necesite tu sistema.
$ sudo apt install wget curl nano ufw software-properties-common dirmngr apt-transport-https gnupg2 ca-certificates lsb-release debian-archive-keyring unzip -y
Puede que algunos de estos paquetes ya estén instalados en tu sistema.
Paso 1 – Configurar el Cortafuegos
El primer paso antes de instalar ningún paquete es configurar el cortafuegos para que permita conexiones HTTP y HTTPS.
Comprueba el estado del cortafuegos.
$ sudo ufw status
Deberías ver algo como lo siguiente
Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6)
Permitir puertos HTTP y HTTPs.
$ sudo ufw allow http $ sudo ufw allow https
Vuelve a comprobar el estado para confirmarlo.
$ sudo ufw status Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 80/tcp ALLOW Anywhere 443/tcp ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) 80/tcp (v6) ALLOW Anywhere (v6) 443/tcp (v6) ALLOW Anywhere (v6)
Paso 2 – Instala PHP
Debian 12 incluye 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 necesidades.
Para estar siempre en la última versión de PHP o si quieres instalar varias versiones de PHP, añade 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
Añade 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
Comprueba la versión de PHP instalada.
$ php --version PHP 8.2.7 (cli) (built: Jun 9 2023 19:37:27) (NTS) Copyright (c) The PHP Group Zend Engine v4.2.7, Copyright (c) Zend Technologies with Zend OPcache v8.2.7, Copyright (c), by Zend Technologies
Paso 3 – Instalar MariaDB
Debian 12 no incluye MySQL por defecto y aún no han publicado 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 utilizando el siguiente comando.
$ sudo apt install mariadb-server
Comprueba la versión de MySQL.
$ mysql --version mysql Ver 15.1 Distrib 10.11.3-MariaDB, for debian-linux-gnu (x86_64) using EditLine wrapper
Ejecuta el script de instalación segura de MariaDB.
$ sudo mysql_secure_installation
Se te pedirá la contraseña de root. Pulsa Intro porque no le hemos puesto ninguna contraseña.
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY! In order to log into MariaDB to secure it, we'll need the current password for the root user. If you've just installed MariaDB, and haven't set the root password yet, you should just press enter here. Enter current password for root (enter for none):
A continuación, se te preguntará si quieres cambiar al método de autenticación por socket Unix. El complemento unix_socket
te permite utilizar las credenciales de tu sistema operativo para conectarte al servidor MariaDB. Como ya tienes una cuenta raíz protegida, introduce n
para continuar.
OK, successfully used password, moving on... Setting the root password or using the unix_socket ensures that nobody can log into the MariaDB root user without the proper authorisation. You already have your root account protected, so you can safely answer 'n'. Switch to unix_socket authentication [Y/n] n
A continuación, se te preguntará si quieres cambiar la contraseña de root. En Debian 12, la contraseña de root está estrechamente ligada al mantenimiento automatizado del sistema, por lo que conviene no modificarla. Escribe n
para continuar.
... skipping. You already have your root account protected, so you can safely answer 'n'. Change the root password? [Y/n] n
A continuación, se te harán algunas preguntas para mejorar la seguridad de MariaDB. Escribe Y para eliminar los usuarios anónimos, desautorizar los inicios de sesión remotos de root, eliminar la base de datos de prueba y recargar las tablas de privilegios.
... skipping. By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? [Y/n] y ... Success! Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? [Y/n] y ... Success! By default, MariaDB comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? [Y/n] y - Dropping test database... ... Success! - Removing privileges on test database... ... Success! Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? [Y/n] y ... Success! Cleaning up... All done! If you've completed all of the above steps, your MariaDB installation should now be secure. Thanks for using MariaDB!
Puedes entrar en el intérprete de comandos de MariaDB escribiendo sudo mysql
o sudo mariadb
en la línea de comandos.
Paso 4 – Configurar MariaDB
Accede al shell de MariaDB.
$ sudo mysql
Crea una base de datos de ejemplo.
MariaDB> CREATE DATABASE exampledb;
Crea una cuenta de usuario SQL.
MariaDB> CREATE USER 'exampleuser'@'localhost' IDENTIFIED BY 'YourPassword2!';
Concede al usuario todos los privilegios sobre la base de datos.
MariaDB> GRANT ALL PRIVILEGES ON exampledb.* TO 'exampleuser'@'localhost';
Como no vamos a modificar el usuario root, debes crear otro usuario SQL para realizar tareas administrativas que empleen autenticación por contraseña. Elige una contraseña segura para éste.
MariaDB> GRANT ALL ON *.* TO 'navjot'@'localhost' IDENTIFIED BY 'Yourpassword32!' WITH GRANT OPTION;
Elimina los privilegios del usuario.
MariaDB> FLUSH PRIVILEGES;
Sal del intérprete de comandos.
MariaDB> exit
Volvamos a entrar en el intérprete de comandos MySQL utilizando 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 los datos de prueba.
MariaDB> INSERT INTO exampledb.name_list (content) VALUES ("Navjot");
Repite el comando anterior varias veces para añadir más entradas. Ejecuta el siguiente comando para comprobar 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 rows in set (0.00 sec)
Sal del intérprete de comandos MySQL.
MariaDB> exit
Paso 5 – Instalar Nginx
Debian 12 incluye una versión antigua de Nginx. Para instalar la última versión, tienes que 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
Añade el repositorio de 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 sólo funcionará con sudo
.
$ sudo nginx -v nginx version: nginx/1.24.0
Inicia Nginx.
$ sudo systemctl start nginx
Comprueba el estado del servicio.
$ sudo systemctl status nginx ? nginx.service - nginx - high performance web server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled) Active: active (running) since Thu 2023-06-15 16:33:46 UTC; 1s ago Docs: https://nginx.org/en/docs/ Process: 2257 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS) Main PID: 2258 (nginx) Tasks: 2 (limit: 1108) Memory: 1.8M CPU: 6ms CGroup: /system.slice/nginx.service ??2258 "nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf" ??2259 "nginx: worker process"
Paso 6 – Configurar PHP-FPM
Abre php.ini
para editarlo.
$ sudo nano /etc/php/8.2/fpm/php.ini
Para configurar el tamaño de subida de los 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 en función de los recursos y requisitos de tu servidor.
memory_limit = 256M
Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te solicite.
También puedes utilizar los siguientes comandos para realizar las modificaciones 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 a nginx. Busca las líneas user=www-data
y group=www-data
en el archivo y cámbialas por nginx
.
... ; Unix user/group of processes ; Note: The user is mandatory. If the group is not set, the default user's group ; will be used. user = nginx group = nginx ...
Busca también las líneas listen.owner=www-data
y listen.group=www-data
en el archivo y cámbialas por nginx
.
listen.owner = nginx listen.group = nginx
Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te solicite.
Reinicia el proceso PHP-fpm.
$ sudo systemctl restart php8.2-fpm
Paso 7 – Instalar phpMyAdmin
Descarga el archivo de phpMyAdmin para el idioma español. Coge el enlace para la última versión de 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 al 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 oscuro para mejorar la seguridad.
$ sudo mv phpMyAdmin-5.2.1-english sm175
Paso 8 – Configurar phpMyAdmin
Copia el archivo de configuración de ejemplo.
$ sudo cp sm175/config.sample.inc.php sm175/config.inc.php
Abre el archivo de configuración para editarlo.
$ sudo nano sm175/config.inc.php
Busca la línea $cfg['blowfish_secret'] = '';
e introduce una cadena aleatoria de 32 caracteres para la autenticación basada en cookies.
Puedes utilizar el generador blowfish online 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 pulsando Ctrl + X e introduciendo Y cuando se te solicite.
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 bytecode de scripts precompilados en la memoria, de modo que cada vez que un usuario visita una página, ésta se carga más rápido. Opcache está instalado por defecto. Para verificarlo, comprueba la versión de PHP.
$ php --version PHP 8.2.7 (cli) (built: Jun 9 2023 19:37:27) (NTS) Copyright (c) The PHP Group Zend Engine v4.2.7, Copyright (c) Zend Technologies with Zend OPcache v8.2.7, Copyright (c), by Zend Technologies
Esto nos indica 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 editarlo.
$ sudo nano /etc/php/8.2/fpm/conf.d/10-opcache.ini
Los siguientes ajustes deberían servirte para empezar a utilizar Opcache y, en general, se recomiendan para obtener un buen rendimiento. Puedes activarla añadiendo las siguientes líneas en la parte inferior.
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 pulsando Ctrl + X e introduciendo Y cuando se te solicite.
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 utilizando el repositorio de Debian u obtener la última versión utilizando la herramienta Snapd. Nosotros utilizaremos la versión 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
Utiliza el siguiente comando para asegurarte de que se puede ejecutar el comando Certbot creando un enlace simbólico al directorio /usr/bin
.
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
Comprueba si Certbot funciona correctamente.
$ certbot --version certbot 2.6.0
Paso 11 – Probar un sitio de demostración
Crea el sitio
Crea y abre una página de prueba para editarla.
$ sudo nano /var/www/html/example.com/index.php
Pega en ella el siguiente código.
<?php $user = "exampleuser"; $password = "YourPassword2!"; $database = "exampledb"; $table = "name_list"; try { $db = new PDO("mysql:host=localhost;dbname=$database", $user, $password); echo "<h2>Members List</h2><ol>"; foreach($db->query("SELECT content FROM $table") as $row) { echo "<li>" . $row['content'] . "</li>"; } echo "</ol>"; } catch (PDOException $e) { print "Error!: " . $e->getMessage() . "<br/>"; die(); }
Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te pida.
Crea 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
de tu servidor.
Genera un certificado de grupo Diffie-Hellman.
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
Comprueba el servicio del programador de renovaciones 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
Realiza una ejecución en seco del proceso para comprobar si la renovación SSL funciona correctamente.
$ sudo certbot renew --dry-run
Si no ves ningún error, ya está todo listo. Tu certificado se renovará automáticamente.
Configurar Nginx
Crea y abre el archivo /etc/nginx/conf.d/example.conf
para editarlo.
$ sudo nano /etc/nginx/conf.d/example.conf
Pega en él el siguiente código.
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; } # Pass PHP Scripts To FastCGI Server location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/run/php/php8.2-fpm.sock; #depends on PHP versions fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } } # enforce HTTPS server { listen 80; listen [::]:80; server_name example.com; return 301 https://$host$request_uri; }
Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te pida.
Abre el archivo /etc/nginx/nginx.conf
para editarlo.
$ sudo nano /etc/nginx/nginx.conf
Añade la siguiente línea antes de la línea include /etc/nginx/conf.d/*.conf;
.
server_names_hash_bucket_size 64;
Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te solicite.
Comprueba la configuración de Nginx.
$ sudo nginx -t
Si no ves ningún error, significa que puedes 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.
Puedes acceder a tu instalación de phpMyAdmin visitando la URL https://example.com/sm175
en tu navegador. Puedes introducir tu usuario administrativo o el usuario creado anteriormente para acceder.
Conclusión
Con esto concluye nuestro tutorial, en el que has aprendido a configurar una pila LEMP en un servidor Debian 12 y has creado un sitio de demostración. Si tienes alguna pregunta, publícala en los comentarios a continuación.