- Kartoza docker-geoserver
- Getting the image
- Environment Variables
- Default installed extensions
- Using sample data
- Enable disk quota storage in PostgreSQL backend
- Activating JNDI PostgreSQL connector
- Running under SSL
- Proxy Base URL
- Removing Tomcat extras
- Upgrading image to use a specific version
- Installing extra fonts
- Other Environment variables supported
- Control flow properties
- Changing GeoServer password and username
- Changing GeoServer deployment context-root
- Mounting Configs
- Clustering using JMS Plugin
- Running the Image
- Kubernetes (Helm Charts)
- Contributing to the image
- Support
- Credits
- A simple docker container that runs GeoServer influenced by this docker recipe.
- The image has environment variables that allow users to configure GeoServer based on running-in-production
- The image uses kartoza/postgis as a database backend. You can use any other PostgreSQL image but adjust the environment variables accordingly.
There are various ways to get the image onto your system:
- Pulling from Dockerhub
- Local build using docker-compose
The preferred way (but using the most bandwidth for the initial image) is to get our docker-trusted build like this:
VERSION=2.25.2
docker pull kartoza/geoserver:$VERSION
Note Although the images are tagged and backed by unit tests
it is recommended to use tagged versions with dates i.e.
kartoza/geoserver:$VERSION--v2024.03.31
.The first date available
from dockerhub
It would be the first version for that series. Successive builds that fix issues
tend to override the tagged images and also produce dated images.
To build yourself with a local checkout using the docker-compose-build.yml:
-
Clone the GitHub repository:
git clone https://github.com/kartoza/docker-geoserver
-
Edit the build arguments in the
.env
file: -
Build the container and spin up the services
cd docker-geoserver docker-compose -f docker-compose-build.yml up -d geoserver-prod --build
To build using a specific tagged release of the tomcat image set the
IMAGE_VERSION
build arg:
See the dockerhub tomcat
for available tags.
VERSION=2.25.2
IMAGE_VERSION=9.0.91-jdk11-temurin-focal
docker build --build-arg IMAGE_VERSION=${IMAGE_VERSION} --build-arg GS_VERSION=${VERSION} -t kartoza/geoserver:${VERSION} .
For some recent builds, it is necessary to set the JAVA_PATH as well (e.g. Apache Tomcat/9.0.36)
docker build --build-arg IMAGE_VERSION=9.0.91-jdk11-temurin-focal --build-arg JAVA_HOME=/usr/local/openjdk-11/bin/java --build-arg GS_VERSION=2.25.2 -t kartoza/geoserver:2.25.2 .
Note: Please check the GeoServer documentation to see which Tomcat versions are supported.
The current build uses the base image tomcat:9.0.91-jdk11-temurin-focal
because of the dependency on
libgdal-java
. The tomcat base images > focal will not
have the java bindings for the GDAL plugin
hence the container will not support the gdal plugin working if you build using base image > focal.
These instructions detail the recommended process for reliably building this on Windows.
Prerequisites - You will need to have this software preinstalled on the system being used to build the Geoserver image:
Add the conda-forge channel to your conda installation:
conda config --add channels conda-forge
Now create a new conda environment with GDAL, installed from conda. Ensure that this environment is active when running the docker build, e.g.
conda create -n geoserver-build -c conda-forge python gdal
conda activate geoserver-build
Modify the .env
with the appropriate environment variables. It is recommended that short paths (without whitespace)
are used with forward slashes to prevent errors. You can get the current Java command short path with PowerShell:
(New-Object -ComObject Scripting.FileSystemObject).GetFile((get-command java).Source).ShortPath
Running the above command should yield a path similar to C:/PROGRA~1/Java/JDK-15~1.2/bin/java.exe
, which can be
assigned to JAVA_HOME
in the environment configuration file.
Then run the docker build commands. If you encounter issues, you may want to ensure that you try to build the image without the cache and then run docker up separately:
docker-compose -f docker-compose-build.yml build --force-rm --no-cache
docker-compose -f docker-compose-build.yml up -d
A full list of environment variables are specified in the .env file
The image activates the default_stable_extensions listed below on container start:
- vectortiles-plugin
- wps-plugin
- libjpeg-turbo-plugin
- control-flow-plugin
- pyramid-plugin
- gdal-plugin
- monitor-plugin
- inspire-plugin
- csw-plugin
If you wish to exclude any of the default activated plugins you will need to set
ACTIVE_EXTENSIONS=${Default_extension} - skipped_default_extension
i.e.
ACTIVE_EXTENSIONS=control-flow-plugin,csw-iso-plugin,csw-plugin,gdal-plugin,inspire-plugin,monitor-plugin,pyramid-plugin,vectortiles-plugin,wps-plugin
will skip activating libjpeg-turbo-plugin.
The variable ACTIVE_EXTENSIONS
is used to specify a set of plugins to enable, if left empty or unset the following
will be enabled : list of default plugins
The environment variable STABLE_EXTENSIONS
is used to activate extensions listed in
stable_plugins
Note: The plugins listed in the url is of the format geoserver-2.25.2-wps-plugin.zip
, but the env
variable expects the env to be of the format wps-plugin
. Always consult the url to see which plugins
are available. The text file stable_plugins.txt
contains a curated list of plugins but might be out of date in some cases.
Example
ie VERSION=2.25.2
docker run -d -p 8600:8080 --name geoserver -e STABLE_EXTENSIONS=charts-plugin,db2-plugin kartoza/geoserver:${VERSION}
You can pass any comma-separated extensions as defined in stable_plugins
The environment variable COMMUNITY_EXTENSIONS
can be used to activate extensions listed in
community_plugins
Note: The plugins listed in the url is of the format geoserver-2.25-SNAPSHOT-cog-http-plugin.zip
, but the env
variable expects the env to be of the format cog-http-plugin
. Always consult the url to see which plugins
are available. The text file community_plugins.txt
contains a curated list of community plugins but might be out of date in some cases.
Example
ie VERSION=2.25.2
docker run -d -p 8600:8080 --name geoserver -e COMMUNITY_EXTENSIONS=gwc-sqlite-plugin,ogr-datastore-plugin kartoza/geoserver:${VERSION}
The image ships with extension zip files pre-downloaded. You can pass an additional environment variable
FORCE_DOWNLOAD_COMMUNITY_EXTENSIONS=true
to download the latest community extensions during the initialisation of the container.
Note: If you experience an issue running community extensions please check upstream before reporting the issue here. If an extension is no longer available you can build the extensions following the guidelines from GeoServer develop guidelines
The image ships with sample data. This can be used to familiarize yourself with GeoServer. This is not activated by default. You can activate it using the environment variable boolean SAMPLE_DATA
.
ie VERSION=2.25.2
docker run -d -p 8600:8080 --name geoserver -e SAMPLE_DATA=true kartoza/geoserver:${VERSION}
GeoServer defaults to using HSQL datastore for configuring disk quota. You can alternatively use a PostgreSQL backend as a disk quota store. When using a PostgreSQL backend, you need to have a running instance of the database which can be connected to.
If you want to test it locally with docker-compose postgres db you need to specify these env variables:
DB_BACKEND=POSTGRES
HOST=db
POSTGRES_PORT=5432
POSTGRES_DB=gwc
POSTGRES_USER=${POSTGRES_USER}
POSTGRES_PASS=${POSTGRES_PASS}
SSL_MODE=allow
POSTGRES_SCHEMA=public
DISK_QUOTA_SIZE=5
When the environment variable FORCE_SSL=TRUE
is set for the database container you
will need to set SSL_MODE=allow
in the GeoServer container.
When the environment variable FORCE_SSL=TRUE
is set for the database container you
will need to set SSL_MODE
to either verify-full
or verify-ca
for the GeoServer container. You will also need to mount the SSL certificates
you have done in the DB.
In the GeoServer container, the certificates need to be mounted to the folder specified by the certificate directory ${CERT_DIR}
SSL_CERT_FILE=/etc/certs/fullchain.pem
SSL_KEY_FILE=/etc/certs/privkey.pem
SSL_CA_FILE=/etc/certs/root.crt
When defining vector stores you can use the JNDI pooling. To activate this, adjust the following environment
variable POSTGRES_JNDI=TRUE
. By default, the environment the
variable is set to FALSE
. Additionally, you will need to
define parameters to connect to an existing PostgreSQL database
POSTGRES_JNDI=TRUE
HOST=${POSTGRES_HOSTNAME}
POSTGRES_DB=${POSTGRES_DB}
POSTGRES_USER=${POSTGRES_USER}
POSTGRES_PASS=${POSTGRES_PASS}
When defining the parameters for the store in GeoServer you will need to set
jndiReferenceName=java:comp/env/jdbc/postgres
You can use the environment variables to specify whether you want to run the GeoServer under SSL. Credits to letsencrpt for the solution to run under SSL.
If you set the environment variable SSL=true
but do not provide the pem files (fullchain.pem
and privkey.pem
)
the container will generate self-signed SSL certificates.
ie VERSION=2.25.2
docker run -it --name geoserver -e PKCS12_PASSWORD=geoserver -e JKS_KEY_PASSWORD=geoserver -e JKS_STORE_PASSWORD=geoserver -e SSL=true -p 8443:8443 -p 8600:8080 kartoza/geoserver:${VERSION}
If you already have your perm files (fullchain.pem
and privkey.pem
) you can mount the directory containing your keys as:
ie VERSION=2.25.2
docker run -it --name geo -v /etc/certs:/etc/certs -e PKCS12_PASSWORD=geoserver -e JKS_KEY_PASSWORD=geoserver -e JKS_STORE_PASSWORD=geoserver -e SSL=true -p 8443:8443 -p 8600:8080 kartoza/geoserver:${VERSION}
You can also use a PFX
file with this image.
Rename your PFX file as certificate.pfx and then mount the folder containing
your pfx file. This will be converted to perm files.
Note When using PFX files make sure that the ALIAS_KEY
you specify as
an environment variable matches the ALIAS_KEY
that was used when generating
your PFX
key.
A full list of SSL variables is provided in SSL Settings
For the server to report a full proxy base URL, you need to pass the following env variable i.e.
HTTP_PROXY_NAME
HTTP_PROXY_PORT
If you are running GeoServer under SSL with reverse proxy i.e. nginx you will need to set the following env variables
Example below:
HTTP_PROXY_NAME=foo.org
HTTP_SCHEME=https
Note: if you're running this on Fargate behind a load balancer that already terminates SSL, you only need
HTTP_SCHEME=https
.
This will prevent the login form from sending insecure http post requests as experienced in login issue
For SSL-based connections, the env variables are:
HTTPS_PROXY_NAME
HTTPS_PROXY_PORT
HTTPS_SCHEME
To include Tomcat extras including docs, examples, and the manager web app, set the
TOMCAT_EXTRAS
environment variable to true
:
Note: If TOMCAT_EXTRAS
is set to true then you should configure TOMCAT_PASSWORD
to use a strong password otherwise a randomly generated password is used.
ie VERSION=2.25.2
docker run -it --name geoserver -e TOMCAT_EXTRAS=true -p 8600:8080 kartoza/geoserver:${VERSION}
Note: If TOMCAT_EXTRAS
is set to false, requests to the root webapp ("/") will return HTTP status code 404.
To issue a redirect to the GeoServer webapp ("/geoserver/web") set ROOT_WEBAPP_REDIRECT=true
If you are migrating your GeoServer instance, from a lower
version to a higher and do not need to update your master
password, you will need to set the variable EXISTING_DATA_DIR
.
You can set the env variable EXISTING_DATA_DIR
to any value i.e.
EXISTING_DATA_DIR=foo
or EXISTING_DATA_DIR=false
When the environment variable is set it will ensure that the password initialization is skipped
during the startup procedure.
If you have downloaded extra fonts you can mount the folder to the path
/opt/fonts
. This will ensure that all the .ttf
or .otf
files are copied to the correct
path during initialisation. This is useful for styling layers i.e. labeling using specific fonts.
ie VERSION=2.25.2
docker run -v fonts:/opt/fonts -p 8080:8080 -t kartoza/geoserver:${VERSION}
You can use the environment variable GOOGLE_FONTS_NAMES
to activate fonts defined in Google fonts
i.e.
ie VERSION=2.25.2
docker run -e GOOGLE_FONTS_NAMES=actor,akronim -p 8080:8080 -t kartoza/geoserver:${VERSION}
You can find a full list of environment variables in Generic Env variables
Note The list below is not exhaustive of all values available.
Always consult the .env
file to check possible values.
- GEOSERVER_DATA_DIR=
PATH
- ENABLE_JSONP=
true or false
- MAX_FILTER_RULES=
Any integer
- OPTIMIZE_LINE_WIDTH=
false or true
- FOOTPRINTS_DATA_DIR=
PATH
- GEOWEBCACHE_CACHE_DIR=
PATH
- GEOSERVER_ADMIN_PASSWORD=
password
- GEOSERVER_ADMIN_USER=
username
- GEOSERVER_FILEBROWSER_HIDEFS=
false or true
- XFRAME_OPTIONS=
"true"
- Based on Xframe-options - INITIAL_MEMORY=
size
: Initial Memory that Java can allocate, default2G
- MAXIMUM_MEMORY=
size
: Maximum Memory that Java can allocate, default4G
The control flow module manages requests in GeoServer. Instructions on what each parameter means can be read from documentation.
The following env variables can be set
REQUEST_TIMEOUT=60
PARALLEL_REQUEST=100
GETMAP=10
REQUEST_EXCEL=4
SINGLE_USER=6
GWC_REQUEST=16
WPS_REQUEST=1000/d;30s
You can pass the environment variables to change it on runtime.
GEOSERVER_ADMIN_PASSWORD
GEOSERVER_ADMIN_USER
The username and password are reinitialized each time the container starts. If you do not pass the env variables
GEOSERVER_ADMIN_PASSWORD
the container will generate a new password which is visible in the
startup logs.
Note: When upgrading the GEOSERVER_ADMIN_PASSWORD
and GEOSERVER_ADMIN_USER
you will
need to mount the volume settings:/settings
so that the lock-files generated by the update_password.sh
are
persistent during initialization. See the example in docker-compose-build
docker run --name "geoserver" -e GEOSERVER_ADMIN_USER=kartoza -e GEOSERVER_ADMIN_PASSWORD=myawesomegeoserver -p 8080:8080 -d -t kartoza/geoserver
Note: The docker-compose recipe uses the password myawesomegeoserver
. It is highly
recommended not to run the container in production using these values.
To avoid passing sensitive information in environment variables, _FILE
can be appended to
some variables to read from files present in the container. This is particularly useful
in conjunction with Docker secrets, as passwords can be loaded from /run/secrets/<secret_name>
e.g.:
- -e GEOSERVER_ADMIN_PASSWORD_FILE=/run/secrets/<geoserver_pass_secret>
For more information see https://docs.docker.com/engine/swarm/secrets/.
Currently, the following environment variables
GEOSERVER_ADMIN_USER
GEOSERVER_ADMIN_PASSWORD
S3_USERNAME
S3_PASSWORD
S3_SERVER_URL
S3_ALIAS
TOMCAT_USER
TOMCAT_PASSWORD
PKCS12_PASSWORD
JKS_KEY_PASSWORD
JKS_STORE_PASSWORD
TOMCAT_USER
are supported.
You can pass the environment variable to change the context-root at runtime, example:
GEOSERVER_CONTEXT_ROOT=my-geoserver
The example above will deploy Geoserver at https://host/my-geoserver instead of the default location at https://host/geoserver.
It is also possible to do a nested context-root. Apache Tomcat nested context-roots are specified via #.
GEOSERVER_CONTEXT_ROOT=foo#my-geoserver
The example above will deploy Geoserver at https://host/foo/my-geoserver instead of the default location at https://host/geoserver.
You can mount the config file to the path /settings
. These configs will
be used in favour of the defaults that are available from the Build data
directory
The configs that can be mounted are
- cluster.properties
- controlflow.properties
- embedded-broker.properties
- geowebcache-diskquota-jdbc.xml
- s3.properties
- tomcat-users.xml
- web.xml - for tomcat cors
- epsg.properties - for custom GeoServer EPSG values
- server.xml - for tomcat configurations
- broker.xml
- users.xml - for Geoserver users.
- roles.xml - To define roles users should have in GeoServer
- logging.properties - Controls logging to sdtout parameters
Example
docker run --name "geoserver" -e GEOSERVER_ADMIN_USER=kartoza -v /data/controlflow.properties:/settings/controlflow.properties -p 8080:8080 -d -t kartoza/geoserver
Note: The files users.xml
and roles.xml
should be mounted together to prevent errors
during container start. Mounting these two files will overwrite GEOSERVER_ADMIN_PASSWORD
and GEOSERVER_ADMIN_USER
You can run some bash script to correct some missing dependencies i.e. in community extension like cluster issue
-v ./run.sh:/docker-entrypoint-geoserver.d/run.sh
The image ships with CORS support. If you however need to modify the web.xml you
can mount web.xml
to /settings/
directory.
GeoServer supports clustering using the JMS cluster plugin.
You can read more about how to set up clustering in kartoza clustering
You can use the docker-compose-external.yml
in the clustering folder.
We provide a sample docker-compose.yml
file that illustrates
how you can establish a GeoServer + PostGIS.
If you are interested in the backups, add a section in the docker-compose.yml
following instructions from docker-pg-backup.
Start the services using:
docker-compose up -d
Note The username and password are specified in the .env
file. It is recommended
to change them into something more secure. If you do not pass the
env GEOSERVER_ADMIN_PASSWORD
the container generates a
random string which will be your password. This is visible from
the startup logs.
Once all the services start, test by visiting the GeoServer landing page in your browser: http://localhost:8600/geoserver.
You can also put Nginx in front of GeoServer to receive the http request and translate it to uwsgi.
A sample docker-compose-nginx.yml
is provided for running GeoServer and Nginx
docker-compose -f docker-compose-nginx.yml up -d
Once the services are running GeoServer will be available from
http://localhost/geoserver/web/
You can run the image in Kubernetes following the recipe
We welcome users who want to contribute to enriching this service. We follow the git principles and all pull requests should be against the develop branch so that we can test them and when we are happy we push them to the master branch.
GeoServer releases and bug fixes are done frequently. We provide a helper script
upgrade_geoserver_version.sh
which can be run to update the
respective files which mention the GeoServer version. To upgrade to
a new version involves:
- Run the upgrade script that updates some env variables.
- Update the github workflows files to. match the specific versions.
/bin/bash upgrade_geoserver_version.sh ${GS_VERSION} ${GS_NEW_VERSION}
Note: The script will also push these changes to the current repo, and it is up to the individual running the script to push the changes to his specific branch of choice and then complete the pull request
When reporting issues especially related to installed extensions (community and stable) please refer to the GeoServer Issue page to see if there are no issues reported there. We rely on the GeoServer community to resolve upstream issues. For urgent upstream problems, you will need to get paid support from the developers in GeoServer.
Other platforms where users can ask questions and get assistance are listed below:
If you require more substantial assistance from kartoza (because our work and interaction on docker-geoserver is pro bono), please consider taking out a Support Level Agreeement
- Tim Sutton (tim@kartoza.com)
- Shane St Clair (shane@axiomdatascience.com)
- Alex Leith (alexgleith@gmail.com)
- Admire Nyakudya (addloe@gmail.com)
- Gavin Fleming (gavin@kartoza.com)