Configurar VPS desde cero V: servidor web nginx
En este post, continuación de la serie de como configurar nuestro servidor vps desde cero, procederemos a instalar el servidor web. Me he decidido por nginx en vez de apache por su mejor aprovechamiento de los recursos. Aunque como contrapartida, su configuración es mas compleja.
En muchas pagina podremos encontrar ficheros .htaccess
usados por Apache con diversas configuraciones, pero es mas raro encontrar la configuración equivalente para nginx. Seguramente tendremos que buscar en otras paginas para saber como configurarlo.
Ademas, una vez metidos en harina, creo que es interesante añadir tres mejoras para optimizar el rendimiento el servidor web: el soporte para el protocolo http2, la compresión brotli y el modulo pagespeed.
- ¿Qué es el protocolo http2?
- ¿Qué es la compresión brotli?
- El módulo pagespeed
- ¿Porque compilar nginx desde el código fuente?
- Preparativos antes de compilar el código fuente de nginx
- Compilando e instalando nginx
- Posibles errores en la compilación
- Modificación del fichero de configuración de la web
- Comprobando http2 y Brotli
¿Qué es el protocolo http2?
El protocolo http2 es una actualización de la version 1.1 del protocolo http, que es el que te permite estar viendo ahora mismo esta web.
Entre sus mejoras, podemos destacar las siguientes:
- HTTP/2 es binario, en lugar de textual.
- Está totalmente multiplexado, enviando múltiples peticiones en paralelo a través de una única conexión TCP.
- Utiliza compresión de cabecera HPACK para reducir la sobrecarga.
- Permite a los servidores "empujar" las respuestas proactivamente a las cachés de los clientes en lugar de esperar una nueva solicitud para cada recurso.
- Utiliza la nueva extensión ALPN que permite conexiones cifradas más rápidas, ya que el protocolo de aplicación se determina durante la conexión inicial.
- Reduce los tiempos adicionales de ida y vuelta (RTT), haciendo que su sitio web se cargue más rápido sin necesidad de optimización.
- Domain sharding y la concatenación de activos ya no son necesarios con HTTP/2.
El protocolo http2 incluye mas mejoras aparte de las citadas, si quieres informarte sobre ellas, puedes consultar el RFC: HTTP/2 RFC7540
¿Qué es la compresión brotli?
Es un método alternativo a la tradicional compresión gzip, que permite servir los recursos de las paginas comprimidos al navegador, con lo que se aumenta la velocidad (esto es relativo, ya que la compresión solo se nota en ficheros de texto: html, css, js, etc; en los recursos binarios apenas se gana nada con la compresión).
Brotli permite un mayor grado de compresión con un menor consumo de cpu. Según la web de certsimple, la mejora de brotli sobre gzip es:
- Los ficheros de Javascript comprimidos con Brotli son un 14% más pequeños que gzip.
- Los ficheros HTML son un 21% más pequeños que gzip.
- Los ficheros CSS son un 17% más pequeños que gzip.
Ademas, la compresión brotli esta soportada en la mayoría de los navegadores:

El módulo pagespeed
El modulo pagespeed desarrollado por Google permite realizar optimizaciones en los ficheros de recursos (javascript, css, html e imágenes) para aumentar la velocidad de carga sin necesidad de modificar nada del código existente.
¿Porque compilar nginx desde el código fuente?
Dado que los repositorios de debian, la version de nginx no incluye ni http2, ni la compresión brotli por defecto, deberemos descargar sus fuentes y compilar de nuevo nginx incluyendo el código fuente de ambas características, asi como de pagespeed.
Si hubiera un repositorio que lo incluyese, seria mucho mas fácil, tan solo con un apt-get install nginx_con_http2_y_brotli
nos serviría. Ademas, al depender de un repositorio, se actualizaría al hacer un apt-get update
.
Pero las cosas no pueden ser sencillas. Así que nos tocara pegarnos con el código fuente, compilar y comprobar que todo funciona perfectamente. Un detalle a tener en cuenta es que al ser compilado, no se actualizara el nginx, por lo que si deseamos hacerlo, deberemos repetir los pasos y compilarlo de nuevo.
Preparativos antes de compilar el código fuente de nginx
Obteniendo los parámetros de configuración de nginx
Como actualmente ya tengo instalada una version de nginx de los repositorios en el servidor vps, y quiero añadir el soporte http2 y la compresión brotli, tengo que compilar el código fuente de nginx.
Un paso muy importante a la hora de compilar es especificar los parámetros de configuración por defecto con que deseamos hacerlo, lo primero que necesito es obtenerlos de la actual version de nginx instalada. De esta manera obtendré una version con los mismos módulos que la actual y evito tener problemas por faltar alguna característica del nginx actual.
nginx -V
Nos devolverá esta respuesta, donde podremos encontrar los parámetros de configuración por defecto que necesitamos. Buscamos la cadena --prefix=
y todo lo que muestra, son parámetros que anotaremos para mas adelante:
nginx version: nginx/1.6.2 TLS SNI support enabled configure arguments: --with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt=-Wl,-z,relro --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module
Añadir soporte http2 a nginx
Para añadir el soporte de http2, debemos incluir el parametro --with-http_v2_module a la hora de hacer el ./configure
en el código de nginx:
--with-http_v2_module
Añadiendo la compresión Brotli
Comenzamos instalando las librerías y programas necesarios para poder compilar el código fuente de brotli:
apt-get install build-essential zlib1g-dev libpcre3-dev libssl-dev libxslt1-dev libxml2-dev libgd2-xpm-dev libgeoip-dev libgoogle-perftools-dev libperl-dev git
Clonamos el código fuente del repositorio de Brotli:
cd /usr/local/src git clone https://github.com/google/ngx_brotli.git cd ngx_brotli git submodule update --init --recursive
Añadiendo el modulo pagespeed
Comenzamos siguiendo las instrucciones de instalación de pagespeed descargando los paquetes necesarios para poder compilar el código fuente:
sudo apt-get install build-essential zlib1g-dev libpcre3 libpcre3-dev unzip uuid-dev
A continuación debemos comprobar cual es la ultima version de pagespeed actualmente y sustituirla en estas instrucciones:
NPS_VERSION=1.13.35.2-stable cd wget https://github.com/apache/incubator-pagespeed-ngx/archive/v${NPS_VERSION}.zip unzip v${NPS_VERSION}.zip nps_dir=$(find . -name "*pagespeed-ngx-${NPS_VERSION}" -type d) cd "$nps_dir" NPS_RELEASE_NUMBER=${NPS_VERSION/beta/} NPS_RELEASE_NUMBER=${NPS_VERSION/stable/} psol_url=https://dl.google.com/dl/page-speed/psol/${NPS_RELEASE_NUMBER}.tar.gz [ -e scripts/format_binary_url.sh ] && psol_url=$(scripts/format_binary_url.sh PSOL_BINARY_URL) wget ${psol_url} tar -xzvf $(basename ${psol_url}) # extracts to psol/
Debemos cambiar la version en negrita (1.13.35.2-stable) por la que actualmente nos muestre en las notas de la version.
Compilando e instalando nginx
Lo primero que necesitamos es descargar el código fuente de OpenSSL, porque para activar ALPN, la version de OpenSSL debe ser mayor o igual a 1.0.2.
Primero, debemos buscar cual es la ultima version del código de OpenSSL publicada. Comprobamos en la pagina de versiones publicadas de OpenSSL la ultima y copiamos el hash. Cuando escribo estas lineas, la ultima version es la OpenSSL es la 1.1.1c y el hash es 97ace46e11dba4c4c2b7cb67140b6ec152cfaaf4.
Creamos el directorio para OpenSSL y descargamos el código fuente:
cd /usr/local/src git clone https://github.com/openssl/openssl.git cd openssl git checkout 97ace46e11dba4c4c2b7cb67140b6ec152cfaaf4
Para que a la hora de compilar nginx compile las fuentes de OpenSSL 1.1.1c, debemos añadir este parametro al ./configure
--with-openssl=/usr/local/src/openssl
Y continuamos descargando la ultima version de nginx disponible, cuando escribo estas lineas es la 1.17.0
wget http://nginx.org/download/nginx-1.17.0.tar.gz
Descomprimimos el fichero tar.gz:
tar -xzvf nginx-1.17.0.tar.gz
PAra incluir el protocolo http2, debemos incluir el parametro:
--with-http_v2_module
Para incluir la compresión brotli, debemos añadir el parámetro:
--add-module=/usr/local/src/ngx_brotli --sbin-path=/usr/sbin/nginx
Para incluir el modulo pagespeed, debemos añadir el siguiente parámetro a la linea de compilación de nginx:
--add-module=../incubator-pagespeed-ngx-1.13.35.2-stable
Con lo que al final procedemos a compilar nginx, comenzando por hacer un ./configure
con los parametros por defecto y los correspondientes a http2, brotli, openssl y pagespeed:
cd nginx-1.17.0 ./configure --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-http_v2_module --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module --with-openssl=/usr/local/src/openssl --add-module=../incubator-pagespeed-ngx-1.13.35.2-stable --add-module=/usr/local/src/ngx_brotli --sbin-path=/usr/sbin/nginx
Nos preguntara si queremos instalar los binarios precompilados de PSOL, responderemos que si:
You have set --with-debug for building nginx, but precompiled Debug binaries for PSOL, which ngx_pagespeed depends on, aren't available. If you're trying to debug PSOL you need to build it from source. If you just want to run nginx with debug-level logging you can use the Release binaries. Use the available Release binaries? [Y/n] Y
Cuando acabe de realizar el ./configure
, nos mostrara una pantalla similar a esta:

procedemos a compilar e instalar nginx:
make make install
Nos mostrar algo similar a esta pantalla:

Comprobamos que nginx se ha actualizado correctamente, hacemos un nginx -V
:
nginx -V
Nos mostrara un mensaje similar a este:
nginx version: nginx/1.17.0 built by gcc 4.9.2 (Debian 4.9.2-10+deb8u2) built with OpenSSL 1.1.1c 28 May 2019 TLS SNI support enabled configure arguments: --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-http_v2_module --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module --with-openssl=/usr/local/src/openssl --add-module=../incubator-pagespeed-ngx-1.13.35.2-stable --add-module=/usr/local/src/ngx_brotli --sbin-path=/usr/sbin/nginx
Podemos comprobar que se ha compilado correctamente con la ultima version de OpenSSL, con el protocolo http2 (--with-http_v2_module
), brotli (--add-module=/usr/local/src/ngx_brotli
) y pagespeed (--add-module=../incubator-pagespeed-ngx-1.13.35.2-stable
)
Posibles errores en la compilación
A continuación se muestran una serie de errores que nos pueden surgir por faltar alguna libreria en nuestro sistema y como resolverlos.
HTTP image filter module requires the GD library
Si nos muestra el mensaje de error:
./configure: error: the HTTP image filter module requires the GD library. You can either do not enable the module or install the libraries.
Debemos instalar el paquete libgd-dev
apt-get install libgd-dev
GeoIP module requires the GeoIP library
Si nos muestra el mensaje de error:
./configure: error: the GeoIP module requires the GeoIP library. You can either do not enable the module or install the library.
Debemos instalar el paquete libgeoip-dev
apt-get install libgeoip-dev
SSL modules require the OpenSSL library
Si nos muestra el mensaje de error:
./configure: error: SSL modules require the OpenSSL library. You can either do not enable the module or install the library.
Debemos instalar el paquete libssl-dev
apt-get install libssl-dev
HTTP rewrite module requires the PCRE library
Si nos muestra el mensaje de error:
./configure: error: the HTTP rewrite module requires the PCRE library. You can either do not enable the module or install the library.
Debemos instalar el paquete libpcre++-dev
apt-get install libpcre++-dev
HTTP XSLT module requires the libxml2/libxslt
Si nos muestra el mensaje de error:
./configure: error: the HTTP XSLT module requires the libxml2/libxslt You can either do not enable the module or install the library.
Debemos instalar el paquete libxslt1-dev
apt-get install libxslt1-dev
Modificación del fichero de configuración de la web
Ahora debemos modificar el fichero de configuración de nuestra web en /etc/nginx/sites-enabled/miweb
. Necesitaremos modificar uno o varios ficheros, dependiendo del numero de web que aloja nuestro vps.
nano /etc/nginx/sites-enables/miweb
Y activamos http2:
listen *:443 ssl http2;
Y también activamos la compresión brotli:
brotli on; brotli_comp_level 6; brotli_min_length 256; brotli_types application/javascript application/json application/xml image/svg+xml text/css text/plain;
En esta tabla se puede comprobar las funciones que realiza cada parametro:
Parámetro | Valor | Función que realiza |
---|---|---|
brotli | on | Activación de la compresión brotli. |
brotli_comp_level | 6 | Nivel de compresión de 1 a 11. A mayor nivel, mas compresión, pero tardara mas en generar el fichero comprimido. |
brotli_min_length | 256 | Longitud minima del fichero a comprimir. Cualquier fichero menor de 256 bytes no sera comprimido. |
brotli_types | application/javascript application/json application/xml image/svg+xml text/css text/plain | Tipo de ficheros a comprimir. Todos los ficheros de estos tipos mime comprimidos si cumplen el criterio anterior. |
Comprobaremos que la configuración es correcta:
nginx -t
Es posible que nos muestre este mensaje de error:
nginx: [emerg] "try_files" directive FileCachePath must be set, even for standby in /etc/nginx/nginx.conf:88
Esto es debido porque debemos indicar el directorio que usara pagespeed, asi que haremos los siguiente:
mkdir -p /var/ngx_pagespeed
Y añadir el parametro FileCachePath
en cada fichero de configuración de cada web:
pagespeed FileCachePath /var/ngx_pagespeed_cache;
Si todo ha salido bien y el nginx -t
no nos muestra ningun aviso de error en la configuración, debemos reiniciar nginx para que se actualice y cargue la nueva configuración de los sitios web:
/etc/init.d/nginx restart
Comprobando http2 y Brotli
Una vez hemos instalado nginx, debemos comprobar que funcionan correctamente tanto el protocolo http2 y la compresión brotli.
Para comprobar el funcionamiento del protocolo http2, podemos ir al sitio http2 test, donde con solo introducir la url de nuestro dominio donde hemos activado http2, nos indicara si esta activo o no.

Podemos comprobar también en la misma pagina si esta activa la compresión brotli:

Ya tenemos funcionando nuestro nginx con http2, pagespeed y brotli!!
Deja una respuesta