Bienvenido al mundo del mañana: ¿cómo montar un entorno «LAMP» con HTTP/2 (H2O) y PHP7 (con FPM)?

HTTP 2: el futuro de internetSi has llegado aquí, es muy probable que seas de los que buscan información sobre entornos «LAMP» con HTTP/2 y PHP7… y no encuentras gran cosa. Espero que este post te aporte un poco de luz.

En mayo de 2015 la Internet Engineering Task Force (IETF) publicó el RFC 7540. Dicha especificación «describe una expresión optimizada de las semánticas de HTTP, referida como HTTP versión 2 (HTTP/2).

El 3 de diciembre de 2015 era liberada la primera versión estable la rama 7 de PHP, PHP 7.0.0.

 

 

Si a estas alturas no te encuentras así, puedes abandonar el post y apagar Internet.

Este artículo no pretende ahondar en las peculiaridades de HTTP/2 ni PHP7 (te recomiendo el artículo de Mikel Madariaga sobre las pruebas que hicimos de PHP7 en nuestro blog), quepa decir que ambas tecnologías tienen un frente común: la mejora del rendimiento.

En Irontec no sólo apostamos por el software libre, también apostamos por la innovación y el conocimiento libre como pilares básicos de nuestra responsabilidad social corporativa, y por ese motivo (y sin mayor dilación), vamos a desgranar paso a paso la instalación de un entorno «LAMP» sobre Debian 8 HTTP/2 con soporte PHP7 mediante FPM.

Sube las escaleras o quédate mirando tus pasos. Ralph Nichols

Para nuestro entorno partiremos de la premisa de disponer de una instalación «limpia» de Debian 8 a la que disponemos de acceso root, bien sea por consola o por SSH (no pierdas la oportunidad de revisar este artículo de nuestro compañero Ismael Chasco sobre las cosas que, quizás, no sabías sobre SSH).

 

H2O

http2_logo-300x162

Para nuestro entorno LAMP HTTP/2 necesitamos un servidor web que soporte HTTP/2. El soporte que actualmente ofrecen a esta tecnología tanto Apache como Nginx están lejos del estándar de calidad a la que estos contendientes nos tienen acostumbrado; es por ello que hemos considerado oportuno darle una oportunidad a H2O, un recién llegado que a buen seguro dará mucho de que hablar.

Prerequisitos H2O

Antes de proceder con la instalación de H2O necesitamos satisfacer una serie de prerequisitos, pero antes aún, y con carácter general, es siempre recomendable que nuestras máquinas dispongan de un conjunto de herramientas que nos permitan operar sobre ellas con normalidad, determinados servicios, configuraciones y librerías.

apt-get update
apt-get install sudo vim git wget curl
apt-get install ntp
apt-get install build-essential pkg-config cmake libtool automake libcunit1 nettle-bin
apt-get install zlib1g-dev
apt-get install libssl
dpkg-reconfigure locales
dpkg-reconfigure tzdata

libuv

cd /usr/src
wget http://dist.libuv.org/dist/v1.8.0/libuv-v1.8.0.tar.gz
tar zxvf libuv-v1.8.0.tar.gz
cd /usr/src/libuv-v1.8.0
sh autogen.sh
./configure
make
make check
make install

wslay

cd /usr/src
git clone https://github.com/tatsuhiro-t/wslay.git
cd /usr/src/wslay
autoreconf -i
automake
autoconf
./configure
make
make install

Es posible que wslay de un mensaje de error relativo a la generación de la documentación, no debe preocuparnos.

Instalación H2O

Realizaremos la instalación de H2O a través de su código fuente, dado que no se encuentra paquetizado. Esto nos obligará, posteriormente, a realizar múltiples configuraciones para asegurarnos que nuestro sistema queda estable (prod-ready).

cd /usr/src/
wget https://github.com/h2o/h2o/archive/v1.6.2.tar.gz
tar zxvf v1.6.2.tar.gz
cd /usr/src/h2o-1.6.2
cmake -DWITH_BUNDLED_SSL=on .
make
make install

Llegados este punto ya tenemos nuestro servidor web H2O instalado. Sin embargo, antes de probar HTTP/2, es importante tener en cuenta que algunos navegadores implementan soporte para HTTP/2 sólo a través de conexiones seguras, con lo que necesitaremos disponer de un certificado SSL para la configuración de nuestro host (supondremos que ya disponemos de él).

Dado que pretendemos que nuestra instalación sea lo más estándar posible se atenga al FHS llevaremos a cabo los siguientes pasos:

mkdir /etc/h2o
mkdir -p /var/www/html
mkdir /var/log/h2o
mkdir /run/h2o
echo \<html\>\<head\>\<title\>PING?\<\/title\>\<\/head\>\<body\>\<p\>PONG\!\<\/b\>\<\/body\>\<\/html\> > /var/www/html/index.html
vi /etc/h2o/h2o.conf
hosts:
  "http2.irontec.com:80":
    listen:
      port: 80
    paths:
      "/":
        redirect: https://http2.irontec.com/
  "http2.irontec.com:443":
    listen:
      port: 443
      ssl:
        certificate-file: /etc/ssl/certs/certificate.crt
        key-file:         /etc/ssl/keys/key.key
    paths:
      "/":
        file.dir: /var/www/html

file.index: [ 'index.html' ]

access-log: /var/log/h2o/h2o-access.log
error-log: /var/log/h2o/h2o-error.log
pid-file: /run/h2o/h2o.pid

Ya podemos iniciar nuestro servidor web y navegar a la URL sobre la que resuelva el host que hayamos creado (debe existir la resolución DNS correspondiente). Para iniciar H2O usaremos el siguiente comando, y podremos detenerlo pulsando Ctrl+C.

h2o -c /etc/h2o/h2o.conf

Configuración H2O

Puesto que nos interesa que nuestro servidor pueda entrar en producción y sea lo más estándar posible deberemos realizar una configuración correcta del mismo. Esta configuración incluirá los puntos que detallaremos a continuación.

Gestión del servicio con Systemd

Creamos un unit para el servicio H2O, de manera que pueda gestionarse a través de H2O e iniciarse automáticamente cada vez que reiniciamos el sistema.

vi /lib/systemd/system/h2o.service
[Unit]
Description=h2o optimized HTTP server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=simple
WorkingDirectory=/etc/h2o
ExecStartPre=-/bin/mkdir -p /var/log/h2o
ExecStartPre=-/bin/mkdir -p /run/h2o
ExecStartPre=/bin/chown -R www-data:www-data /run/h2o
ExecStart=/usr/local/bin/h2o -c /etc/h2o/h2o.conf &
ExecReload=/usr/bin/kill -HUP $MAINPID
PrivateDevices=yes
PrivateTmp=true
LimitNOFILE=infinity

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable h2o.service
systemctl start h2o.service

Rotado de los registros

Es importante mantener un histórico de los registros de acceso y error a nuestro host a través de H2O, por ello configuramos la rotación de registros, habiendo optado en nuestro caso por rotar los registros semanalmente manteniendo un histórico de un año (la personalización de este apartado es subjetiva y está sujeta a la criticidad o el tráfico de los sitios hospedados).

vi /etc/logrotate.d/h2o
/var/log/h2o/*.log
{
    weekly
    missingok
    rotate 52
    compress
    delaycompress
    sharedscripts
    dateext
    dateformat -%Y-%m-%d-%s
    postrotate
        systemctl restart h2o.service > /dev/null
    endscript
}

 

PHP7

PHP-7

Para la instalación de PHP7 vamos a utilizar los paquetes precompilados que ofrecen en Dotdeb.

Instalación PHP7

La instalación desde Dotdeb requiere dar de alta el repositorio, importar su clave e instalar los paquetes básicos de PHP junto con los módulos que nos interese de entre los disponibles.

echo "deb http://packages.dotdeb.org jessie all" > /etc/apt/sources.list.d/dotdeb.list
gpg --keyserver keys.gnupg.net --recv-key 89DF5277
gpg -a --export 89DF5277 | sudo apt-key add -
apt-get update
apt-get install php7.0 php7.0-bz2 php7.0-cli php7.0-common php7.0-curl php7.0-dev php7.0-fpm php7.0-gd php7.0-imap php7.0-json php7.0-mcrypt php7.0-mysql php7.0-opcache php7.0-readline php7.0-recode php7.0-tidy php7.0-xmlrpc

Instalación módulos adicionales PHP7

En nuestro caso, nos interesan ciertos módulos que no están disponibles en el repositorio, así que deberemos instalarlos haciendo uso de pear.

cd /usr/src
wget http://pear.php.net/go-pear.phar
php go-pear.phar
vi /etc/php/7.0/fpm/php.ini
~> include_path = ".:/usr/share/php:/usr/share/pear"
systemctl restart php7.0-fpm.service

yaml

apt-get install libyaml-0-2 libyaml-dev
pear config-set preferred_state beta
pecl install yaml
echo "extension=yaml.so" > /etc/php/mods-available/yaml.ini
ln -s /etc/php/mods-available/yaml.ini /etc/php/7.0/fpm/conf.d/20-yaml.ini
ln -s /etc/php/mods-available/yaml.ini /etc/php/7.0/cli/conf.d/20-yaml.ini
systemctl restart php7.0-fpm.service

imagick

apt-get install imagemagick libmagickwand-6.q16-dev
pecl install imagick
echo "extension=imagick.so" > /etc/php/mods-available/imagick.ini
ln -s /etc/php/mods-available/imagick.ini /etc/php/7.0/fpm/conf.d/20-imagick.ini
ln -s /etc/php/mods-available/imagick.ini /etc/php/7.0/cli/conf.d/20-imagick.ini
systemctl restart php7.0-fpm.service

Configuración PHP7

Ajustamos los valores de PHP para adecuarlos a nuestro futuro entorno de producción y para su posterior conexión a H2O. En los recuadros se indica el valor de determinados valores de la configuración del fichero /etc/php/7.0/fpm/php.ini (primer cuadro) y /etc/php/7.0/fpm/pool.d/www.conf (segundo cuadro). Tras aplicar estos valores es necesario reiniciar el servicio mediante «systemctl restart php7.0-fpm.service«.

post_max_size = 640M
upload_max_filesize = 512M
memory_limit = 512M
mbstring.encoding_translation = On
date.timezone = Europe/Madrid
listen = 127.0.0.1:9000
pm.max_children = 100
pm.start_servers = 25
pm.min_spare_servers = 25
pm.max_spare_servers = 50
pm.max_requests = 1000

Integración H2O – PHP7

Finalmente procedemos a integrar nuestro servidor web H2O con PHP7, para ello deberemos modificar nuestro fichero de configuración /etc/h2o/h2o.conf.

hosts:
  "http2.irontec.com:80":
    listen:
      port: 80
    paths:
      "/":
        redirect: https://http2.irontec.com/
  "http2.irontec.com:443":
    listen:
      port: 443
      ssl:
        certificate-file: /etc/ssl/certs/certificate.crt
        key-file:         /etc/ssl/keys/key.key
    paths:
      "/":
        file.dir: /var/www/html

file.custom-handler:
  extension: .php
  fastcgi.connect:
    host: 127.0.0.1
    port: 9000
    type: tcp

file.index: [ 'index.php', 'index.html' ]

access-log: /var/log/h2o/h2o-access.log
error-log: /var/log/h2o/h2o-error.log
pid-file: /run/h2o/h2o.pid

Finalmente debemos reiniciar el servicio H2O para aplicar la nueva configuración y ya podremos desplegar ficheros PHP sobre nuestra plataforma.

systemctl restart h2o.service

Salida de la función phpinfo en nuestro entorno PHP7 sobre HTTP/2.

 

MySQL 5.7

MySQL

Un entorno LAMP requiere, por definición, de un SGBD, y no íbamos a dejarlo de lado. Para nuestro entorno HTTP/2 con PHP7 mediante FPM realizaremos la instalación de la última versión estable de MySQL, la 5.7, con importantes mejoras en el rendimiento y la seguridad.

La instalación la realizaremos a través de los repositorios oficiales de Oracle, y posteriormente realizaremos una securización básica mediante el script mysql_secure_installation. A continuación se exponen los pasos necesario para este proceso, aunque no es la finalidad de este artículo ahondar en este punto del proceso de instalación del entorno LAMP.

cd /usr/src
wget https://dev.mysql.com/get/mysql-apt-config_0.6.0-1_all.deb
dpkg -i mysql-apt-config_0.6.0-1_all.deb
apt-get update
apt-get install mysql-server-5.7 mysql-client-5.7
mysql_secure_installation

 

Con esto llegamos al final de este artículo, dejamos para entregas posteriores

  • Registro de acceso por host en H2O.
  • Trucos para desplegar un WordPress en nuestro entorno HTTP/2 y PHP7.
  • Mejoras en el rendimiento de H2O.
  • Securización en los accesos SSL en H2O.
  • Desplegar un klear sobre nuestro entorno HTTP/2 y PHP7.

…y próximamente en su blog preferido: cómo migramos nuestros entornos de preproducción a IPv6 🙂



¿Te gusta este post? Es solo un ejemplo de cómo podemos ayudar a tu empresa...
Sobre Mikel Villar

Responsable del departamento de sistemas y redes de Irontec. El resto son historias que no merecen ser contadas.

Queremos tu opinión :)