Microordenadores - Desarrollos modernos para sistemas retro

Servidor web Nginx + PHP + MariaDB en Raspberry Pi
7 de Julio de 2017

Si quieres montar un servidor web casero para sitios dinámicos con bases de datos una buena opción es usar Nginx con PHP5 y MariaDB con Raspbian en una Raspberry Pi 3 Model B usando solamente repositorios oficiales y sin tener que compilar ningún paquete, lo que facilitará enormemente las actualizaciones.

Como se trata de un servidor LAMP modernizado (Nginx en vez de Apache y MariaDB en vez de MySQL) no hace falta entorno gráfico, por lo que configuro el sistema como un servidor con línea de comandos sin autologin mediante raspi-config, eligiendo las siguientes opciones:

$ sudo raspi-config
  1. Boot Options
  2. B1 Desktop / CLI
  3. B1 Console

Una vez seleccionado esto y mediante tabulador, elijo la opción Finish y el sistema reiniciará.

Actualizar la lista de paquetes

Primero de todo hay que actualizar la lista de paquetes. Es conveniente actualizar también los paquetes actualizados para que todo esté al día:

$ sudo apt-get update
$ sudo apt-get upgrade 

Eliminar systemd

Este paso es opcional; yo lo hago en cualquier sistema Linux donde no vaya a usar entorno gráfico ya que systemd añade complejidad al sistema, es una fuente de problemas y no es necesario. Resumen del tutorial para eliminar systemd de Raspbian:

$ sudo apt-get install sysvinit-core sysvinit-utils
$ sudo cp /usr/share/sysvinit/inittab /etc/inittab
$ sudo apt-get remove --purge --auto-remove systemd

Instalación de Nginx, MariaDB y PHP5

Aunque PHP 7 tiene mayor rendimiento, aún no está disponible en los repositorios oficiales de Raspbian, por lo que uso PHP 5, de forma que evito compilaciones manuales que luego suponen complicaciones a la hora de actualizar y tener que confiar en repositorios de terceros.

Con el comando apt-cache search php5 puedes ver los módulos disponibles para PHP; en este caso instalaré solamente php5-mysqlnd que es el que se necesita para acceso a base de datos MySQL. Al usar el servidor web Nginx (que ofrece un rendimiento mucho mayor a Apache2) el paquete de PHP que hay que instalar es php-fpm. Durante el proceso de instalación de MariaDB pedirá una contraseña para root; ésta es la contraseña del usuario administrador de la base de datos.

$ sudo apt-get install php5-mysqlnd nginx php5-fpm mariadb-server

Una vez terminado el proceso puedes borrar los paquetes que ya no son necesarios:

$ sudo apt-get autoremove

Como configurar Nginx.conf para que soporte PHP

Para que el servidor web tenga soporte de PHP hay que editar el archivo de configuración de Nginx. Usaré el editor nano; para salir y guardar se pulsa Control+X.

$ sudo nano /etc/nginx/sites-enabled/default

Aquí hago una serie de cambios: comentar la línea listen [::]:80 default_server; poniendo el carácter # delante, ya que no voy a usar IPv6; también añado index.php al parámetro index y quito comentarios en la parte correspondiente al bloque location ~ \.php$ { }, con lo que el archivo (quitando bloques de comentarios) queda así:

server {
	listen 80 default_server;
	#listen [::]:80 default_server;

	root /var/www/html;
	server_name _;

	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		try_files $uri $uri/ =404;
	}

	# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
	#
	location ~ \.php$ {
		include snippets/fastcgi-php.conf;

		# With php5-cgi alone:
		#fastcgi_pass 127.0.0.1:9000;
		# With php5-fpm:
		fastcgi_pass unix:/var/run/php5-fpm.sock;
	}
}

Para que los cambios surjan efecto hay que cargar la nueva configuración de Nginx:

pi@raspberrypi:~ $ sudo /etc/init.d/nginx reload
[ ok ] Reloading nginx configuration: nginx.

Si usas systemd el comando es:

$ sudo systemctl reload nginx.service

Si no confirma que ha cargado bien revisa el log de esta forma:

$ tail -f /var/log/nginx/error.log

Haciendo este tutorial encontré dos errores:

  • [emerg] 3298#0: "fastcgi_pass" directive is duplicate in /etc/nginx/sites-enabled/default:51
  • [emerg] 2811#0: socket() [::]:80 failed (97: Address family not supported by protocol)

El primero de ellos se debe a que descomenté el bloque entero de PHP con lo que había dos llamadas a fastcgi_pass. El segundo se debe a que no comenté la línea de IPv6. Tal y como está la configuración que puse anteriormente funciona perfectamente.

Configuración de MariaBD

Ahora tienes que ejecutar un script para mejorar la seguridad de la instalación por defecto, y añadir un usuario y base de datos específica para tu aplicación (en este ejemplo usuario owncloud, base de datos owncloud y contraseña Cpn4aB~]ODeW^:

# mysql_secure_installation
Enter current password for root (enter for none): Enter
Set root password? [Y/n] Enter 
Remove anonymous users? [Y/n] Enter
Disallow root login remotely? [Y/n] Enter
Remove test database and access to it? [Y/n] Enter
Reload privilege tables now? [Y/n] Enter

# mysql -u root -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 9
Server version: 10.0.30-MariaDB-0+deb8u2 (Raspbian)

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> create database owncloud;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> create user 'owncloud'@'localhost' identified by 'Cpn4aB~]ODeW^';
Query OK, 0 rows affected (0.00 sec)

ariaDB [(none)]> grant all privileges on owncloud.* to 'owncloud'@'localhost';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> quit
Bye

Tienes más información sobre MariaDB en el tutorial para configurar la Raspberry Pi como servidor de bases de datos SQL.

Comprobando que todo funciona

Crea con nano el archivo /var/www/html/info.php con el siguiente contenido:

<?php
	phpinfo();
?>

Cargando la dirección http://ip.de.tu.raspberry/info.php desde el navegador de un ordenador conectado a tu misma red la IP de tu Raspberry debe aparecer una pantalla así, lo que confirma que la instalación ha sido correcta:

Servidor web Nginx + PHP + MariaDB en una Raspberry Pi 3

Como abrir y redireccionar los puertos del router

Si quieres que tu servidor web sea visible desde internet necesitas abrir el puerto 80 en el router y redirigirlo a la IP de tu Raspberry. En mi caso uso un router OpenBSD, concretamente el EdgeRouter Lite, y esto es tan sencillo como añadir esta línea a /etc/pf.conf y cargar la nueva configuración con doas pfctl -f /etc/pf.conf:

pass in on egress inet proto tcp from any to (egress) port 80 rdr-to 192.168.2.121

Si usas LEDE u OpenWrt aquí tienes un tutorial que explica como redireccionar los puertos del router.

Aplicaciones

Con este conjunto de software puedes desarrollar sitios web dinámicos o instalar aplicaciones como una nube casera con Nextcloud.


Contenido relacionado: