Hosting GeoServer behind a Reverse Proxy and CDN
Published
I thought it would be fun to serve geo-tagged photos and GPX track data over a WMS/WFS interface with GeoServer. This turned out to be quite challenging to run GeoServer behind a reverse proxy, and with a context path (e.g. /api/geoserver/
).
After a lot of trial and error, the configuration documented below ultimately worked for me 🙂
Goal
My goal was for GeoServer to be accessible from https://mysite.com/api/geoserver
. I was hoping to run the service in a Docker container, and add a CDN and Apache reverse proxy in-front to help with caching.
Challenges
I faced several challenges configuring the base and context URLs inside GeoServer, as well as some general issues with the Admin interface.
Setting the Base URL and Context Path
GeoServer needs to know where it is running so that the URLs and redirects it generates are valid. For example, redirecting to an internal URL like http://192.168.1.x/api/geoserver
would break the application for the end user.
In my case, the base URL was https://mysite.com/
, and the context path was /api/geoserver
.
Depending on how you’re hosting GeoServer, configuring these URLs in multiple places may be required. For example, the Global “Proxy Base URL” setting will set the URL for OGC output, but user login redirects for the admin interface may need to be configured in Tomcat XML configuration files.
Recommendation: use the kartoza/docker-geoserver Docker image, which makes it simple to configure the base URL and context path as part of the docker run
command, for example:
docker run -p 8881:8080
--env GEOSERVER_CONTEXT_ROOT=api#geoserver
--env HTTP_PROXY_NAME="mysite.com"
--env HTTP_PROXY_PORT=443
--env HTTP_SCHEME=https
kartoza/geoserver
Admin UI CORS Errors
The GeoServer Admin interface employs CSRF security checks during form POSTs, which were breaking for me during certain operations like Adding a new Layer. Recommendations online were to disable to CSRF checks, or provide a domain whitelist.
Oddly I also found the admin interface was much more stable when running in an incognito window.
Configuring the CDN
Fortunately the CDN configuration was straight-forward and mostly a matter of configuring when to pass along headers/cookies/query string parameters.
/api/geoserver/*/wms
– WMS calls – trying to cache these requests, I only passed theHost
,Origin
, andReferer
headers back, along with all query strings (used by OGC calls)/api/geoserver/*/ogc
– WFS calls – same configuration as #1./api/geoserver/*
– GeoSever Admin Interface – I disabled all caching on this behavior, and passed all headers/cookies/query string parameters back to the origin server.
Important: make sure the rules #1 and #2 are evaluated by the CDN before #3, otherwise the requests will not be cached. In CloudFront, this is done by making sure #1 and #2 appear in the list above #3.
Configuring the Apache Reverse Proxy
The reverse proxy configuration was minimal, and forwarded incoming requests back to the Docker container, which was listening on port 8881
.
# configure reverse proxy to geoserver docker container
ProxyPass /api/geoserver http://127.0.0.1:8881/api/geoserver
ProxyPassReverse /api/geoserver http://127.0.0.1:8881/api/geoserver
# optional for CORS support
<LocationMatch /api/geoserver>
Header set Access-Control-Allow-Origin "*"
</LocationMatch>
Running the GeoServer Docker Container
As mentioned above, I used the kartoza/docker-geoserver image. It was extremely flexible and allowed for the specific URL configuration that I needed.
docker run -e GEOSERVER_ADMIN_USER=admin -e GEOSERVER_ADMIN_PASSWORD=geoserver --name geoserver
--mount type=bind,src=/local/os/path/geoserver/data,target=/opt/geoserver/data_dir -p 8881:8080
--env GEOSERVER_CONTEXT_ROOT=api#geoserver
--env HTTP_PROXY_NAME="mysite.com"
--env HTTP_PROXY_PORT=443
--env HTTP_SCHEME=https
kartoza/geoserver
Next Steps
Now that my GeoServer instance is available, I will begin to load it with data and publish layers. I am excited to experiment with updating data via WFS Transactions.
In addition to the fun stuff, I should better secure the GeoServer instance by changing the default user/password, and configuring the instance so that it is only accessing from certain machines via an IP allow-list.
Comments
No responses yet