|

Nginx 1.30 con GeoIP2 en Alpine Docker, sin compilar

Para correr Nginx 1.30 GeoIP2 Alpine Docker sin compilar nada a mano, el truco que publicó el desarrollador crow004 en dev.to es forzar el repositorio edge de Alpine para traer el paquete nginx-mod-http-geoip2 binario-compatible, y copiar los entrypoints oficiales de Nginx desde otra imagen base. Resultado: geolocalización MaxMind en tiempo real con una imagen liviana, sin build-essential ni dolores de cabeza de dependencias.

En 30 segundos

  • Alpine stable (hasta la 3.23) clava Nginx en versiones viejas; el repo edge tiene Nginx 1.30 y su módulo GeoIP2.
  • La línea clave es apk add --no-cache -U -X http://dl-cdn.alpinelinux.org/alpine/edge/main nginx nginx-mod-http-geoip2.
  • El módulo GeoIP2 usa la base GeoLite2 de MaxMind (cuenta gratuita) para geolocalizar por IP.
  • El multi-stage copia /docker-entrypoint.sh y /docker-entrypoint.d desde la imagen oficial de Nginx.
  • Ojo con proxy_http_version 2.0 hacia upstream: el autor lo menciona, pero no es funcionalidad estándar del Nginx open source. Tomalo con pinzas.

Actualizar un reverse proxy en producción a veces es un jueguito del gato y el ratón con el package manager. Querés una versión nueva, el repo estable no la tiene, y compilar módulos dinámicos adentro de un build multi-stage termina siendo un infierno de dependencias. El método que vamos a ver evita todo eso.

GeoIP2 en Nginx es un módulo dinámico que lee la base de datos MaxMind y expone variables como $geoip2_data_country_iso_code para tomar decisiones según la ubicación de cada visitante. Sirve para rutear por región, bloquear países o servir contenido distinto según geografía, todo dentro del propio Nginx.

Por qué Nginx 1.30 con GeoIP2 importa para streaming en vivo

Ponele que armás un gateway para una plataforma de streaming en vivo y necesitás dos cosas a la vez: geolocalizar al usuario para cumplir restricciones de licencia por país, y mover protocolos modernos con la menor latencia posible. Ahí es donde el combo Nginx reciente más GeoIP2 se vuelve interesante.

El problema concreto que describe el autor: las releases estándar de Alpine, hasta la 3.23, clavan los paquetes estables de Nginx en versiones más viejas. Si querés la 1.30 desde el package manager (sin compilar), el repo estable no te la da. Cubrimos ese tema en detalle en automatizar despliegues de Docker.

Los casos de uso reales son varios. Edge routing en una CDN, gateways seguros, y aplicaciones con restricción geográfica donde necesitás saber el país del visitante antes de dejar pasar la request. En todos, meter la lógica de geo en el reverse proxy te ahorra una capa de aplicación.

Requisitos previos y compatibilidad

Antes de copiar y pegar el Dockerfile, chequeá esto:

  • Docker con soporte multi-stage (cualquier versión moderna lo tiene).
  • Conocimiento básico de Dockerfiles con varias etapas. Si nunca hiciste un COPY --from=, leé eso primero.
  • Una cuenta gratuita de MaxMind para bajar la base GeoLite2.
  • Las dependencias críticas en runtime: libmaxminddb y la libc.musl de Alpine.

Una advertencia importante: Alpine edge es cutting-edge, no es LTS. No tiene soporte de largo plazo y los paquetes se mueven seguido. Y regla de oro: no mezcles módulos compilados contra una versión de Nginx con un binario de Nginx distinto. Si el .so del módulo no coincide con la versión exacta del server, no carga y chau.

Alpine stable vs Alpine edge: cuándo usar cada uno

La diferencia es simple pero define todo el approach. Estable prioriza que nada se rompa; edge prioriza tener lo último.

AspectoAlpine stable (3.23)Alpine edge
Versión de NginxVersiones más antiguas del branch estableNginx 1.30+
EstabilidadAlta, pensada para producciónVariable, rolling
Ciclo de updatesLento y predecibleContinuo, casi diario
SoporteBranch con mantenimiento definidoSin garantías de LTS
Recomendado paraImágenes base de producciónTraer paquetes puntuales recientes
nginx 1.30 geoip2 alpine docker diagrama explicativo

La movida elegante no es correr toda tu imagen sobre edge. Es usar edge solo para traer el paquete que necesitás, y mantener el resto sobre una base sólida.

Accediendo al repositorio edge desde el Dockerfile

Acá viene el corazón del asunto. La sintaxis para instalar Nginx 1.30 y su módulo GeoIP2 tirando del repo edge es esta: Más contexto en elegir herramienta de despliegue.

RUN apk add --no-cache -U \
 -X http://dl-cdn.alpinelinux.org/alpine/edge/main \
 nginx nginx-mod-http-geoip2 libmaxminddb

¿Qué hace cada flag? -X agrega un repositorio extra solo para esa instalación, sin tocar tus repos por defecto. -U actualiza el índice de paquetes antes de instalar. Y --no-cache evita dejar el cache de apk en la capa, así la imagen pesa menos.

El punto es que con -X apuntás a edge/main de forma quirúrgica: Nginx 1.30 viene de ahí, pero el resto de tu sistema sigue en la base que elegiste.

Configurando GeoIP2 y MaxMind

Instalado el módulo, hay que cargarlo y darle la base de datos. El módulo queda en /usr/lib/nginx/modules como un archivo .so. Lo cargás en el contexto principal del config:

load_module modules/ngx_http_geoip2_module.so;

http {
 geoip2 /etc/nginx/geoip/GeoLite2-Country.mmdb {
 $geoip2_data_country_iso_code country iso_code;
 $geoip2_data_country_name country names en;
 }
}

La base GeoLite2-Country la bajás de MaxMind con una cuenta gratis. Con la variable $geoip2_data_country_iso_code ya podés armar un map para bloquear o rutear. Ejemplo concreto: mandar a un backend distinto si el ISO es AR, o devolver un 403 a países fuera de tu licencia.

Un detalle que muerde a todos: testear geo desde localhost no sirve, porque 127.0.0.1 no está en ninguna base de país. Probalo con una IP pública real o detrás de una VPN. Lo explicamos a fondo en servir contenido por ubicación.

HTTP/2, streaming y la parte que conviene mirar con lupa

El autor dice que necesitaba proxy_http_version 2.0 para arquitecturas de streaming en tiempo real. Acá te freno un segundo.

Nginx open source soporta HTTP/2 del lado del cliente sin drama (el clásico listen 443 ssl; http2 on;). Pero HTTP/2 hacia el upstream, que es lo que sugiere proxy_http_version 2.0, no es una funcionalidad estándar del Nginx libre. Habría que ver con qué build exacto lo logró. Si tu objetivo es streaming, lo que sí te conviene confirmar es HTTP/2 o HTTP/3 hacia el cliente y un buen tuning de buffers y keep-alive, que es donde se gana latencia de verdad.

Para HLS, que parte el video en segmentos servidos por HTTP, multiplexar sobre HTTP/2 del lado cliente ayuda. Para RTMP necesitás otro módulo distinto. No los confundas.

Dockerfile multi-stage: el esqueleto

La idea del multi-stage es traer una etapa official (la imagen oficial de Nginx) solo para robarle los scripts de arranque, y construir tu runtime sobre Alpine instalando desde edge. Así te quedás con los entrypoints probados sin arrastrar peso de más.

FROM nginx:1.30-alpine AS official

FROM alpine:3.23
RUN apk add --no-cache -U -X http://dl-cdn.alpinelinux.org/alpine/edge/main \
 nginx nginx-mod-http-geoip2 libmaxminddb

COPY --from=official /docker-entrypoint.sh /
COPY --from=official /docker-entrypoint.d /docker-entrypoint.d

RUN mkdir -p /etc/nginx/templates /var/cache/nginx /var/log/nginx \
 /etc/nginx/conf.d /usr/lib/nginx/modules /etc/nginx/modules \
 && chown -R nginx:nginx /var/cache/nginx /var/log/nginx /etc/nginx

ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

Como base sobre Alpine, la imagen final queda en el orden de las pocas decenas de megabytes, sin el build-essential que te inflaría todo si compilaras a mano. Si vas a desplegar esto sobre un VPS o cloud y buscás infraestructura confiable en Argentina, donweb.com tiene opciones para correr contenedores sin complicarte.

Errores comunes (y cómo zafar)

  • El módulo no carga. Casi siempre es mismatch de versión: el .so se compiló contra otra build de Nginx. Verificá con nginx -T que el server y el módulo salgan del mismo repo edge.
  • GeoIP devuelve vacío. O estás testeando desde localhost, o la base .mmdb no está montada en la ruta que pusiste en el config. Revisá el path exacto.
  • Base de MaxMind desactualizada. GeoLite2 cambia seguido. Si no la refrescás cada tanto, vas a geolocalizar mal IPs reasignadas. Automatizá la descarga.
  • Pinear todo a edge. Correr la imagen entera sobre edge en producción es buscarse problemas. Usá -X solo para el paquete puntual.

Preguntas Frecuentes

¿Cómo actualizar Nginx a la versión 1.30 en Alpine dentro de Docker?

Usá el flag -X de apk apuntando al repositorio edge: apk add --no-cache -U -X http://dl-cdn.alpinelinux.org/alpine/edge/main nginx. Eso trae Nginx 1.30 sin tocar tus repos por defecto ni compilar nada. Estable, hasta la 3.23 de Alpine, no ofrece esa versión. Esto se conecta con lo que analizamos en ejecutar servicios sin API.

¿Cómo agregar soporte GeoIP2 a Nginx en un contenedor?

Instalá el paquete nginx-mod-http-geoip2 junto con libmaxminddb desde el mismo repo edge, cargá el módulo con load_module y montá la base GeoLite2 de MaxMind. Después accedés a la ubicación con variables como $geoip2_data_country_iso_code.

¿Cuál es la diferencia entre Alpine stable y edge para Nginx?

Stable (3.23) prioriza estabilidad y trae versiones de Nginx más conservadoras; edge es rolling y tiene Nginx 1.30 y módulos recientes, pero sin garantía de soporte largo. Para producción, lo sano es usar una base estable y tirar de edge solo para el paquete puntual.

¿Por qué usar un Dockerfile multi-stage para esto?

El multi-stage te deja copiar los entrypoints oficiales de Nginx (/docker-entrypoint.sh y /docker-entrypoint.d) desde la imagen oficial sin arrastrar su peso completo, mientras construís el runtime sobre Alpine instalando desde edge. La imagen final queda liviana y sin herramientas de compilación.

¿GeoIP2 funciona si lo pruebo desde localhost?

No. Las direcciones como 127.0.0.1 y las IP privadas no figuran en las bases de país de MaxMind, así que las variables vuelven vacías. Tenés que probar con una IP pública real o usando una VPN para validar la geolocalización.

Conclusión

El aporte real del método de crow004 no es magia: es dejar de pelear con la compilación manual y usar el package manager como corresponde. Forzás edge para un paquete concreto, copiás los entrypoints que ya funcionan, y te queda una imagen liviana con GeoIP2 nativo.

Eso sí: validá vos mismo la parte de HTTP/2 hacia upstream antes de prometérsela a nadie, porque no es estándar en Nginx open source. Y si vas a edge, hacelo a propósito y acotado, nunca para toda la imagen en producción. Con esas dos salvedades, es una receta limpia para geolocalizar tráfico sin inflar el contenedor.

Fuentes

Te puede interesar...