GeoServer y PostGIS: la ruta VPN que importa es la del servidor
Que su portátil llegue a GeoServer no dice nada sobre si GeoServer llega a PostGIS. Compare los dos orígenes, la frontera de la caché y la propia fuente del almacén de datos.
Abre la capa en QGIS y se dibuja. Un colega en la misma VPN recibe un error para la misma capa. Alguien concluye que la VPN está rota, y la hora siguiente se va en mover una base de datos o en exponer un puerto que nunca necesitó ninguna de las dos cosas. La petición del escritorio y la consulta que GeoServer hace a PostGIS salen de máquinas distintas, en espacios de nombres de red distintos, con credenciales distintas. Separar esas dos rutas es la mayor parte del diagnóstico.
Dos conexiones, dos orígenes
QGIS -> client's permitted path (often the VPN) -> GeoServer listener
GeoServer -> server's permitted path -> PostGIS listener
La segunda flecha no hereda el túnel del primer ordenador. Un GeoServer en un contenedor tiene la pila de red del contenedor, no la del host, y un contenedor en una red puente puede alcanzar una base de datos que el host no alcanza, o al revés. Así, el mismo usuario puede acertar y fallar dentro de una misma sesión, según si la respuesta vino de la caché o de una consulta nueva.
| What you tested | What it proves |
|---|---|
Portal page or GetCapabilities | HTTP reachability to GeoServer only |
| A tile served from cache | nothing about the database |
GetMap for an uncached layer | a datastore query had to happen |
Encontrar el paso que falló de verdad
Un rechazo a nivel de servicio, una petición de imagen que no llega a su almacén de datos y un problema de permisos en una capa se parecen en una pestaña del navegador y son completamente distintos en el registro del servidor. Pida la operación concreta y luego lea el evento propio de GeoServer para la misma marca de tiempo.
curl -s -o /dev/null -w '%{http_code}\n' \
"https://gis.example.com/geoserver/wms?service=WMS&version=1.3.0&request=GetCapabilities"
curl -s -o /tmp/tile.png -w '%{http_code} %{size_download}\n' \
"https://gis.example.com/geoserver/wms?service=WMS&version=1.3.0&request=GetMap&layers=corp:parcels&bbox=-13650000,4500000,-13600000,4550000&width=256&height=256&srs=EPSG:3857&format=image/png"
Un 200 de la segunda petición con una imagen plausible demuestra que el almacén de datos respondió. Un 200 con un documento de excepción de servicio demuestra que no lo hizo, y el texto de la excepción suele nombrar el almacén y no el cliente.
Leer el almacén de datos desde el lado del servidor
La referencia de PostGIS de GeoServer enumera lo que necesita el almacén: host, puerto, base de datos y credenciales. Todo ello describe la conexión que abre GeoServer. Nada de ello describe un inicio de sesión del cliente de escritorio. Lea esos cuatro campos como una afirmación sobre el contexto de red del servidor, y toda la clase de tickets de «a ellos les funciona» se vuelve manejable.
Por eso localhost en un almacén de datos es un error tan común. Significa el contexto de red del propio proceso de GeoServer. Si GeoServer se ejecuta en Docker mientras PostGIS se ejecuta en el host, localhost apunta dentro del contenedor y no encuentra nada, y ninguna cantidad de configuración de VPN cambia eso.
En el servidor, compruebe la ruta, el listener y la política de autenticación en ese orden. La autenticación basada en host de PostgreSQL compara la dirección de origen que observa, que una pasarela puede traducir, así que añadir un grupo de VPN de clientes al archivo HBA rara vez arregla una conexión del lado del servidor. Pruebe como lo haría el servidor: mismo host, mismo puerto, mismo usuario. Si esa prueba sale bien mientras GeoServer sigue fallando, la diferencia está en el contexto del proceso y no en la base de datos.
ip route get 10.20.5.11
ss -tnp | grep 5432
psql "host=10.20.5.11 dbname=gis user=geoserver" -c 'select 1'
Los grupos y las cachés conservan estado entre cambios
Los grupos de conexiones del almacén de datos mantienen sockets abiertos. Un túnel que subió una hora después de crear el grupo no da necesariamente al grupo una ruta nueva, y una conexión inactiva puede quedarse en una ruta muerta hasta que una validación o un tiempo de espera la cierre. Consulte la configuración de validación del almacén instalado en lugar de suponer una recuperación, y evite la tentación de reiniciar todo el servicio antes de saber qué capa falló.
Las cachés de teselas crean la imagen inversa de ese problema: pueden servir un mapa de aspecto correcto mucho después de que se rompiera la conexión con la base de datos. Vaciar la caché para «ver si ayuda» destruye la única prueba que le habría dicho qué ruta estaba viva.
Pasar el caso nombrando los dos orígenes
La descripción que consigue un arreglo rápido nombra dos cosas: la petición del cliente que llegó a GeoServer y la operación de backend que GeoServer no pudo completar. Con ambas, el propietario correcto puede reparar la ruta que falló. Con solo la primera, el arreglo natural es exponer la base de datos públicamente, lo que resuelve el ticket creando un problema peor.
Anote la capa, el código de respuesta, la excepción del lado del servidor y el contenedor o host que la produjo. Son cuatro líneas, y eliminan la ambigüedad por completo.