Skip to content

Commit

Permalink
fix(dockerfile): Adjust the docker setup
Browse files Browse the repository at this point in the history
Without any configuration the container uses an example yml config shipped with it.
Graph locations are parsed from envs, json and yml files
  • Loading branch information
MichaelsJP committed Feb 4, 2024
1 parent 84099e4 commit 3a68457
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 96 deletions.
7 changes: 1 addition & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ ARG BASE_FOLDER=/home/ors
ENV LANG='en_US' LANGUAGE='en_US' LC_ALL='en_US'

# Setup the target system with the right user and folders.
RUN apk add --no-cache bash=~'5' openssl=~'3' && \
RUN apk add --no-cache bash=~'5' openssl=~'3' yq jq && \
addgroup ors && \
mkdir -p ${BASE_FOLDER}/logs ${BASE_FOLDER}/files ${BASE_FOLDER}/.graphs ${BASE_FOLDER}/.elevation_cache && \
adduser -D -h ${BASE_FOLDER} --system -G ors ors && \
Expand All @@ -54,11 +54,6 @@ RUN chmod +x /ors.jar && chown -R ors:ors /entrypoint.sh && chown -R ors:ors ${B
ENV BUILD_GRAPHS="False"
# Set the ARG to an ENV. Else it will be lost.
ENV BASE_FOLDER=${BASE_FOLDER}
ENV ors.engine.source_file=/heidelberg.osm.gz
ENV ors.engine.profiles.car.enabled='true'
ENV ors.engine.graphs_root_path=${BASE_FOLDER}/graphs
ENV ors.engine.elevation.cache_path=${BASE_FOLDER}/elevation_cache
ENV server.port=8082

# Start the container
ENTRYPOINT ["/entrypoint.sh"]
41 changes: 25 additions & 16 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
version: '2.4'
services:
ors-app:
# Activate the following lines to build the container from the repository
#build:
# context: ./
container_name: ors-app
ports:
- "8080:8080"
- "8080:8082"
- "9001:9001"
image: openrouteservice/openrouteservice:nightly
# For versioned images see https://giscience.github.io/openrouteservice/installation/Running-with-Docker.html
image: local/openrouteservice:test-compose
user: "${UID:-0}:${GID:-0}"
# build:
# context: ./
# args:
# OSM_FILE: ./ors-api/src/test/files/heidelberg.osm.gz
volumes:
- ./docker/graphs:/home/ors/ors-core/data/graphs
- ./docker/elevation_cache:/home/ors/ors-core/data/elevation_cache
- ./docker/logs/ors:/home/ors/logs
- ./docker/logs/tomcat:/home/ors/tomcat/logs
- ./docker/conf:/home/ors/ors-conf
- ./docker/data:/home/ors/ors-core/data
- ./graphs:/home/ors/graphs
- ./elevation_cache:/home/ors/elevation_cache
- ./config:/home/ors/config
- ./logs:/home/ors/logs
- ./files:/home/ors/files
# Activate the following lines to use the environment file from the repo root for configuration
#env_file:
# - ors-config.env
environment:
- BUILD_GRAPHS=False # Forces the container to rebuild the graphs, e.g. when PBF is changed
- "JAVA_OPTS=-Djava.awt.headless=true -server -XX:TargetSurvivorRatio=75 -XX:SurvivorRatio=64 -XX:MaxTenuringThreshold=3 -XX:+UseG1GC -XX:+ScavengeBeforeFullGC -XX:ParallelGCThreads=4 -Xms1g -Xmx2g"
- "CATALINA_OPTS=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9001 -Dcom.sun.management.jmxremote.rmi.port=9001 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=localhost"
- ORS_CONFIG=/home/ors/ors-conf/ors-config.json
#ORS_CONFIG_LOCATION: /home/ors/config/example-ors-config.yml
BUILD_GRAPHS: True
# The following environment variables are used to configure the container without an ors-config.yml file.
# See the ors-config.env file for more options.
# These variables override values set by any config file.
#logging.level.org.heigit: INFO
#ors.engine.source_file: /home/ors/files/example-heidelberg.osm.gz
#ors.engine.profiles.car.enabled: true
#ors.engine.profiles.hgv.enabled: false
#ors.engine.profiles.walking.enabled: false
#ors.engine.profiles.bike-regular.enabled: false
#ors.engine.profiles.wheelchair.enabled: false
172 changes: 98 additions & 74 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,35 @@ function info() {

echo "#################"
echo "# Container ENV #"
echo "################"
echo "#################"
# Users should define ORS_HOME. If not, use /home/ors
if [ -z "${ORS_HOME}" ]; then
info "ORS_HOME not explicitly set. Using default: ${BASE_FOLDER}"
ORS_HOME=${BASE_FOLDER}
success "ORS_HOME set to: ${ORS_HOME}"
else
success "ORS_HOME found: ${ORS_HOME}"
fi
# Set the jar file location
jar_file=/ors.jar
original_jar_file=/ors.jar
# Make sure BUILD_GRAPHS is safe to use
ors_build_graphs=${BUILD_GRAPHS:-"false"}
# Decide if we should print the migration info in the end
print_migration_info=${PRINT_MIGRATION_INFO:-"false"}
# Parse the ors.* properties
env | while read -r line; do
info "${line}"
done
# get ors.engine.graphs_root_path=. Dot notations in bash are not allowed, so we need to use awk to parse it.
ors_engine_graphs_root_path=$(env | grep "^ors\.engine\.graphs_root_path=" | awk -F '=' '{print $2}')
# get ors.engine.elevation.cache_path
ors_engine_elevation_cache_path=$(env | grep "^ors\.engine\.elevation\.cache_path=" | awk -F '=' '{print $2}')
# get ors.engine.source_file
ors_engine_source_file=$(env | grep "^ors\.engine\.source_file=" | awk -F '=' '{print $2}')
# get ors_config_location
ors_config_location=${ORS_CONFIG_LOCATION:-""}
# Unset the ORS_CONFIG_LOCATION to not interfere with the spring-boot application
unset ORS_CONFIG_LOCATION
# Parse the ors.* properties
env | while read -r line; do
info "${line}"
done
warning "If a config file is provided, the above ENV vars will override their respective counter part in the config file."

echo "###########################"
Expand All @@ -62,14 +74,6 @@ else
success "BASE_FOLDER var valid at: ${BASE_FOLDER}"
fi

# Users should define ORS_HOME. If not, use /home/ors
if [ -z "${ORS_HOME}" ]; then
info "ORS_HOME not explicitly set. Using default: /home/ors"
ORS_HOME="/home/ors"
else
success "ORS_HOME found: ${ORS_HOME}"
fi

# Make sure ORS_HOME exists and is writable
mkdir -p "${ORS_HOME}"

Expand All @@ -81,60 +85,53 @@ else
rm -rf "${ORS_HOME:?}"/.test
fi

# Check the jar file exists
if [ ! -f "${jar_file}" ]; then
error "Jar file not found. This shouldn't happen. Exiting."
# Check if the original jar file exists
if [ ! -f "${original_jar_file}" ]; then
error "Original Jar file not found. This shouldn't happen. Exiting."
else
success "Jar file found: ${jar_file}"
success "Jar file found, update jar at ${ORS_HOME}/ors.jar"
cp -f "${original_jar_file}" "${ORS_HOME}/ors.jar" || warning "Could not copy ${original_jar_file} to ${ORS_HOME}/ors.jar"
jar_file="${ORS_HOME}/ors.jar"
fi

# Check that ors_engine_graphs_root_path is not empty and not set to /
if [ -n "${ors_engine_graphs_root_path}" ] && [ "${ors_engine_graphs_root_path}" = "/" ]; then
error "ors.engine.graphs_root_path is set to /. This is not allowed. Exiting."
else
success "ors.engine.graphs_root_path is not set to /"
fi

# Check that ors_engine_elevation_cache_path is not empty and not set to /
if [ -n "${ors_engine_elevation_cache_path}" ] && [ "${ors_engine_elevation_cache_path}" = "/" ]; then
error "ors.engine.elevation.cache_path is set to /. This is not allowed. Exiting."
else
success "ors.engine.elevation.cache_path is not set to /"
fi

# Check if the env ors.engine.source_file is not empty and set to /heidelberg.osm.gz and print an info message
if [ -n "${ors_engine_source_file}" ] && [ "${ors_engine_source_file}" = "/heidelberg.osm.gz" ]; then
success "Using the default heidelberg.osm.gz file: "${ors_engine_source_file}""
else
info "ors.engine.source_file is not set to /heidelberg.osm.gz. This is fine if you've provided your own .osm.pbf file: ${ors_engine_source_file}"
success "Using the default heidelberg.osm.gz file: \"${ors_engine_source_file}\""
fi

# Get the config file location and unset the original ENV to avoid accidental usage in the container
ors_config_location=${ORS_CONFIG_LOCATION:-""}
# Unset the ORS_CONFIG_LOCATION
unset ORS_CONFIG_LOCATION
# The config situation is difficult due to the recent ors versions.
# To ensure a smooth transition, we need to check if the user is using a .json file or a .yml file.
# If neither is the case and no environment variables are set, we need to print a migration info and default to the example-ors-config.env file.
# Check if ors_config_location is a .json file
if [[ "${ors_config_location}" = *.json ]]; then
# Print the above warning message in individual warning calls
warning "You're using a .json config file. This is deprecated and will be removed in the future."
print_migration_info="true"
elif [[ "${ors_config_location}" = *.yml ]]; then
warning "Using custom yml config: ${ors_config_location}"
warning "The env variables will have precedence over configuration variables from config files."
warning "Consider switching to configuring your container with environment variables."
print_migration_info="true"
success "Using yml config: ${ors_config_location}"
info "Any ENV variables will have precedence over configuration variables from config files."
# Get the ors_engine_graphs_root_path from the yaml file
elif [[ -n "${ors_engine_graphs_root_path}" ]] && [[ -n "${ors_engine_elevation_cache_path}" ]] && [[ -n "${ors_engine_source_file}" ]]; then
success "Using environment variables for configuration."
info "The necessary environment variables are set. Using the following configuration:"
info "ors.engine.graphs_root_path=${ors_engine_graphs_root_path}"
info "ors.engine.elevation.cache_path=${ors_engine_elevation_cache_path}"
info "ors.engine.source_file=${ors_engine_source_file}"
else
success "Using only environment variables for configuration."
fi

# Build graphs is only possible when not using a config file
if [[ -n "${ors_config_location}" ]] && [[ "${ors_build_graphs}" = "true" ]]; then
warning "BUILD_GRAPHS can not be used with config files, since we cannot safely determine the graph location."
warning "Please set BUILD_GRAPHS to False or use environment variables for configuration."
success "No config provided and the default environment variables are not set."
success "Defaulting to the example-ors-config.yml file."
ors_config_location="${ORS_HOME}/config/example-ors-config.yml"
print_migration_info="true"
ors_build_graphs="false"
elif [[ "${ors_build_graphs}" = "true" ]]; then
success "ORS configured with environment variables. BUILD_GRAPHS is safe to use."
fi

success "All relevant checks passed"
Expand Down Expand Up @@ -187,41 +184,76 @@ mkdir -p "${ORS_HOME}"/{files,logs,config,graphs,elevation_cache} || warning "Co
chown -R "$(whoami)" "${ORS_HOME}" || warning "Could not chown ${ORS_HOME}"
success "Populated ORS_HOME=${ORS_HOME} with the default folders: files, logs, config, graphs, elevation_cache"

# Remove existing graphs if BUILD_GRAPHS is set to true
if [ "${ors_build_graphs}" = "true" ]; then
warning "BUILD_GRAPHS is set to true. Trying to remove existing graphs."
# Warn if ors.engine.graphs_root_path is not set or empty
if [ -z "${ors_engine_graphs_root_path}" ]; then
warning "ors.engine.graphs_root_path ENV not set or empty. Skipping cleanup."
elif [ -d "${ors_engine_graphs_root_path}" ]; then
# Check the ors.engine.graphs_root_path folder exists
info "Remove graph at ${ors_engine_graphs_root_path}/*."
rm -rf "${ors_engine_graphs_root_path:?}"/* || warning "Could not remove ${ors_engine_graphs_root_path}"
else
info "ors.engine.graphs_root_path=${ors_engine_graphs_root_path} does not exist (yet). Skipping cleanup."
fi
# Create the graphs folder again
mkdir -p "${ors_engine_graphs_root_path}" || warning "Could not populate graph folder at ${ors_engine_graphs_root_path}"
fi

# check if the example-ors-config.env exists in the config folder or if the example-ors-config.env in the root folder has changed
if [ ! -f "${ORS_HOME}/config/example-ors-config.env" ] || ! cmp -s "/example-ors-config.env" "${ORS_HOME}/config/example-ors-config.env"; then
success "Update the example-ors-config.env at ${ORS_HOME}/config/example-ors-config.env"
cp -f "/example-ors-config.env" "${ORS_HOME}/config/example-ors-config.env" || warning "Could not copy example-ors-config.env to ${ORS_HOME}/config"
success "Updated the example-ors-config.env at ${ORS_HOME}/config/example-ors-config.env"
print_migration_info="true"
else
success "The example-ors-config.env in ${ORS_HOME}/config is up to date"
fi

# Check if the example-ors-config.yml exists in the config folder or if the example-ors-config.yml in the root folder has changed
if [ ! -f "${ORS_HOME}/config/example-ors-config.yml" ] || ! cmp -s "/example-ors-config.yml" "${ORS_HOME}/config/example-ors-config.yml"; then
success "Update the example-ors-config.yml at ${ORS_HOME}/config/example-ors-config.yml"
cp -f "/example-ors-config.yml" "${ORS_HOME}/config/example-ors-config.yml" || warning "Could not copy example-ors-config.yml to ${ORS_HOME}/config"
success "Updated the example-ors-config.yml at ${ORS_HOME}/config/example-ors-config.yml"
print_migration_info="true"
else
success "The example-ors-config.yml in ${ORS_HOME}/config is up to date"
fi

# Copy the heidelberg.osm.gz file to the files folder if it doesn't exist
if [ ! -f "${ORS_HOME}/files/example-heidelberg.osm.gz" ]; then
success "Copy example-heidelberg.osm.gz to ${ORS_HOME}/files/example-heidelberg.osm.gz"
cp -f "/heidelberg.osm.gz" "${ORS_HOME}/files/example-heidelberg.osm.gz" || warning "Could not copy example-heidelberg.osm.gz to ${ORS_HOME}/files/"
else
success "The example-heidelberg.osm.gz in ${ORS_HOME}/files is up to date"
fi


# Check if ors_engine_graphs_root_path is not set and config is a .yml file
if [[ -z "${ors_engine_graphs_root_path}" ]] && [[ "${ors_config_location}" = *.yml ]]; then
ors_engine_graphs_root_path=$( yq -r '.ors.engine.graphs_root_path' "${ors_config_location}" )
# Check if ors_engine_graphs_root_path is null
if [ "${ors_engine_graphs_root_path}" = null ]; then
ors_engine_graphs_root_path=""
fi
fi
# Check if ors_engine_graphs_root_path is not set and config is a .json
if [[ -z "${ors_engine_graphs_root_path}" ]] && [[ "${ors_config_location}" = *.json ]]; then
ors_engine_graphs_root_path=$( jq -r '.ors.services.routing.profiles.default_params.graphs_root_path' "${ors_config_location}" )
# Check if ors_engine_graphs_root_path is null
if [ "${ors_engine_graphs_root_path}" = null ]; then
ors_engine_graphs_root_path=""
fi
fi

if [ -n "${ors_engine_graphs_root_path}" ]; then
success "Found graphs root path: ${ors_engine_graphs_root_path}"
else
warning "No graphs root path found in config files and the environment. It will be set to the default: ${ORS_HOME}/graphs"
ors_engine_graphs_root_path="${ORS_HOME}/graphs"
fi

# Remove existing graphs if BUILD_GRAPHS is set to true
if [ "${ors_build_graphs}" = "true" ]; then
# Warn if ors.engine.graphs_root_path is not set or empty
if [ -z "${ors_engine_graphs_root_path}" ]; then
warning "ors.engine.graphs_root_path ENV not set or empty. Skipping cleanup."
elif [ -d "${ors_engine_graphs_root_path}" ]; then
# Check the ors.engine.graphs_root_path folder exists
rm -rf "${ors_engine_graphs_root_path:?}"/* || warning "Could not remove ${ors_engine_graphs_root_path}"
success "Removed graphs at ${ors_engine_graphs_root_path}/*."
else
info "${ors_engine_graphs_root_path} does not exist (yet). Skipping cleanup."
fi
# Create the graphs folder again
mkdir -p "${ors_engine_graphs_root_path}" || warning "Could not populate graph folder at ${ors_engine_graphs_root_path}"
fi




# Print the migration info if print_migration_info is set to true but not if PRINT_MIGRATION_INFO is set to False
if [ "${print_migration_info}" = "true" ] && [ "${PRINT_MIGRATION_INFO}" != "false" ]; then
echo "##########################################"
Expand All @@ -246,17 +278,9 @@ echo "# ORS startup phase #"
echo "#####################"
# Start the jar with the given arguments and add the ORS_HOME env var
success "Starting ORS with the following command:"
special_env_vars=""
# If ORS_CONFIG_LOCATION is set, add it to the special_env_vars
if [ -n "${ors_config_location}" ]; then
special_env_vars="${special_env_vars} -DORS_CONFIG_LOCATION=${ors_config_location}"
fi
# If ORS_HOME is set, add it to the special_env_vars
if [ -n "${ORS_HOME}" ]; then
special_env_vars="${special_env_vars} -DORS_HOME=${ORS_HOME}"
fi

# Print the full command
info "java ${JAVA_OPTS} ${CATALINA_OPTS} ${special_env_vars} -jar ${jar_file}"
info "java ${JAVA_OPTS} ${CATALINA_OPTS} -jar ${jar_file}"
# shellcheck disable=SC2086 # we need word splitting here
export ORS_HOME=${ORS_HOME}
exec java ${JAVA_OPTS} ${CATALINA_OPTS} ${special_env_vars} -jar "${jar_file}" "$@"
export ORS_CONFIG_LOCATION=${ors_config_location}
exec java ${JAVA_OPTS} ${CATALINA_OPTS} -jar "${jar_file}" "$@"

0 comments on commit 3a68457

Please sign in to comment.