From eee16c94e4a4fafdcb8b85b08f1583cb0efa6dbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20B=C3=BChner?= Date: Thu, 8 Oct 2020 14:11:24 +0200 Subject: [PATCH 01/11] Add first Dockerfile implementation --- .gitignore | 1 + Dockerfile | 57 +++++++++++++++++++++++++++++++++++ README.md | 53 ++++++++++++++++++++++++++++++-- scripts/entrypoint.sh | 25 +++++++++++++++ scripts/install-extensions.sh | 21 +++++++++++++ 5 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 scripts/entrypoint.sh create mode 100644 scripts/install-extensions.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bff2d76 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.iml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c27aa69 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,57 @@ +ARG TOMCAT_VERSION=9.0.38 +ARG JAVA_VERSION=8 +ARG IMAGE_VERSION=${TOMCAT_VERSION}-jdk${JAVA_VERSION}-openjdk-slim + +FROM tomcat:$IMAGE_VERSION + +ARG GS_VERSION=2.18.0 +ARG MARLIN_TAG=0_9_4_3 +ARG MARLIN_VERSION=0.9.4.3 + +ARG WAR_URL=https://downloads.sourceforge.net/project/geoserver/GeoServer/${GS_VERSION}/geoserver-${GS_VERSION}-war.zip +ARG STABLE_PLUGIN_URL=https://sourceforge.net/projects/geoserver/files/GeoServer/${GS_VERSION}/extensions + +# environment variables +ENV GS_VERSION=${GS_VERSION} \ + MARLIN_TAG=${MARLIN_TAG} \ + MARLIN_VERSION=${MARLIN_VERSION} \ + WAR_URL=${WAR_URL} \ + STABLE_PLUGIN_URL=${STABLE_PLUGIN_URL} \ + INITIAL_MEMORY="2G" \ + MAXIMUM_MEMORY="4G" \ + JAIEXT_ENABLED=true \ + STABLE_EXTENSIONS='' \ +# COMMUNITY_EXTENSIONS='' \ + DEBIAN_FRONTEND=noninteractive \ + EXTENSION_DOWNLOAD_DIR=/opt/geoserver_extension_downloads \ + GEOSERVER_DATA_DIR=/opt/geoserver_data \ + GEOWEBCACHE_CACHE_DIR=/opt/geowebcache_data + +RUN mkdir ${EXTENSION_DOWNLOAD_DIR} ${GEOSERVER_DATA_DIR} ${GEOWEBCACHE_CACHE_DIR} + +# install required dependencies +# also clear the initial webapps +RUN apt update && \ + apt install -y curl wget openssl zip fontconfig libfreetype6 && \ + rm -rf ${CATALINA_HOME}/webapps/* + +# install geoserver +RUN wget --progress=bar:force:noscroll -c --no-check-certificate "${WAR_URL}" -O /tmp/geoserver.zip && \ + unzip /tmp/geoserver.zip geoserver.war -d ${CATALINA_HOME}/webapps && \ + mkdir -p ${CATALINA_HOME}/webapps/geoserver && \ + unzip -q ${CATALINA_HOME}/webapps/geoserver.war -d ${CATALINA_HOME}/webapps/geoserver && \ + rm ${CATALINA_HOME}/webapps/geoserver.war + +# install marlin renderer +RUN wget --progress=bar:force:noscroll -c --no-check-certificate https://github.com/bourgesl/marlin-renderer/releases/download/v${MARLIN_TAG}/marlin-${MARLIN_VERSION}-Unsafe.jar -O ${CATALINA_HOME}/lib/marlin-${MARLIN_VERSION}-Unsafe.jar + +# copy scripts +COPY scripts /scripts +RUN chmod +x /scripts/*.sh + +# cleanup +RUN apt clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +WORKDIR ${CATALINA_HOME} + +CMD ["/bin/sh", "/scripts/entrypoint.sh"] diff --git a/README.md b/README.md index 0d2e45c..07818f4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,51 @@ -# docker -GeoServer docker image +# Docker GeoServer image + +This docker GeoServer image is based on the following proposal: + +https://github.com/geoserver/geoserver/wiki/GSIP-192 + +Work is still in progress! + +## How it works + +1. The [Dockerfile](Dockerfile) + 1. installs dependencies + 1. installs the GeoServer by downloading and extracting the war file + 1. installs the marlin renderer + 1. defines defaults for environment variables +1. The [entrypoint.sh](scripts/entrypoint.sh) startup script (in a running container) + 1. executes [install-extensions.sh](scripts/install-extensions.sh) to download and install GeoServer extensions based on the `STABLE_EXTENSIONS` environment variable. + 1. handles the `GEOSERVER_OPTS` + 1. starts the tomcat + +## Building + +`docker build -t geoserver:test .` + +## Running + +`docker run -it -e STABLE_EXTENSIONS='wps,csw' -p 8080:8080 geoserver:test` + +The extensions will be downloaded on startup of the image (before starting the tomcat). + +## Configuration + +Pass as environment variables. If not passed, the default values will be used. + +* `GEOSERVER_DATA_DIR` (default: /opt/geoserver_data) +* `INITIAL_MEMORY` (default: 2G) +* `MAXIMUM_MEMORY` (default: 4G) +* `JAIEXT_ENABLED` (default: true) +* `STABLE_EXTENSIONS` as comma separated list, will be downloaded and installed on startup (default: "") + +## TODOs + +* CORS +* configuration of JNDI connections in the tomcat/custom tomcat configuration in general +* default data for gs datadir? +* possibility to add custom java dependencies (for example the oracle jdbc driver) + * in this context: mount `EXTENSION_DOWNLOAD_DIR` and implement checks to cache extensions that have already been downloaded before? +* log4j properties +* add possibility to add custom fonts +* starting from which version we want to provide geoserver images (maybe 2.15.x?)/backwards compatability +* add a docker-compose demo environment? diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh new file mode 100644 index 0000000..d329090 --- /dev/null +++ b/scripts/entrypoint.sh @@ -0,0 +1,25 @@ +#!/bin/bash +## Inspired by https://github.com/kartoza/docker-geoserver +set -e + +## install GeoServer extensions before starting the tomcat +echo "Starting installation of extensions" +/scripts/install-extensions.sh +echo "\nFinished installation of extensions" + +export GEOSERVER_OPTS="-Djava.awt.headless=true -server \ + -Dfile.encoding=UTF8 \ + -Djavax.servlet.request.encoding=UTF-8 \ + -Djavax.servlet.response.encoding=UTF-8 \ + -Xms${INITIAL_MEMORY} -Xmx${MAXIMUM_MEMORY} \ + -XX:SoftRefLRUPolicyMSPerMB=36000 -XX:+UseG1GC \ + -XX:MaxGCPauseMillis=200 -XX:ParallelGCThreads=20 -XX:ConcGCThreads=5 \ + -Xbootclasspath/a:${CATALINA_HOME}/lib/marlin-${MARLIN_VERSION}-Unsafe.jar \ + -Dsun.java2d.renderer=org.marlin.pisces.MarlinRenderingEngine \ + -Dorg.geotools.coverage.jaiext.enabled=${JAIEXT_ENABLED}" + +## JVM command line arguments +export JAVA_OPTS="${JAVA_OPTS} ${GEOSERVER_OPTS}" + +## Start the tomcat +exec /usr/local/tomcat/bin/catalina.sh run diff --git a/scripts/install-extensions.sh b/scripts/install-extensions.sh new file mode 100644 index 0000000..00f2bf6 --- /dev/null +++ b/scripts/install-extensions.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# Inspired by https://github.com/kartoza/docker-geoserver + +function download_extension() { + URL=$1 + EXTENSION=$2 + if curl --output /dev/null --silent --head --fail "${URL}"; then + DOWNLOAD_FILE="${EXTENSION_DOWNLOAD_DIR}/geoserver-${GS_VERSION}-${EXTENSION}-plugin.zip" + echo -e "\nDownloading ${EXTENSION}-extension from ${URL}" + wget --progress=bar:force:noscroll -c --no-chec k-certificate "${URL}" -O ${DOWNLOAD_FILE} + unzip -q -o ${DOWNLOAD_FILE} -d ${CATALINA_HOME}/webapps/geoserver/WEB-INF/lib + else + echo "URL does not exist: ${URL}" + fi +} + +# Install stable plugins +for EXTENSION in $(echo "${STABLE_EXTENSIONS}" | tr ',' ' '); do + URL="${STABLE_PLUGIN_URL}/geoserver-${GS_VERSION}-${EXTENSION}-plugin.zip" + download_extension ${URL} ${EXTENSION} +done From a03ee5ae96870907c0b0e89e3b21a1c8351575d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20B=C3=BChner?= Date: Thu, 17 Dec 2020 16:52:53 +0100 Subject: [PATCH 02/11] Switch to OpenJDK 11 --- .gitignore | 2 ++ Dockerfile | 16 ++-------------- README.md | 1 - scripts/entrypoint.sh | 4 +--- 4 files changed, 5 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index bff2d76..92bc551 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ *.iml +*.idea + diff --git a/Dockerfile b/Dockerfile index c27aa69..152a6bd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,27 +1,18 @@ -ARG TOMCAT_VERSION=9.0.38 -ARG JAVA_VERSION=8 -ARG IMAGE_VERSION=${TOMCAT_VERSION}-jdk${JAVA_VERSION}-openjdk-slim +FROM tomcat:jdk11-openjdk-slim -FROM tomcat:$IMAGE_VERSION - -ARG GS_VERSION=2.18.0 -ARG MARLIN_TAG=0_9_4_3 -ARG MARLIN_VERSION=0.9.4.3 +ARG GS_VERSION=2.18.1 ARG WAR_URL=https://downloads.sourceforge.net/project/geoserver/GeoServer/${GS_VERSION}/geoserver-${GS_VERSION}-war.zip ARG STABLE_PLUGIN_URL=https://sourceforge.net/projects/geoserver/files/GeoServer/${GS_VERSION}/extensions # environment variables ENV GS_VERSION=${GS_VERSION} \ - MARLIN_TAG=${MARLIN_TAG} \ - MARLIN_VERSION=${MARLIN_VERSION} \ WAR_URL=${WAR_URL} \ STABLE_PLUGIN_URL=${STABLE_PLUGIN_URL} \ INITIAL_MEMORY="2G" \ MAXIMUM_MEMORY="4G" \ JAIEXT_ENABLED=true \ STABLE_EXTENSIONS='' \ -# COMMUNITY_EXTENSIONS='' \ DEBIAN_FRONTEND=noninteractive \ EXTENSION_DOWNLOAD_DIR=/opt/geoserver_extension_downloads \ GEOSERVER_DATA_DIR=/opt/geoserver_data \ @@ -42,9 +33,6 @@ RUN wget --progress=bar:force:noscroll -c --no-check-certificate "${WAR_URL}" -O unzip -q ${CATALINA_HOME}/webapps/geoserver.war -d ${CATALINA_HOME}/webapps/geoserver && \ rm ${CATALINA_HOME}/webapps/geoserver.war -# install marlin renderer -RUN wget --progress=bar:force:noscroll -c --no-check-certificate https://github.com/bourgesl/marlin-renderer/releases/download/v${MARLIN_TAG}/marlin-${MARLIN_VERSION}-Unsafe.jar -O ${CATALINA_HOME}/lib/marlin-${MARLIN_VERSION}-Unsafe.jar - # copy scripts COPY scripts /scripts RUN chmod +x /scripts/*.sh diff --git a/README.md b/README.md index 07818f4..61d679c 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,6 @@ Work is still in progress! 1. The [Dockerfile](Dockerfile) 1. installs dependencies 1. installs the GeoServer by downloading and extracting the war file - 1. installs the marlin renderer 1. defines defaults for environment variables 1. The [entrypoint.sh](scripts/entrypoint.sh) startup script (in a running container) 1. executes [install-extensions.sh](scripts/install-extensions.sh) to download and install GeoServer extensions based on the `STABLE_EXTENSIONS` environment variable. diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index d329090..b545daa 100644 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -12,10 +12,8 @@ export GEOSERVER_OPTS="-Djava.awt.headless=true -server \ -Djavax.servlet.request.encoding=UTF-8 \ -Djavax.servlet.response.encoding=UTF-8 \ -Xms${INITIAL_MEMORY} -Xmx${MAXIMUM_MEMORY} \ - -XX:SoftRefLRUPolicyMSPerMB=36000 -XX:+UseG1GC \ + -XX:SoftRefLRUPolicyMSPerMB=36000 \ -XX:MaxGCPauseMillis=200 -XX:ParallelGCThreads=20 -XX:ConcGCThreads=5 \ - -Xbootclasspath/a:${CATALINA_HOME}/lib/marlin-${MARLIN_VERSION}-Unsafe.jar \ - -Dsun.java2d.renderer=org.marlin.pisces.MarlinRenderingEngine \ -Dorg.geotools.coverage.jaiext.enabled=${JAIEXT_ENABLED}" ## JVM command line arguments From ed60742751dc76febc394524f8b711e28d085fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20B=C3=BChner?= Date: Thu, 17 Dec 2020 17:49:18 +0100 Subject: [PATCH 03/11] Add basic docker-compose demo --- .gitignore | 1 + README.md | 8 ++++++++ docker-compose-demo.yml | 13 +++++++++++++ 3 files changed, 22 insertions(+) create mode 100644 docker-compose-demo.yml diff --git a/.gitignore b/.gitignore index 92bc551..00e37c1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.iml *.idea +demo_data \ No newline at end of file diff --git a/README.md b/README.md index 61d679c..1492caf 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,14 @@ Work is still in progress! 1. handles the `GEOSERVER_OPTS` 1. starts the tomcat +## Quickstart + +You can quickstart by using the docker-compose demo + +`docker-compose -f docker-compose-demo.yml up --build` + +(use `sudo` if you get problems with mounted geoserver data dir) + ## Building `docker build -t geoserver:test .` diff --git a/docker-compose-demo.yml b/docker-compose-demo.yml new file mode 100644 index 0000000..58c017a --- /dev/null +++ b/docker-compose-demo.yml @@ -0,0 +1,13 @@ +version: '3' +services: + geoserver: + build: + context: . + ports: + - 8080:8080 + environment: + - STABLE_EXTENSIONS=wps + - INITIAL_MEMORY=1G + - MAXIMUM_MEMORY=2G + volumes: + - ./demo_data/geoserver_data:/opt/geoserver_data/:Z From a4e3a838160d40083632b96c7f1dda83fd1fa361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20B=C3=BChner?= Date: Thu, 17 Dec 2020 18:11:00 +0100 Subject: [PATCH 04/11] Add flag to control download of extensions at run time --- Dockerfile | 1 + README.md | 1 + docker-compose-demo.yml | 1 + scripts/entrypoint.sh | 2 -- scripts/install-extensions.sh | 14 +++++++++----- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index 152a6bd..dd099c5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,7 @@ ENV GS_VERSION=${GS_VERSION} \ INITIAL_MEMORY="2G" \ MAXIMUM_MEMORY="4G" \ JAIEXT_ENABLED=true \ + DOWNLOAD_EXTENSIONS=false \ STABLE_EXTENSIONS='' \ DEBIAN_FRONTEND=noninteractive \ EXTENSION_DOWNLOAD_DIR=/opt/geoserver_extension_downloads \ diff --git a/README.md b/README.md index 1492caf..34c3a65 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ Pass as environment variables. If not passed, the default values will be used. * `INITIAL_MEMORY` (default: 2G) * `MAXIMUM_MEMORY` (default: 4G) * `JAIEXT_ENABLED` (default: true) +* `DOWNLOAD_EXTENSIONS` (default: false) * `STABLE_EXTENSIONS` as comma separated list, will be downloaded and installed on startup (default: "") ## TODOs diff --git a/docker-compose-demo.yml b/docker-compose-demo.yml index 58c017a..9b23ceb 100644 --- a/docker-compose-demo.yml +++ b/docker-compose-demo.yml @@ -6,6 +6,7 @@ services: ports: - 8080:8080 environment: + - DOWNLOAD_EXTENSIONS=true - STABLE_EXTENSIONS=wps - INITIAL_MEMORY=1G - MAXIMUM_MEMORY=2G diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index b545daa..e49359f 100644 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -3,9 +3,7 @@ set -e ## install GeoServer extensions before starting the tomcat -echo "Starting installation of extensions" /scripts/install-extensions.sh -echo "\nFinished installation of extensions" export GEOSERVER_OPTS="-Djava.awt.headless=true -server \ -Dfile.encoding=UTF8 \ diff --git a/scripts/install-extensions.sh b/scripts/install-extensions.sh index 00f2bf6..72d7bc2 100644 --- a/scripts/install-extensions.sh +++ b/scripts/install-extensions.sh @@ -14,8 +14,12 @@ function download_extension() { fi } -# Install stable plugins -for EXTENSION in $(echo "${STABLE_EXTENSIONS}" | tr ',' ' '); do - URL="${STABLE_PLUGIN_URL}/geoserver-${GS_VERSION}-${EXTENSION}-plugin.zip" - download_extension ${URL} ${EXTENSION} -done +# Install stable plugins only if DOWNLOAD_EXTENSIONS is true +if [ "$DOWNLOAD_EXTENSIONS" = "true" ]; then + echo "Starting installation of extensions" + for EXTENSION in $(echo "${STABLE_EXTENSIONS}" | tr ',' ' '); do + URL="${STABLE_PLUGIN_URL}/geoserver-${GS_VERSION}-${EXTENSION}-plugin.zip" + download_extension ${URL} ${EXTENSION} + done + echo "Finished installation of extensions" +fi From 4261b1bdc117ab4327b46a545b501fe2167fcdda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20B=C3=BChner?= Date: Thu, 17 Dec 2020 20:12:44 +0100 Subject: [PATCH 05/11] Enable installation of custom libs/jars/extensions --- Dockerfile | 8 +++---- README.md | 9 +++----- docker-compose-demo.yml | 1 + scripts/install-extensions.sh | 42 ++++++++++++++++++++++++++--------- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/Dockerfile b/Dockerfile index dd099c5..aaa0d74 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,11 +15,11 @@ ENV GS_VERSION=${GS_VERSION} \ DOWNLOAD_EXTENSIONS=false \ STABLE_EXTENSIONS='' \ DEBIAN_FRONTEND=noninteractive \ - EXTENSION_DOWNLOAD_DIR=/opt/geoserver_extension_downloads \ - GEOSERVER_DATA_DIR=/opt/geoserver_data \ - GEOWEBCACHE_CACHE_DIR=/opt/geowebcache_data + ADDITIONAL_LIBS_DIR=/opt/additional_libs/ \ + GEOSERVER_DATA_DIR=/opt/geoserver_data/ \ + GEOWEBCACHE_CACHE_DIR=/opt/geowebcache_data/ -RUN mkdir ${EXTENSION_DOWNLOAD_DIR} ${GEOSERVER_DATA_DIR} ${GEOWEBCACHE_CACHE_DIR} +RUN mkdir ${ADDITIONAL_LIBS_DIR} ${GEOSERVER_DATA_DIR} ${GEOWEBCACHE_CACHE_DIR} # install required dependencies # also clear the initial webapps diff --git a/README.md b/README.md index 34c3a65..6292ca6 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ You can quickstart by using the docker-compose demo ## Running -`docker run -it -e STABLE_EXTENSIONS='wps,csw' -p 8080:8080 geoserver:test` +`docker run -it -e DOWNLOAD_EXTENSIONS='true' -e STABLE_EXTENSIONS='wps,csw' -p 8080:8080 geoserver:test` The extensions will be downloaded on startup of the image (before starting the tomcat). @@ -44,16 +44,13 @@ Pass as environment variables. If not passed, the default values will be used. * `MAXIMUM_MEMORY` (default: 4G) * `JAIEXT_ENABLED` (default: true) * `DOWNLOAD_EXTENSIONS` (default: false) -* `STABLE_EXTENSIONS` as comma separated list, will be downloaded and installed on startup (default: "") + * `STABLE_EXTENSIONS` applies only if `DOWNLOAD_EXTENSIONS` is true: provide a comma separated list of extension identifiers and they will be downloaded and installed on startup (default: "") ## TODOs * CORS * configuration of JNDI connections in the tomcat/custom tomcat configuration in general * default data for gs datadir? -* possibility to add custom java dependencies (for example the oracle jdbc driver) - * in this context: mount `EXTENSION_DOWNLOAD_DIR` and implement checks to cache extensions that have already been downloaded before? * log4j properties * add possibility to add custom fonts -* starting from which version we want to provide geoserver images (maybe 2.15.x?)/backwards compatability -* add a docker-compose demo environment? +* starting from which version we want to provide geoserver images/backwards compatability? diff --git a/docker-compose-demo.yml b/docker-compose-demo.yml index 9b23ceb..64c5493 100644 --- a/docker-compose-demo.yml +++ b/docker-compose-demo.yml @@ -12,3 +12,4 @@ services: - MAXIMUM_MEMORY=2G volumes: - ./demo_data/geoserver_data:/opt/geoserver_data/:Z + - ./demo_data/additional_libs:/opt/additional_libs:Z # by mounting this we can install libs from host on startup diff --git a/scripts/install-extensions.sh b/scripts/install-extensions.sh index 72d7bc2..ca68a3c 100644 --- a/scripts/install-extensions.sh +++ b/scripts/install-extensions.sh @@ -4,22 +4,44 @@ function download_extension() { URL=$1 EXTENSION=$2 - if curl --output /dev/null --silent --head --fail "${URL}"; then - DOWNLOAD_FILE="${EXTENSION_DOWNLOAD_DIR}/geoserver-${GS_VERSION}-${EXTENSION}-plugin.zip" - echo -e "\nDownloading ${EXTENSION}-extension from ${URL}" - wget --progress=bar:force:noscroll -c --no-chec k-certificate "${URL}" -O ${DOWNLOAD_FILE} - unzip -q -o ${DOWNLOAD_FILE} -d ${CATALINA_HOME}/webapps/geoserver/WEB-INF/lib - else - echo "URL does not exist: ${URL}" + DOWNLOAD_FILE="${ADDITIONAL_LIBS_DIR}geoserver-${GS_VERSION}-${EXTENSION}-plugin.zip" + + if [ -e "$DOWNLOAD_FILE" ]; then + echo "$DOWNLOAD_FILE already exists. Skipping download." + else + if curl --output /dev/null --silent --head --fail "${URL}"; then + echo -e "\nDownloading ${EXTENSION}-extension from ${URL}" + wget --progress=bar:force:noscroll -c --no-chec k-certificate "${URL}" -O ${DOWNLOAD_FILE} + else + echo "URL does not exist: ${URL}" + fi fi } -# Install stable plugins only if DOWNLOAD_EXTENSIONS is true +# Download stable plugins only if DOWNLOAD_EXTENSIONS is true if [ "$DOWNLOAD_EXTENSIONS" = "true" ]; then - echo "Starting installation of extensions" + echo "Starting download of extensions" for EXTENSION in $(echo "${STABLE_EXTENSIONS}" | tr ',' ' '); do URL="${STABLE_PLUGIN_URL}/geoserver-${GS_VERSION}-${EXTENSION}-plugin.zip" download_extension ${URL} ${EXTENSION} done - echo "Finished installation of extensions" + echo "Finished download of extensions" fi + +TARGET_LIB_DIR="${CATALINA_HOME}/webapps/geoserver/WEB-INF/lib/" +# Install all extensions that are available in the additional lib dir now +echo "Starting installation of extensions" +for ADDITIONAL_LIB in ${ADDITIONAL_LIBS_DIR}*; do + [ -e "$ADDITIONAL_LIB" ] || continue + + if [[ $ADDITIONAL_LIB == *.zip ]]; then + unzip -q -o -d ${TARGET_LIB_DIR} ${ADDITIONAL_LIB} "*.jar" + echo "Installed all jar files from ${ADDITIONAL_LIB}" + elif [[ $ADDITIONAL_LIB == *.jar ]]; then + cp ${ADDITIONAL_LIB} ${TARGET_LIB_DIR} + echo "Installed ${ADDITIONAL_LIB}" + else + echo "Skipping ${ADDITIONAL_LIB}: unknown file extension." + fi +done +echo "Finished installation of extensions" From 6945df30cb64ece329b0088adb2f6cb20ec5e9ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20B=C3=BChner?= Date: Thu, 17 Dec 2020 22:33:39 +0100 Subject: [PATCH 06/11] Add CORS support --- Dockerfile | 40 +++++++++++++++++++++++++++++++++++----- docker-compose-demo.yml | 5 ++++- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index aaa0d74..0b92208 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,12 +5,17 @@ ARG GS_VERSION=2.18.1 ARG WAR_URL=https://downloads.sourceforge.net/project/geoserver/GeoServer/${GS_VERSION}/geoserver-${GS_VERSION}-war.zip ARG STABLE_PLUGIN_URL=https://sourceforge.net/projects/geoserver/files/GeoServer/${GS_VERSION}/extensions +ARG CORS_ENABLED=false +ARG CORS_ALLOWED_ORIGINS=* +ARG CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE,HEAD,OPTIONS +ARG CORS_ALLOWED_HEADERS=* + # environment variables ENV GS_VERSION=${GS_VERSION} \ - WAR_URL=${WAR_URL} \ + GEOSERVER_DIR=${CATALINA_HOME}/webapps/geoserver \ STABLE_PLUGIN_URL=${STABLE_PLUGIN_URL} \ - INITIAL_MEMORY="2G" \ - MAXIMUM_MEMORY="4G" \ + INITIAL_MEMORY=2G \ + MAXIMUM_MEMORY=4G \ JAIEXT_ENABLED=true \ DOWNLOAD_EXTENSIONS=false \ STABLE_EXTENSIONS='' \ @@ -30,10 +35,35 @@ RUN apt update && \ # install geoserver RUN wget --progress=bar:force:noscroll -c --no-check-certificate "${WAR_URL}" -O /tmp/geoserver.zip && \ unzip /tmp/geoserver.zip geoserver.war -d ${CATALINA_HOME}/webapps && \ - mkdir -p ${CATALINA_HOME}/webapps/geoserver && \ - unzip -q ${CATALINA_HOME}/webapps/geoserver.war -d ${CATALINA_HOME}/webapps/geoserver && \ + mkdir -p ${GEOSERVER_DIR} && \ + unzip -q ${CATALINA_HOME}/webapps/geoserver.war -d ${GEOSERVER_DIR} && \ rm ${CATALINA_HOME}/webapps/geoserver.war +# configure CORS (inspired by https://github.com/oscarfonts/docker-geoserver) +RUN if [ "$CORS_ENABLED" = "true" ]; then \ + sed -i "\::i\ \ + \n\ \ + CorsFilter\n\ \ + org.apache.catalina.filters.CorsFilter\n\ \ + \n\ \ + cors.allowed.origins\n\ \ + ${CORS_ALLOWED_ORIGINS}\n\ \ + \n\ \ + \n\ \ + cors.allowed.methods\n\ \ + ${CORS_ALLOWED_METHODS}\n\ \ + \n\ \ + \n\ \ + cors.allowed.headers\n\ \ + ${CORS_ALLOWED_HEADERS}\n\ \ + \n\ \ + \n\ \ + \n\ \ + CorsFilter\n\ \ + /*\n\ \ + " "${GEOSERVER_DIR}/WEB-INF/web.xml"; \ + fi + # copy scripts COPY scripts /scripts RUN chmod +x /scripts/*.sh diff --git a/docker-compose-demo.yml b/docker-compose-demo.yml index 64c5493..6a3a9a0 100644 --- a/docker-compose-demo.yml +++ b/docker-compose-demo.yml @@ -3,11 +3,14 @@ services: geoserver: build: context: . + args: + - CORS_ENABLED=true + - CORS_ALLOWED_METHODS=GET,POST,PUT,HEAD,OPTIONS ports: - 8080:8080 environment: - DOWNLOAD_EXTENSIONS=true - - STABLE_EXTENSIONS=wps + - STABLE_EXTENSIONS=wps,csw - INITIAL_MEMORY=1G - MAXIMUM_MEMORY=2G volumes: From 5391f2cb4fd6b28609ae93eed48523c2eada286e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20B=C3=BChner?= Date: Thu, 17 Dec 2020 22:44:46 +0100 Subject: [PATCH 07/11] Minors --- README.md | 1 - docker-compose-demo.yml | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6292ca6..a2a97f8 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,6 @@ Pass as environment variables. If not passed, the default values will be used. ## TODOs -* CORS * configuration of JNDI connections in the tomcat/custom tomcat configuration in general * default data for gs datadir? * log4j properties diff --git a/docker-compose-demo.yml b/docker-compose-demo.yml index 6a3a9a0..4411215 100644 --- a/docker-compose-demo.yml +++ b/docker-compose-demo.yml @@ -13,6 +13,8 @@ services: - STABLE_EXTENSIONS=wps,csw - INITIAL_MEMORY=1G - MAXIMUM_MEMORY=2G + - JAIEXT_ENABLED=true + - GEOSERVER_DATA_DIR=/opt/geoserver_data/ volumes: - ./demo_data/geoserver_data:/opt/geoserver_data/:Z - ./demo_data/additional_libs:/opt/additional_libs:Z # by mounting this we can install libs from host on startup From 7dbb9d5ae0a4c11f2858d81f572f4da8a31dbfaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20B=C3=BChner?= Date: Thu, 17 Dec 2020 22:59:50 +0100 Subject: [PATCH 08/11] Add GeoServer version to docker-compose yaml --- Dockerfile | 8 ++++---- docker-compose-demo.yml | 1 + scripts/install-extensions.sh | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0b92208..7e4ba0f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,9 @@ FROM tomcat:jdk11-openjdk-slim -ARG GS_VERSION=2.18.1 +ARG GEOSERVER_VERSION=2.18.1 -ARG WAR_URL=https://downloads.sourceforge.net/project/geoserver/GeoServer/${GS_VERSION}/geoserver-${GS_VERSION}-war.zip -ARG STABLE_PLUGIN_URL=https://sourceforge.net/projects/geoserver/files/GeoServer/${GS_VERSION}/extensions +ARG WAR_URL=https://downloads.sourceforge.net/project/geoserver/GeoServer/${GEOSERVER_VERSION}/geoserver-${GEOSERVER_VERSION}-war.zip +ARG STABLE_PLUGIN_URL=https://sourceforge.net/projects/geoserver/files/GeoServer/${GEOSERVER_VERSION}/extensions ARG CORS_ENABLED=false ARG CORS_ALLOWED_ORIGINS=* @@ -11,7 +11,7 @@ ARG CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE,HEAD,OPTIONS ARG CORS_ALLOWED_HEADERS=* # environment variables -ENV GS_VERSION=${GS_VERSION} \ +ENV GEOSERVER_VERSION=${GEOSERVER_VERSION} \ GEOSERVER_DIR=${CATALINA_HOME}/webapps/geoserver \ STABLE_PLUGIN_URL=${STABLE_PLUGIN_URL} \ INITIAL_MEMORY=2G \ diff --git a/docker-compose-demo.yml b/docker-compose-demo.yml index 4411215..de2385a 100644 --- a/docker-compose-demo.yml +++ b/docker-compose-demo.yml @@ -4,6 +4,7 @@ services: build: context: . args: + - GEOSERVER_VERSION=2.18.1 - CORS_ENABLED=true - CORS_ALLOWED_METHODS=GET,POST,PUT,HEAD,OPTIONS ports: diff --git a/scripts/install-extensions.sh b/scripts/install-extensions.sh index ca68a3c..0338af6 100644 --- a/scripts/install-extensions.sh +++ b/scripts/install-extensions.sh @@ -4,7 +4,7 @@ function download_extension() { URL=$1 EXTENSION=$2 - DOWNLOAD_FILE="${ADDITIONAL_LIBS_DIR}geoserver-${GS_VERSION}-${EXTENSION}-plugin.zip" + DOWNLOAD_FILE="${ADDITIONAL_LIBS_DIR}geoserver-${GEOSERVER_VERSION}-${EXTENSION}-plugin.zip" if [ -e "$DOWNLOAD_FILE" ]; then echo "$DOWNLOAD_FILE already exists. Skipping download." @@ -22,7 +22,7 @@ function download_extension() { if [ "$DOWNLOAD_EXTENSIONS" = "true" ]; then echo "Starting download of extensions" for EXTENSION in $(echo "${STABLE_EXTENSIONS}" | tr ',' ' '); do - URL="${STABLE_PLUGIN_URL}/geoserver-${GS_VERSION}-${EXTENSION}-plugin.zip" + URL="${STABLE_PLUGIN_URL}/geoserver-${GEOSERVER_VERSION}-${EXTENSION}-plugin.zip" download_extension ${URL} ${EXTENSION} done echo "Finished download of extensions" From 82e350ddaa21fdb07276115f01c5ab28e881f73b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20B=C3=BChner?= Date: Fri, 29 Jan 2021 18:44:11 +0100 Subject: [PATCH 09/11] Enable use of custom war build --- Dockerfile | 16 ++++++++-------- README.md | 5 ++++- docker-compose-demo.yml | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7e4ba0f..2f6748d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ -FROM tomcat:jdk11-openjdk-slim +FROM tomcat:9.0.41-jdk11-openjdk-slim AS base -ARG GEOSERVER_VERSION=2.18.1 +ARG GEOSERVER_VERSION=2.18.2 -ARG WAR_URL=https://downloads.sourceforge.net/project/geoserver/GeoServer/${GEOSERVER_VERSION}/geoserver-${GEOSERVER_VERSION}-war.zip +ARG GEOSERVER_WAR_SRC=https://downloads.sourceforge.net/project/geoserver/GeoServer/${GEOSERVER_VERSION}/geoserver-${GEOSERVER_VERSION}-war.zip ARG STABLE_PLUGIN_URL=https://sourceforge.net/projects/geoserver/files/GeoServer/${GEOSERVER_VERSION}/extensions ARG CORS_ENABLED=false @@ -32,15 +32,15 @@ RUN apt update && \ apt install -y curl wget openssl zip fontconfig libfreetype6 && \ rm -rf ${CATALINA_HOME}/webapps/* +ADD "${GEOSERVER_WAR_SRC}" "/tmp/" + # install geoserver -RUN wget --progress=bar:force:noscroll -c --no-check-certificate "${WAR_URL}" -O /tmp/geoserver.zip && \ - unzip /tmp/geoserver.zip geoserver.war -d ${CATALINA_HOME}/webapps && \ - mkdir -p ${GEOSERVER_DIR} && \ - unzip -q ${CATALINA_HOME}/webapps/geoserver.war -d ${GEOSERVER_DIR} && \ +RUN unzip /tmp/geoserver*.zip geoserver.war -d ${CATALINA_HOME}/webapps && \ + mkdir -p ${GEOSERVER_DIR} && \unzip -q ${CATALINA_HOME}/webapps/geoserver.war -d ${GEOSERVER_DIR} && \ rm ${CATALINA_HOME}/webapps/geoserver.war # configure CORS (inspired by https://github.com/oscarfonts/docker-geoserver) -RUN if [ "$CORS_ENABLED" = "true" ]; then \ +RUN if [ "${CORS_ENABLED}" = "true" ]; then \ sed -i "\::i\ \ \n\ \ CorsFilter\n\ \ diff --git a/README.md b/README.md index a2a97f8..6f4441e 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,10 @@ Work is still in progress! 1. The [Dockerfile](Dockerfile) 1. installs dependencies - 1. installs the GeoServer by downloading and extracting the war file + 1. installs the GeoServer by adding a ZIP and extracting the WAR from it + 1. the expected file name of the war in the zip is `geoserver.war` + 1. by default, the GeoServer URL from sourceforge is used, but you could also provide a custom URL with a zip in the `GEOSERVER_WAR_SRC` build argument. + 1. you can also use the `GEOSERVER_WAR_SRC` build argument to burn your custom WAR file from your local machine to the docker image, e.g. with something like `docker build -t geoserver:test --build-arg GEOSERVER_WAR_SRC="./resources/geoserver.zip" .` 1. defines defaults for environment variables 1. The [entrypoint.sh](scripts/entrypoint.sh) startup script (in a running container) 1. executes [install-extensions.sh](scripts/install-extensions.sh) to download and install GeoServer extensions based on the `STABLE_EXTENSIONS` environment variable. diff --git a/docker-compose-demo.yml b/docker-compose-demo.yml index de2385a..df67b48 100644 --- a/docker-compose-demo.yml +++ b/docker-compose-demo.yml @@ -4,7 +4,7 @@ services: build: context: . args: - - GEOSERVER_VERSION=2.18.1 + - GEOSERVER_VERSION=2.18.2 - CORS_ENABLED=true - CORS_ALLOWED_METHODS=GET,POST,PUT,HEAD,OPTIONS ports: From 3fa73d0aefad4be7eee4c0884e5abcdd6830b007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20B=C3=BChner?= Date: Thu, 11 Mar 2021 12:22:42 +0100 Subject: [PATCH 10/11] Extract war from zip if necessary --- Dockerfile | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2f6748d..f3c0c1f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,10 +34,17 @@ RUN apt update && \ ADD "${GEOSERVER_WAR_SRC}" "/tmp/" +# extract war from zip if necessary +RUN if [ "${GEOSERVER_WAR_SRC##*.}" = "zip" ]; then \ + unzip "/tmp/*zip" -d /tmp/; \ + ls -lah; \ + rm /tmp/*zip; \ + fi + # install geoserver -RUN unzip /tmp/geoserver*.zip geoserver.war -d ${CATALINA_HOME}/webapps && \ - mkdir -p ${GEOSERVER_DIR} && \unzip -q ${CATALINA_HOME}/webapps/geoserver.war -d ${GEOSERVER_DIR} && \ - rm ${CATALINA_HOME}/webapps/geoserver.war +RUN mkdir -p ${GEOSERVER_DIR} && \ + unzip -q /tmp/*war -d ${GEOSERVER_DIR} && \ + rm /tmp/*war # configure CORS (inspired by https://github.com/oscarfonts/docker-geoserver) RUN if [ "${CORS_ENABLED}" = "true" ]; then \ From 5d8ca42c091ef1b7e173aeb06a73d3e6a3ee4d6e Mon Sep 17 00:00:00 2001 From: Johannes Weskamm Date: Wed, 22 Jun 2022 17:01:25 +0200 Subject: [PATCH 11/11] Updating docker and scripts --- .gitignore | 1 - Dockerfile | 134 +++++++++--------- README.md | 122 +++++++++------- additional_fonts/.gitignore | 5 + additional_libs/.gitignore | 5 + docker-compose-demo.yml | 4 +- geoserver_data/.gitignore | 5 + ...all-extensions.sh => install-extensions.sh | 18 +-- scripts/entrypoint.sh | 21 --- startup.sh | 51 +++++++ 10 files changed, 218 insertions(+), 148 deletions(-) create mode 100644 additional_fonts/.gitignore create mode 100644 additional_libs/.gitignore create mode 100644 geoserver_data/.gitignore rename scripts/install-extensions.sh => install-extensions.sh (69%) delete mode 100644 scripts/entrypoint.sh create mode 100755 startup.sh diff --git a/.gitignore b/.gitignore index 00e37c1..92bc551 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ *.iml *.idea -demo_data \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index f3c0c1f..3afd9e3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,83 +1,87 @@ -FROM tomcat:9.0.41-jdk11-openjdk-slim AS base - -ARG GEOSERVER_VERSION=2.18.2 - -ARG GEOSERVER_WAR_SRC=https://downloads.sourceforge.net/project/geoserver/GeoServer/${GEOSERVER_VERSION}/geoserver-${GEOSERVER_VERSION}-war.zip -ARG STABLE_PLUGIN_URL=https://sourceforge.net/projects/geoserver/files/GeoServer/${GEOSERVER_VERSION}/extensions +FROM ubuntu:22.04 +# The GS_VERSION argument could be used like this to overwrite the default: +# docker build --build-arg GS_VERSION=2.11.3 -t geoserver:2.11.3 . +ARG TOMCAT_VERSION=9.0.64 +ARG GS_VERSION=2.21.0 +ARG GS_DATA_PATH=./geoserver_data/ +ARG ADDITIONAL_LIBS_PATH=./additional_libs/ +ARG ADDITIONAL_FONTS_PATH=./additional_fonts/ ARG CORS_ENABLED=false ARG CORS_ALLOWED_ORIGINS=* ARG CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE,HEAD,OPTIONS ARG CORS_ALLOWED_HEADERS=* +ARG STABLE_PLUGIN_URL=https://sourceforge.net/projects/geoserver/files/GeoServer/${GS_VERSION}/extensions -# environment variables -ENV GEOSERVER_VERSION=${GEOSERVER_VERSION} \ - GEOSERVER_DIR=${CATALINA_HOME}/webapps/geoserver \ - STABLE_PLUGIN_URL=${STABLE_PLUGIN_URL} \ - INITIAL_MEMORY=2G \ - MAXIMUM_MEMORY=4G \ - JAIEXT_ENABLED=true \ - DOWNLOAD_EXTENSIONS=false \ - STABLE_EXTENSIONS='' \ - DEBIAN_FRONTEND=noninteractive \ - ADDITIONAL_LIBS_DIR=/opt/additional_libs/ \ - GEOSERVER_DATA_DIR=/opt/geoserver_data/ \ - GEOWEBCACHE_CACHE_DIR=/opt/geowebcache_data/ +# Environment variables +ENV CATALINA_HOME=/opt/apache-tomcat-${TOMCAT_VERSION} +ENV GEOSERVER_VERSION=$GS_VERSION +ENV GEOSERVER_DATA_DIR=/opt/geoserver_data/ +ENV GEOSERVER_LIB_DIR=$CATALINA_HOME/webapps/geoserver/WEB-INF/lib/ +ENV EXTRA_JAVA_OPTS="-Xms256m -Xmx1g" +ENV CORS_ENABLED=$CORS_ENABLED +ENV CORS_ALLOWED_ORIGINS=$CORS_ALLOWED_ORIGINS +ENV CORS_ALLOWED_METHODS=$CORS_ALLOWED_METHODS +ENV CORS_ALLOWED_HEADERS=$CORS_ALLOWED_HEADERS +ENV DEBIAN_FRONTEND=noninteractive +ENV INSTALL_EXTENSIONS=false +ENV STABLE_EXTENSIONS='' +ENV STABLE_PLUGIN_URL=$STABLE_PLUGIN_URL +ENV ADDITIONAL_LIBS_DIR=/opt/additional_libs/ +ENV ADDITIONAL_FONTS_DIR=/opt/additional_fonts/ -RUN mkdir ${ADDITIONAL_LIBS_DIR} ${GEOSERVER_DATA_DIR} ${GEOWEBCACHE_CACHE_DIR} +# see http://docs.geoserver.org/stable/en/user/production/container.html +ENV CATALINA_OPTS="\$EXTRA_JAVA_OPTS \ + -Djava.awt.headless=true -server \ + -Dfile.encoding=UTF-8 \ + -Djavax.servlet.request.encoding=UTF-8 \ + -Djavax.servlet.response.encoding=UTF-8 \ + -D-XX:SoftRefLRUPolicyMSPerMB=36000 \ + -Xbootclasspath/a:$CATALINA_HOME/lib/marlin.jar \ + -Xbootclasspath/a:$CATALINA_HOME/lib/marlin-sun-java2d.jar \ + -Dsun.java2d.renderer=org.marlin.pisces.PiscesRenderingEngine \ + -Dorg.geotools.coverage.jaiext.enabled=true" -# install required dependencies -# also clear the initial webapps +# init RUN apt update && \ - apt install -y curl wget openssl zip fontconfig libfreetype6 && \ - rm -rf ${CATALINA_HOME}/webapps/* + apt -y upgrade && \ + apt install -y --no-install-recommends openssl unzip gdal-bin wget curl openjdk-11-jdk && \ + rm -rf $CATALINA_HOME/webapps/* && \ + apt clean && \ + rm -rf /var/cache/apt/* && \ + rm -rf /var/lib/apt/lists/* -ADD "${GEOSERVER_WAR_SRC}" "/tmp/" +WORKDIR /opt/ +RUN wget -q https://dlcdn.apache.org/tomcat/tomcat-9/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz && \ + tar xf apache-tomcat-${TOMCAT_VERSION}.tar.gz && \ + rm apache-tomcat-${TOMCAT_VERSION}.tar.gz && \ + rm -rf /opt/apache-tomcat-${TOMCAT_VERSION}/webapps/ROOT && \ + rm -rf /opt/apache-tomcat-${TOMCAT_VERSION}/webapps/docs && \ + rm -rf /opt/apache-tomcat-${TOMCAT_VERSION}/webapps/examples -# extract war from zip if necessary -RUN if [ "${GEOSERVER_WAR_SRC##*.}" = "zip" ]; then \ - unzip "/tmp/*zip" -d /tmp/; \ - ls -lah; \ - rm /tmp/*zip; \ - fi +WORKDIR /tmp # install geoserver -RUN mkdir -p ${GEOSERVER_DIR} && \ - unzip -q /tmp/*war -d ${GEOSERVER_DIR} && \ - rm /tmp/*war +RUN wget -q -O /tmp/geoserver.zip http://downloads.sourceforge.net/project/geoserver/GeoServer/$GEOSERVER_VERSION/geoserver-$GEOSERVER_VERSION-war.zip && \ + unzip geoserver.zip geoserver.war -d $CATALINA_HOME/webapps && \ + mkdir -p $CATALINA_HOME/webapps/geoserver && \ + unzip -q $CATALINA_HOME/webapps/geoserver.war -d $CATALINA_HOME/webapps/geoserver && \ + rm $CATALINA_HOME/webapps/geoserver.war && \ + mkdir -p $GEOSERVER_DATA_DIR -# configure CORS (inspired by https://github.com/oscarfonts/docker-geoserver) -RUN if [ "${CORS_ENABLED}" = "true" ]; then \ - sed -i "\::i\ \ - \n\ \ - CorsFilter\n\ \ - org.apache.catalina.filters.CorsFilter\n\ \ - \n\ \ - cors.allowed.origins\n\ \ - ${CORS_ALLOWED_ORIGINS}\n\ \ - \n\ \ - \n\ \ - cors.allowed.methods\n\ \ - ${CORS_ALLOWED_METHODS}\n\ \ - \n\ \ - \n\ \ - cors.allowed.headers\n\ \ - ${CORS_ALLOWED_HEADERS}\n\ \ - \n\ \ - \n\ \ - \n\ \ - CorsFilter\n\ \ - /*\n\ \ - " "${GEOSERVER_DIR}/WEB-INF/web.xml"; \ - fi - -# copy scripts -COPY scripts /scripts -RUN chmod +x /scripts/*.sh +COPY $GS_DATA_PATH $GEOSERVER_DATA_DIR +COPY $ADDITIONAL_LIBS_PATH $GEOSERVER_LIB_DIR +COPY $ADDITIONAL_FONTS_PATH /usr/share/fonts/truetype/ # cleanup -RUN apt clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +RUN apt purge -y && \ + apt autoremove --purge -y && \ + rm -rf /tmp/* -WORKDIR ${CATALINA_HOME} +# copy scripts +COPY *.sh /opt/ +RUN chmod +x /opt/*.sh -CMD ["/bin/sh", "/scripts/entrypoint.sh"] +ENTRYPOINT /opt/startup.sh + +WORKDIR /opt diff --git a/README.md b/README.md index 6f4441e..93d48b6 100644 --- a/README.md +++ b/README.md @@ -1,58 +1,80 @@ -# Docker GeoServer image +# A geoserver docker image -This docker GeoServer image is based on the following proposal: - -https://github.com/geoserver/geoserver/wiki/GSIP-192 +This Dockerfile can be used to create images for all geoserver versions since 2.5. -Work is still in progress! +* Debian based Linux +* OpenJDK 11 +* Tomcat 9 +* GeoServer + * Support of custom fonts (e.g. for SLD styling) + * CORS support -## How it works +**IMPORTANT NOTE:** Please change the default geoserver master password! The default masterpw is located in this file (within the docker container): `/opt/geoserver_data/security/masterpw/default/masterpw` -1. The [Dockerfile](Dockerfile) - 1. installs dependencies - 1. installs the GeoServer by adding a ZIP and extracting the WAR from it - 1. the expected file name of the war in the zip is `geoserver.war` - 1. by default, the GeoServer URL from sourceforge is used, but you could also provide a custom URL with a zip in the `GEOSERVER_WAR_SRC` build argument. - 1. you can also use the `GEOSERVER_WAR_SRC` build argument to burn your custom WAR file from your local machine to the docker image, e.g. with something like `docker build -t geoserver:test --build-arg GEOSERVER_WAR_SRC="./resources/geoserver.zip" .` - 1. defines defaults for environment variables -1. The [entrypoint.sh](scripts/entrypoint.sh) startup script (in a running container) - 1. executes [install-extensions.sh](scripts/install-extensions.sh) to download and install GeoServer extensions based on the `STABLE_EXTENSIONS` environment variable. - 1. handles the `GEOSERVER_OPTS` - 1. starts the tomcat +## How to build? -## Quickstart +`docker build -t {YOUR_TAG} .` -You can quickstart by using the docker-compose demo +## How to quickstart? + +Build the image as described above, then: + +`docker run -it -p 80:8080 {YOUR_TAG}` + +or if you want to start the container daemonized: + +`docker run -d -p 80:8080 {YOUR_TAG}` + +Check http://localhost/geoserver to see the geoserver page and login with geoserver defaults `admin:geoserver` + +## How to build a specific GeoServer version? + +`docker build --build-arg GS_VERSION={YOUR_VERSION} -t {YOUR_TAG} .` + +## How to build with custom geoserver data? + +`docker build --build-arg GS_DATA_PATH={RELATIVE_PATH_TO_YOUR_GS_DATA} .` + +**Note:** The passed path **must not** be absolute! Instead, the path should be within the build context (e.g. next to the Dockerfile) and should be passed as a relative path, e.g. `GS_DATA_PATH=./my_data/` + +## Can I build a specific GS version with custom data? + +Yes! Just pass the `--build-arg` param twice, e.g. + +`... --build-arg GS_VERSION={VERSION} --build-arg GS_DATA_PATH={PATH} ...` + +## How to build with additional libs/extensions/plugins? + +Put your `*.jar` files (e.g. the WPS extension) in the `additional_libs` folder and build with one of the commands from above! (They will be copied to the GeoServer `WEB-INF/lib` folder during the build.) + +**Note:** Similar to the GeoServer data path from above, you can also configure the path to the additional libraries by passing the `ADDITIONAL_LIBS_PATH` argument when building: + +`--build-arg ADDITIONAL_LIBS_PATH={RELATIVE_PATH_TO_YOUR_LIBS}` + +## How to add additional libs using an existing docker image? + +If you want to add geoserver extensions/libs by using a mount, you can add something like + +``` +--mount src="/dir/with/libs/on/host",target=/opt/additional_libs,type=bind +``` + +## How to add additional fonts to the docker image (e.g. for SLD styling)? + +If you want to add custom fonts (the base image only contains 26 fonts) by using a mount, you can add something like + +``` +--mount src="/dir/with/fonts/on/host",target=/opt/additional_fonts,type=bind +``` + +to your `docker run` command. + +**Note:** Do not change the target value! + +## How to watch geoserver.log from host? + +`docker exec -it {CONTAINER_ID} tail -f /opt/geoserver_data/logs/geoserver.log` + +## How to use the docker-compose demo? `docker-compose -f docker-compose-demo.yml up --build` - -(use `sudo` if you get problems with mounted geoserver data dir) - -## Building - -`docker build -t geoserver:test .` - -## Running - -`docker run -it -e DOWNLOAD_EXTENSIONS='true' -e STABLE_EXTENSIONS='wps,csw' -p 8080:8080 geoserver:test` - -The extensions will be downloaded on startup of the image (before starting the tomcat). - -## Configuration - -Pass as environment variables. If not passed, the default values will be used. - -* `GEOSERVER_DATA_DIR` (default: /opt/geoserver_data) -* `INITIAL_MEMORY` (default: 2G) -* `MAXIMUM_MEMORY` (default: 4G) -* `JAIEXT_ENABLED` (default: true) -* `DOWNLOAD_EXTENSIONS` (default: false) - * `STABLE_EXTENSIONS` applies only if `DOWNLOAD_EXTENSIONS` is true: provide a comma separated list of extension identifiers and they will be downloaded and installed on startup (default: "") - -## TODOs - -* configuration of JNDI connections in the tomcat/custom tomcat configuration in general -* default data for gs datadir? -* log4j properties -* add possibility to add custom fonts -* starting from which version we want to provide geoserver images/backwards compatability? diff --git a/additional_fonts/.gitignore b/additional_fonts/.gitignore new file mode 100644 index 0000000..76bedae --- /dev/null +++ b/additional_fonts/.gitignore @@ -0,0 +1,5 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore + diff --git a/additional_libs/.gitignore b/additional_libs/.gitignore new file mode 100644 index 0000000..76bedae --- /dev/null +++ b/additional_libs/.gitignore @@ -0,0 +1,5 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore + diff --git a/docker-compose-demo.yml b/docker-compose-demo.yml index df67b48..8ea844e 100644 --- a/docker-compose-demo.yml +++ b/docker-compose-demo.yml @@ -4,13 +4,13 @@ services: build: context: . args: - - GEOSERVER_VERSION=2.18.2 + - GEOSERVER_VERSION=2.21.0 - CORS_ENABLED=true - CORS_ALLOWED_METHODS=GET,POST,PUT,HEAD,OPTIONS ports: - 8080:8080 environment: - - DOWNLOAD_EXTENSIONS=true + - INSTALL_EXTENSIONS=true - STABLE_EXTENSIONS=wps,csw - INITIAL_MEMORY=1G - MAXIMUM_MEMORY=2G diff --git a/geoserver_data/.gitignore b/geoserver_data/.gitignore new file mode 100644 index 0000000..76bedae --- /dev/null +++ b/geoserver_data/.gitignore @@ -0,0 +1,5 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore + diff --git a/scripts/install-extensions.sh b/install-extensions.sh similarity index 69% rename from scripts/install-extensions.sh rename to install-extensions.sh index 0338af6..541cbd3 100644 --- a/scripts/install-extensions.sh +++ b/install-extensions.sh @@ -10,16 +10,16 @@ function download_extension() { echo "$DOWNLOAD_FILE already exists. Skipping download." else if curl --output /dev/null --silent --head --fail "${URL}"; then - echo -e "\nDownloading ${EXTENSION}-extension from ${URL}" - wget --progress=bar:force:noscroll -c --no-chec k-certificate "${URL}" -O ${DOWNLOAD_FILE} + echo -e "\nDownloading ${EXTENSION}-extension from ${URL} to ${DOWNLOAD_FILE}" + wget --progress=bar:force:noscroll -c --no-check-certificate "${URL}" -O ${DOWNLOAD_FILE} else echo "URL does not exist: ${URL}" fi fi } -# Download stable plugins only if DOWNLOAD_EXTENSIONS is true -if [ "$DOWNLOAD_EXTENSIONS" = "true" ]; then +# Download stable plugins only if INSTALL_EXTENSIONS is true +if [ "$INSTALL_EXTENSIONS" = "true" ]; then echo "Starting download of extensions" for EXTENSION in $(echo "${STABLE_EXTENSIONS}" | tr ',' ' '); do URL="${STABLE_PLUGIN_URL}/geoserver-${GEOSERVER_VERSION}-${EXTENSION}-plugin.zip" @@ -28,17 +28,17 @@ if [ "$DOWNLOAD_EXTENSIONS" = "true" ]; then echo "Finished download of extensions" fi -TARGET_LIB_DIR="${CATALINA_HOME}/webapps/geoserver/WEB-INF/lib/" -# Install all extensions that are available in the additional lib dir now +# Install the extensions echo "Starting installation of extensions" -for ADDITIONAL_LIB in ${ADDITIONAL_LIBS_DIR}*; do +for EXTENSION in $(echo "${STABLE_EXTENSIONS}" | tr ',' ' '); do + ADDITIONAL_LIB=${ADDITIONAL_LIBS_DIR}geoserver-${GEOSERVER_VERSION}-${EXTENSION}-plugin.zip [ -e "$ADDITIONAL_LIB" ] || continue if [[ $ADDITIONAL_LIB == *.zip ]]; then - unzip -q -o -d ${TARGET_LIB_DIR} ${ADDITIONAL_LIB} "*.jar" + unzip -q -o -d ${GEOSERVER_LIB_DIR} ${ADDITIONAL_LIB} "*.jar" echo "Installed all jar files from ${ADDITIONAL_LIB}" elif [[ $ADDITIONAL_LIB == *.jar ]]; then - cp ${ADDITIONAL_LIB} ${TARGET_LIB_DIR} + cp ${ADDITIONAL_LIB} ${GEOSERVER_LIB_DIR} echo "Installed ${ADDITIONAL_LIB}" else echo "Skipping ${ADDITIONAL_LIB}: unknown file extension." diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh deleted file mode 100644 index e49359f..0000000 --- a/scripts/entrypoint.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -## Inspired by https://github.com/kartoza/docker-geoserver -set -e - -## install GeoServer extensions before starting the tomcat -/scripts/install-extensions.sh - -export GEOSERVER_OPTS="-Djava.awt.headless=true -server \ - -Dfile.encoding=UTF8 \ - -Djavax.servlet.request.encoding=UTF-8 \ - -Djavax.servlet.response.encoding=UTF-8 \ - -Xms${INITIAL_MEMORY} -Xmx${MAXIMUM_MEMORY} \ - -XX:SoftRefLRUPolicyMSPerMB=36000 \ - -XX:MaxGCPauseMillis=200 -XX:ParallelGCThreads=20 -XX:ConcGCThreads=5 \ - -Dorg.geotools.coverage.jaiext.enabled=${JAIEXT_ENABLED}" - -## JVM command line arguments -export JAVA_OPTS="${JAVA_OPTS} ${GEOSERVER_OPTS}" - -## Start the tomcat -exec /usr/local/tomcat/bin/catalina.sh run diff --git a/startup.sh b/startup.sh new file mode 100755 index 0000000..812e243 --- /dev/null +++ b/startup.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +## install GeoServer extensions before starting the tomcat +/opt/install-extensions.sh + +# copy additional geoserver libs before starting the tomcat +# we also count whether at least one file with the extensions exists +count=`ls -1 $ADDITIONAL_LIBS_DIR/*.jar 2>/dev/null | wc -l` +if [ -d "$ADDITIONAL_LIBS_DIR" ] && [ $count != 0 ]; then + cp $ADDITIONAL_LIBS_DIR/*.jar $CATALINA_HOME/webapps/geoserver/WEB-INF/lib/ +fi + +# copy additional fonts before starting the tomcat +# we also count whether at least one file with the extensions exists +count=`ls -1 *.ttf 2>/dev/null | wc -l` +if [ -d "$ADDITIONAL_FONTS_DIR" ] && [ $count != 0 ]; then + cp $ADDITIONAL_FONTS_DIR/*.ttf /usr/share/fonts/truetype/ +fi + +# configure CORS (inspired by https://github.com/oscarfonts/docker-geoserver) +# if enabled, this will add the filter definitions +# to the end of the web.xml +# (this will only happen if our filter has not yet been added before) +if [ "${CORS_ENABLED}" = "true" ]; then + if ! grep -q DockerGeoServerCorsFilter "$CATALINA_HOME/webapps/geoserver/WEB-INF/web.xml"; then + sed -i "\::i\\ + \n\ + DockerGeoServerCorsFilter\n\ + org.apache.catalina.filters.CorsFilter\n\ + \n\ + cors.allowed.origins\n\ + ${CORS_ALLOWED_ORIGINS}\n\ + \n\ + \n\ + cors.allowed.methods\n\ + ${CORS_ALLOWED_METHODS}\n\ + \n\ + \n\ + cors.allowed.headers\n\ + ${CORS_ALLOWED_HEADERS}\n\ + \n\ + \n\ + \n\ + DockerGeoServerCorsFilter\n\ + /*\n\ + " "$CATALINA_HOME/webapps/geoserver/WEB-INF/web.xml"; + fi +fi + +# start the tomcat +$CATALINA_HOME/bin/catalina.sh run