CDN con Varnish, Nginx y Minio

Escrito el 2023-04-07 por Alberto Ferrer
Tiempo de lectura: 5 minuto(s)
Etiquetas: nginx minio varnish cdn

El artículo describe cómo crear un CDN (Content Delivery Network) utilizando Varnish, Nginx y Minio. Un CDN es una red de servidores distribuidos geográficamente que almacenan contenido web estático y lo entregan al usuario final desde el servidor más cercano.

Utilizando Varnish como caché de nivel superior y Minio como almacenamiento de objetos, podemos construir un CDN escalable y de alto rendimiento.

Nginx se utiliza como servidor web para servir el contenido estático y manejar la conexión SSL. El artículo proporciona una guía paso a paso para configurar cada uno de estos componentes y conectarlos para crear un CDN funcional.

  • Instala Varnish y Nginx en tu servidor. Puedes usar el gestor de paquetes de tu sistema operativo o descargar los binarios desde las páginas oficiales de Varnish y Nginx.

Configura Nginx para servir los archivos estáticos. En el archivo de configuración de Nginx, agrega un bloque de servidor para el dominio que utilizarás como CDN y define la ruta de los archivos estáticos. Puedes utilizar la siguiente configuración como punto de partida:

    server {
        listen 80;
        server_name cdn.example.com;
        location / {
            root /var/www/cdn.example.com;
            expires 1d;
        }
    }

En este ejemplo, los archivos estáticos se encuentran en /var/www/cdn.example.com y se establece una caducidad de 1 día para los mismos.

Configura Varnish para cachear los archivos estáticos. En el archivo de configuración de Varnish, agrega una regla para que Varnish cachee las solicitudes a la ruta definida en Nginx. Puedes utilizar la siguiente configuración como punto de partida:

    backend default {
        .host = "127.0.0.1";
        .port = "8080";
    }

    sub vcl_recv {
        if (req.url ~ "\.(png|gif|jpg|jpeg|js|css)$") {
            return (hash);
        }
    }

    sub vcl_backend_response {
        set beresp.ttl = 1d;
    }

    sub vcl_deliver {
        set resp.http.Cache-Control = "max-age=86400";
    }

En este ejemplo, se define que Varnish se conecte a Nginx en 127.0.0.1:8080 y se establece una regla para cachear las solicitudes a archivos con extensiones png, gif, jpg, jpeg, js o css. También se establece un tiempo de vida (TTL) de 1 día para las respuestas del backend y se agrega una cabecera Cache-Control con un tiempo de vida de 1 día en las respuestas entregadas.

Configura Minio para almacenar los archivos en la nube. Puedes instalar Minio en el mismo servidor o en un servidor diferente. En el archivo de configuración de Minio, define una política de acceso que permita a Varnish acceder a los archivos almacenados. Puedes utilizar la siguiente configuración como punto de partida:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "AWS": "*"
                },
                "Action": [
                    "s3:GetObject"
                ],
                "Resource": [
                    "arn:aws:s3:::cdn.example.com/*"
                ],
                "Condition": {
                    "IpAddress": {
                        "aws:SourceIp": [
                            "127.0.0.1/32",
                            "::1/128"
                        ]
                    }
                }
            }
        ]
    }

En este ejemplo, se define una política de acceso que permite la acción s3:GetObject en los recursos que coinciden con el patrón arn:aws:s3:::cdn.example.com/*. También se establece una condición para limitar el acceso a las direcciones IP 127.0.0.1 y ::1, que corresponden a la dirección IP del servidor local.

Configura Varnish para obtener los archivos de Minio. En el archivo de configuración de Varnish, agrega una regla para que Varnish obtenga los archivos de Minio en caso de que no se encuentren en la caché. Puedes utilizar la siguiente configuración como punto de partida:

    backend minio {
        .host = "minio.example.com";
        .port = "9000";
        .username = "accesskey";
        .password = "secretkey";
        .path_prefix = "/cdn.example.com";
    }

    sub vcl_backend_fetch {
        set bereq.url = regsub(bereq.url, "^/", "/cdn.example.com/");
    }

    sub vcl_hash {
        if (req.url ~ "^/cdn.example.com/") {
            hash_data(req.url);
        }
    }

En este ejemplo, se define un backend llamado minio que se conecta a Minio en minio.example.com:9000 utilizando las credenciales accesskey y secretkey. También se define un prefijo de ruta cdn.example.com para acceder a los archivos almacenados en Minio. Se establece una regla en vcl_backend_fetch para que Varnish solicite los archivos a Minio en caso de que no se encuentren en la caché, y una regla en vcl_hash para que se utilice la URL completa, incluyendo el prefijo de ruta, al generar la clave de caché.

Con estos pasos, habrás creado un CDN utilizando Varnish, Nginx y Minio. Ahora puedes apuntar tu sitio web a cdn.example.com para utilizar los archivos estáticos almacenados en la caché de Varnish o en Minio, según corresponda. Además, puedes configurar Varnish y Nginx para utilizar certificados SSL y asegurar la comunicación entre el cliente y el servidor.