Docker container

Introduction

This is the documentation of the official Apache Hop docker container published on:

It’s a Hop Docker image supporting both short-lived and long-lived setups. A short-lived setup executes a pipeline or workflow and stops right after. A long-lived setup starts a Hop server and waits for work.

This page describes apache/hop (hop-run and Hop Server). For the Hop Web GUI image (apache/hop-web), including which folders to persist across upgrades, see Hop Web in Docker: persistence and upgrades.

Operating system

The docker container runs a minimal Linux system called Alpine. OpenJDK version 21 is then used to execute Apache Hop. The Linux user used to execute in the container is hop and the group is hop as well.

Container Folder Structure

Folder Description

/opt/hop

The installation location of the hop client package.

/files

This volume has read-write permissions for Linux user hop. You can use it for example to mount a folder that contains the hop and project config as well as the workflows and pipelines. Do not persist project files only under /opt/hop; that tree is replaced when you pull a new image.

/home/hop

The initial working directory location of the docker container.

Environment Variables

You can provide values for the following environment variables:

Environment Variable Default Description

HOP_LOG_LEVEL

Basic

The log level. Use one of: None, Error, Minimal, Basic, Detailed, Debug or Rowlevel.

HOP_LOG_PATH

/opt/hop/hop.err.log

The file path to the Hop log file.

HOP_CONFIG_FOLDER

Folder that contains hop-config.json (project and environment registrations, GUI settings). Leave unset to use the image default (config/ under the Hop install). Point this at a mounted volume if the configuration must survive replacing the container. See Hop Web in Docker for the Hop Web layout; the same variable applies here.

HOP_AUDIT_FOLDER

Folder for GUI / execution audit data. Point this at a mounted volume to keep it across container recreation.

HOP_PROJECT_NAME

Name of the Hop project to create in the container. You also need to specify the HOP_PROJECT_FOLDER variable. If you do not set this variable, no project or environment will be created.

HOP_PROJECT_FOLDER

HOP_PROJECT_DIRECTORY (Deprecated)

Path to the home of the Hop project.

HOP_PROJECT_CONFIG_FILE_NAME

project-config.json

Name of the project config file.

HOP_PARENT_PROJECT_NAME

Optional name of a one-level parent project to register in the container before the main project. Required together with HOP_PARENT_PROJECT_FOLDER when the main project inherits metadata from another project (parentProjectName in project-config.json). Only a single parent level is supported in the image; deeper chains need a custom entrypoint.

HOP_PARENT_PROJECT_FOLDER

Path to the home of the parent Hop project inside the container. Required together with HOP_PARENT_PROJECT_NAME. Mount both parent and child project folders into the container.

HOP_PARENT_PROJECT_CONFIG_FILE_NAME

project-config.json

Name of the parent project config file (relative to the parent home).

HOP_ENVIRONMENT_NAME

The name of the Hop environment to create in the container. If you do not set this variable, no environment will be created. When using an environment a project has to be created too

HOP_ENVIRONMENT_CONFIG_FILE_NAME_PATHS

This is a comma separated list of paths to environment config files (including filename and file extension).

HOP_OPTIONS

-XX:+AggressiveHeap

Any JRE options you want to set. The -XX:+AggressiveHeap option tells the container to use all memory assigned to it.

HOP_SHARED_JDBC_FOLDERS

Comma separated list to locations where JDBC drivers live (default is /lib/jdbc).

HOP_DRIVERS_DOWNLOAD

Comma separated list of JDBC drivers to download and install on container start, before Hop is launched. Each entry is a driver id (run hop driver list to see them), optionally followed by :version, for example oracle,mariadb:3.4.1,mysql. See Downloading JDBC drivers.

HOP_DRIVERS_ACCEPT_LICENSE

Set to true to accept the vendor license of restricted (Category X) drivers such as Oracle, MySQL, MariaDB and DB2. Required to download those drivers, since Apache Hop does not distribute them.

HOP_DRIVERS_MAVEN_REPO

Optional Maven repository base URL to download the drivers from (defaults to Maven Central). Point this at an internal Nexus or Artifactory for air-gapped environments.

HOP_CUSTOM_ENTRYPOINT_EXTENSION_SHELL_FILE_PATH

Optional path to a custom entrypoint extension script file. You can use this for example to fetch Hop project files from S3 or gitlab.

HOP_SYSTEM_PROPERTIES

The system properties that should be set during execution. You can specify the properties as a comma separated list, e.g. PROP1=xxx,PROP2=yyy

HOP_START_ACTION

The name of the Workflow Action you want the Workflow to start from

HOP_CONFIG_OPTIONS

If you specify a value for this variable, they will be used to execute hop-conf.sh right before execution of the short- or long-lived container. You can use it for example to configure values for keys, plugins, and so on. See Cloud storage credentials for the cloud storage options. Specify multiple options separated by spaces. Enclose values containing spaces in quotes, for example --set-variable=FOO=bar --describe-variable=FOO="An example variable".

HOP_COMMAND

This is the Hop sub-command to execute like for example python, arrow, encrypt, or doc.

HOP_COMMAND_PARAMETERS

The parameters (options) to specify for the Hop command you want to execute, for example the host and port options for the Python and Arrow servers.

Here are the variables for short-lived containers, to execute a workflow or pipeline:

Environment Variable Required Description

HOP_FILE_PATH

Yes

The path to the Hop workflow or pipeline to execute. If you configured a project you can use a relative path to the project home folder.

HOP_RUN_CONFIG

Yes

The name of the Hop run configuration to use to execute your pipeline or workflow.

HOP_RUN_PARAMETERS

No

Optionally, you can specify the parameters that should be passed to the pipeline or workflow you are executing. You can specify them as a comma separated list, e.g. PARAM_1=aaa,PARAM_2=bbb.

HOP_RUN_METADATA_EXPORT

No

You can specify a metadata export file here which will contain all required metadata elements. See also the metadata export option in the Hop Conf tool.

Below are the variables you can use for a long-lived container, running Hop Server:

Environment Variable Default value Description

HOP_SERVER_HOSTNAME

0.0.0.0 (listen to anything)

The IP address the server will listen to.

HOP_SERVER_PORT

8080

The port the server will listen to.

HOP_SERVER_SHUTDOWN_TIMEOUT

0

The maximum number of seconds to wait for running pipelines and workflows to finish when the server shuts down (for example on a SIGTERM from the container runtime). 0 shuts down immediately.

HOP_SERVER_AUTH

true

Disable/Enable the authentication used for hop server

HOP_SERVER_USER

cluster

The username to log into the Hop server.

HOP_SERVER_PASS

cluster

The password to log into the Hop server

HOP_SERVER_METADATA_FOLDER

(optional)

You can point to a folder containing metadata JSON files which are then available to the server.

HOP_SERVER_MAX_LOG_LINES

0 (keep all logging in memory)

The maximum number of log lines kept in memory by the server.

HOP_SERVER_MAX_LOG_TIMEOUT

1440 (clean up log lines after one day)

The time (in minutes) it takes for a log line to be cleaned up in memory.

HOP_SERVER_MAX_OBJECT_TIMEOUT

1440 (a day)

The time (in minutes) it takes for a pipeline or workflow execution to be removed from the server status.

HOP_SERVER_KEYSTORE

(optional)

The path to the Java keystore file you want to use to run the Hop server with SSL enabled to support https.

HOP_SERVER_KEYSTORE_PASSWORD

(optional)

The password of the Java keystore file you want to use to run the Hop server with SSL enabled to support https

HOP_SERVER_KEY_PASSWORD

(optional)

The password of the key if you want to use to run the Hop server with SSL enabled. If both passwords are the same you can omit setting this variable.

Updating the Hop docker container image

Make sure to get the latest updates for the Hop image by pulling them:

bash
docker pull apache/hop:<tag>

If you do not specify a value for :<tag> the value latest will be taken. Latest will contain the last officially released version of Apache Hop. You can also specify Development as a tag. That image will contain the last built Development snapshot of Apache Hop. rxq7777

How to run the Container

Running the short-lived container

The most common use case will be that you run a short-lived container to just complete one Hop workflow or pipeline. If CI already baked the project into the image, this is often all you need in production: a scheduler starts the container, hop-run finishes, the container exits — no long-lived Hop Server. See Skip Hop Server: short-lived containers and Scheduling workflows and pipelines.

The first example below runs the sample switch-case-basic.hpl pipeline from the samples project.

Replace <tag> with latest, Development or a release tag, and replace <HOP_SAMPLE_PROJECT_PATH> with the path to the config/projects/samples folder in your Hop installation to mount that folder as a volume. This will make the samples project folder available as the /files folder in the container.

bash
docker run -it --rm \
  --env HOP_LOG_LEVEL=Basic \
  --env HOP_FILE_PATH='${PROJECT_HOME}/transforms/switch-case-basic.hpl' \
  --env HOP_PROJECT_FOLDER=/files \
  --env HOP_PROJECT_NAME=samples \
  --env HOP_RUN_CONFIG=local \
  --name hop-test-container \
  -v <HOP_SAMPLE_PROJECT_PATH>:/files \
  apache/hop:<tag>

The second example below runs a workflow.

In addition to the most basic example below, this example adds the environment, based on HOP_ENVIRONMENT_NAME, HOP_ENVIRONMENT_CONFIG_FILE_NAME_PATHS and run parameters with HOP_RUN_PARAMETERS

bash
docker run -it --rm \
  --env HOP_LOG_LEVEL=Basic \
  --env HOP_FILE_PATH='${PROJECT_HOME}/pipelines-and-workflows/main.hwf' \
  --env HOP_PROJECT_FOLDER=/files/project \
  --env HOP_PROJECT_NAME=project-a \
  --env HOP_ENVIRONMENT_NAME=project-a-test \
  --env HOP_ENVIRONMENT_CONFIG_FILE_NAME_PATHS=/files/config/project-a-test.json \
  --env HOP_RUN_CONFIG=local \
  --env HOP_RUN_PARAMETERS=PARAM_LOG_MESSAGE=Hello,PARAM_WAIT_FOR_X_MINUTES=1 \
  -v /path/to/local/dir:/files \
  --name my-simple-hop-container \
  apache/hop:<tag>

Projects with a parent

When a project inherits metadata from another project (parentProjectName in project-config.json), both project homes must be mounted and the parent must be registered in the container as well.

Set HOP_PARENT_PROJECT_NAME and HOP_PARENT_PROJECT_FOLDER (optionally HOP_PARENT_PROJECT_CONFIG_FILE_NAME). The entrypoint registers the parent first, then the main project with --project-parent, so parent metadata is merged into HOP_METADATA_FOLDER and the built-in variables PARENT_PROJECT_HOME / PARENT_PROJECT_NAME resolve correctly.

Only one parent level is supported through these environment variables.

bash
docker run -it --rm \
  --env HOP_LOG_LEVEL=Basic \
  --env HOP_FILE_PATH='jobs/load_projectB_data.hwf' \
  --env HOP_PROJECT_FOLDER=/files/projects/projectB \
  --env HOP_PROJECT_NAME=projectB \
  --env HOP_PARENT_PROJECT_FOLDER=/files/projects/projectA \
  --env HOP_PARENT_PROJECT_NAME=projectA \
  --env HOP_ENVIRONMENT_NAME=prod_docker_exec \
  --env HOP_ENVIRONMENT_CONFIG_FILE_NAME_PATHS=/files/projects/projectB/prod_docker_exec-config.json \
  --env HOP_RUN_CONFIG=docker_run_config \
  -v /path/to/projects:/files/projects \
  --name docker-exec-projectB \
  apache/hop:<tag>

The value of HOP_PARENT_PROJECT_NAME should match parentProjectName in the child project’s project-config.json.

Running the long-lived container (server)

If you need a long-lived container, this option is also available.

For more information on the long-lived container please also see the Hop Server documentation as it describes what can be done using the Hop Server.

To ship a git-hosted project with the image (CI builds FROM apache/hop, copies the project to /your-project, then rolls the container) see Project in a Docker image.

Run this command to start a Hop Server in a docker container:

bash
docker run -it --rm \
  --env HOP_SERVER_USER=admin \
  --env HOP_SERVER_PASS=admin \
  --env HOP_SERVER_PORT=8181 \
  --env HOP_SERVER_PORT=8180 \
  --env HOP_SERVER_HOSTNAME=0.0.0.0 \
  -p 8080:8080 \
  -p 8181:8181 \
  -p 8180:8180 \
  --name my-hop-server-container \
 apache/hop:<tag>
localhost is a loopback to your machine, which may be the container but not the host (your laptop or server where your run the container). Use 0.0.0.0 instead to listen on all available interfaces.

Hop Server is designed to receive all variables and metadata from executing clients. This means it needs little to no configuration to run.

If you want to use the web-services functionality additional information on how to configure your webserver can be found on the user manual Web Service page. For this to work properly the HOP_SERVER_METADATA_FOLDER variable has to be set too.

When started can then access the hop-server UI from your host at http://0.0.0.0:8181 or http://localhost:8181

Running a Hop command

You can run any Hop command with the variables HOP_COMMAND and HOP_COMMAND_PARAMETERS. Here is an example of running the Python Hop server:

bash
docker run \
  -p 25333:25333 \
  -v /home/hop/projects/demo:/demo \
  -e HOP_PROJECT_FOLDER=/demo \
  -e HOP_PROJECT_NAME=demo \
  -e HOP_COMMAND=python \
  -e HOP_COMMAND_PARAMETERS="--gateway-ip-address 0.0.0.0 --gateway-port 25333" \
  apache/hop:<tag>

In this example, a project is created in the container and exposed in the Hop Python server. This gives you access to project metadata or similarly environment configurations.

The option to run commands is available from Hop version 2.18.

Downloading JDBC drivers

Apache Hop ships the JDBC drivers it is allowed to redistribute (PostgreSQL, MS SQL Server, Snowflake, …​). Drivers with a restricted license - Oracle, MySQL, MariaDB, IBM DB2 and others - are not bundled and have to be added to the lib/jdbc folder yourself.

The container can do this for you on start-up. Set HOP_DRIVERS_DOWNLOAD to a comma separated list of driver ids and the entrypoint runs hop driver install for each one before Hop is launched, so the drivers are picked up by the normal lib/jdbc scan. Each entry is a driver id, optionally followed by :version. Run hop driver list (inside the container or a local Hop install) to see the available ids.

Because the restricted drivers are downloaded from the vendor / Maven Central under the vendor’s license, you must explicitly accept that license by setting HOP_DRIVERS_ACCEPT_LICENSE=true. Without it, restricted drivers are skipped with an error. Apache Hop neither hosts nor redistributes these drivers; obtaining them this way is your action under the vendor’s terms.

Download the Oracle and MariaDB drivers in a short-lived container
shell
docker run -it --rm \
  --env HOP_DRIVERS_DOWNLOAD="oracle,mariadb:3.4.1" \
  --env HOP_DRIVERS_ACCEPT_LICENSE=true \
  --env HOP_PROJECT_FOLDER=/project \
  --env HOP_PROJECT_NAME=my-project \
  --env HOP_FILE_PATH='${PROJECT_HOME}/main.hpl' \
  --env HOP_RUN_CONFIG=local \
  --mount type=bind,source=/path/to/project,target=/project \
  apache/hop

For air-gapped environments, point the download at an internal Maven mirror with HOP_DRIVERS_MAVEN_REPO:

shell
docker run -it --rm \
  --env HOP_DRIVERS_DOWNLOAD="oracle" \
  --env HOP_DRIVERS_ACCEPT_LICENSE=true \
  --env HOP_DRIVERS_MAVEN_REPO=https://nexus.internal/repository/maven-public/ \
  ... \
  apache/hop

The download is supported by the client/server image (running pipelines, workflows or hop-server) and the Hop web image. The drivers and their transitive dependencies are written to HOP_SHARED_JDBC_FOLDERS (default lib/jdbc). If the container filesystem is read-only, make sure that folder is writable, for example by mounting a volume over it.

HOP_DRIVERS_DOWNLOAD is available from Hop version 2.19.

Downloading Marketplace plugins

The Docker container can install optional or third-party plugins from the Hop marketplace or a corporate Maven repository (e.g. Sonatype Nexus, JFrog Artifactory) on startup before Hop starts. The stock image does this at runtime, so a custom image is not required. A repeated start skips a plugin when its receipt version matches and its files are still present. Every coordinate is installed by one hop marketplace install invocation.

Set HOP_PLUGINS_DOWNLOAD to a comma-separated list of plugin coordinates. Each entry can be:

  • An artifact id or short name (e.g. hop-tech-parquet, datavault), when a browsable repository or the Apache catalog can resolve it.

  • An artifact id with version (e.g. hopper-edw:0.10.0), with the same limitation.

  • Full Maven coordinates (e.g. org.hopper:hopper-edw:0.10.0).

HOP_PLUGINS_MAVEN_REPO is the repository to try first. The configured Apache and Maven Central repositories are still used when a plugin is not in that repository, so a private plugin and an Apache optional plugin can be requested together. Pass a full groupId:artifactId:version for the private one when that repository cannot be browsed.

A repository that cannot be browsed (a plain Maven repository, or HOP_PLUGINS_REPO_TYPE=maven) does not accept a short name. The install fails and asks for groupId:artifactId:version instead of guessing org.apache.hop. HOP_PLUGINS_REPO_TYPE selects the browse API: auto (default), nexus, forgejo, jfrog, or maven. auto infers Nexus, Artifactory, or Forgejo from the URL.

HOP_PLUGINS_REPO_ID is the id of that repository (default corporate-repo). The entrypoint does not put the password on the hop command line. It exports HOP_MARKETPLACE_<ID>_USERNAME and either HOP_MARKETPLACE_<ID>_PASSWORD or, when the auth type is token, HOP_MARKETPLACE_<ID>_TOKEN. For the default id those names are HOP_MARKETPLACE_CORPORATE_REPO_USERNAME, HOP_MARKETPLACE_CORPORATE_REPO_PASSWORD and HOP_MARKETPLACE_CORPORATE_REPO_TOKEN. Any other id is uppercased, and every character that is not a letter or digit becomes an underscore. You can set those variables yourself instead of HOP_PLUGINS_REPO_USERNAME and HOP_PLUGINS_REPO_PASSWORD.

  • HOP_PLUGINS_REPO_USERNAME: Basic auth username.

  • HOP_PLUGINS_REPO_PASSWORD: Basic auth password or bearer token.

  • HOP_PLUGINS_REPO_AUTH_TYPE: auto (default), none, basic, or token.

The global HOP_MARKETPLACE_USERNAME and HOP_MARKETPLACE_PASSWORD variables are also picked up.

Install a private plugin and an Apache plugin, keeping them on a volume
shell
docker run -it --rm \
  --env HOP_PLUGINS_DOWNLOAD="org.hopper:hopper-edw:0.10.0,hop-tech-parquet" \
  --env HOP_PLUGINS_MAVEN_REPO="https://repository.data-hopper.com/repository/hop-community-plugins/" \
  --env HOP_PLUGINS_REPO_ID=data-hopper \
  --env HOP_PLUGIN_BASE_FOLDERS=/opt/hop/plugins,/files/plugins \
  --env HOP_PROJECT_FOLDER=/project \
  --env HOP_PROJECT_NAME=my-project \
  --env HOP_FILE_PATH='${PROJECT_HOME}/main.hpl' \
  --env HOP_RUN_CONFIG=local \
  --mount type=bind,source=/path/to/project,target=/project \
  --mount type=volume,source=hop-plugins,target=/files/plugins \
  apache/hop

HOP_PLUGIN_BASE_FOLDERS replaces the default plugins folder. Include the image plugins path and the mounted path, as in the example. The install is written to the first writable directory in that list that is not the image install itself. Shared lib/core jars are written next to that plugins folder and added to the classpath of hop, hop-run and hop-server.

Plugins written only into the container filesystem are not kept when the container is removed. They are kept when that install directory is a mounted volume, or when the install happened while building an image.

The Hop web image installs marketplace plugins at startup as well. The image rewrites the hop classpath the same way as hop-run.sh, so it includes WEB-INF/lib (where the Hop jars live) as well as lib/core. Shared jars from a plugin are installed into WEB-INF/lib so Tomcat and hop both load them. Plugin folders still follow HOP_PLUGIN_BASE_FOLDERS.

Building a derived image is optional. It avoids the download on every start when a custom image is acceptable:

dockerfile
FROM apache/hop:2.20.0
RUN /opt/hop/hop marketplace install \
    org.hopper:hopper-edw:0.10.0 \
    org.apache.hop:hop-tech-parquet:2.20.0 \
    --repo-url https://repository.data-hopper.com/repository/hop-community-plugins/ \
    --repo-id data-hopper

If you maintain a declarative Hop environment install spec (hop-env.yaml) or repository definition (hop-marketplace-repo.yaml), you can point to it directly using HOP_PLUGINS_ENV_FILE:

shell
docker run -it --rm \
  --env HOP_PLUGINS_ENV_FILE=https://raw.githubusercontent.com/ProjectDataHopper/hopper-edw/main/hop-marketplace-repo.yaml \
  ... \
  apache/hop
HOP_PLUGINS_DOWNLOAD is available from Hop version 2.20.

Cloud storage credentials

The cloud file systems in Hop (s3://, gs://, azure://, googledrive://, dropbox://) get their default credentials from one of two places:

  • the standard environment variables of the provider’s SDK (AWS and Google Cloud), or

  • the Hop configuration (hop-config.json), which you set in the container with hop-conf options in HOP_CONFIG_OPTIONS.

The sample file docker/hop.env.sample lists the options below with comments. Copy it, uncomment what you need and pass it with --env-file:

bash
docker run -it --rm \
  --env-file hop.env \
  -v /path/to/project:/files \
  -v /path/to/keys:/keys:ro \
  apache/hop:<tag>

docker run --env-file takes everything after the first = literally, quotes included, so do not wrap values in quotes. A line with only a variable name, for example AWS_SECRET_ACCESS_KEY, copies that variable from the shell that runs docker run.

The sample is for docker run --env-file only. Do not use it as a Docker Compose env_file: Compose strips quotes and expands ${…​}, which breaks the quoted Azure key and HOP_FILE_PATH.

File system Environment variables HOP_CONFIG_OPTIONS

Amazon S3 (s3://)

AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, AWS_REGION. Or mount a credentials file with -v ~/.aws:/home/hop/.aws:ro and set AWS_PROFILE.

Not needed.

Google Cloud Storage (gs://)

GOOGLE_APPLICATION_CREDENTIALS, pointing to a mounted service account key file.

--google-cloud-service-account-key-file=/keys/key.json

Azure Storage (azure://)

None.

--azure-account=<account> --azure-key=<key>, optionally --azure-emulator=<url>

Google Drive (googledrive://)

None.

--google-drive-credentials-file=<file> --google-drive-tokens-folder=<folder>

Dropbox (dropbox://)

None.

--dropbox-access-token=<token>

HOP_CONFIG_OPTIONS is a single variable. To configure more than one file system, put all options on one line, separated by spaces:

properties
HOP_CONFIG_OPTIONS=--azure-account=mystorageaccount --azure-key="Encrypted 2be98..." --dropbox-access-token=my-token

The Azure key may be encrypted with hop-encrypt.sh -hop <key>. The result contains a space, so quote it as shown above.

Google Drive needs a token that is created by an interactive browser login. Log in once with Hop GUI on a desktop, then mount the credentials file and the tokens folder into the container. The credentials file can stay on the read-only /keys mount. Hop writes to the tokens folder, so mount it read-write and make it owned by uid 501, the hop user in the image:

bash
chown -R 501 /path/to/google-drive-tokens

docker run -it --rm \
  --env-file hop.env \
  -v /path/to/keys:/keys:ro \
  -v /path/to/google-drive-tokens:/home/hop/google-drive-tokens \
  apache/hop:<tag>

with --google-drive-credentials-file=/keys/google-drive-credentials.json --google-drive-tokens-folder=/home/hop/google-drive-tokens in HOP_CONFIG_OPTIONS.

Named connections

Connections that are defined as metadata in your project, such as S3, MinIO, Azure Storage or Google Cloud Storage connections, are read from the project and not from the environment file.

  • An S3 connection with the Default (environment / instance profile) authentication type uses the AWS_* variables from the table above.

  • An Azure connection with the Managed Identity authentication type also accepts a service principal through AZURE_CLIENT_ID, AZURE_TENANT_ID and AZURE_CLIENT_SECRET.

Other connection fields can use Hop variables such as ${S3_SECRET_KEY}. Container environment variables are not Hop variables. Set them in the environment configuration file (HOP_ENVIRONMENT_CONFIG_FILE_NAME_PATHS) or pass them as system properties with HOP_SYSTEM_PROPERTIES.

Keeping secrets safe

Anyone who can run docker inspect on the container can read its environment variables, including the values in HOP_CONFIG_OPTIONS. hop-conf also writes those values to hop-config.json inside the container. The values in HOP_CONFIG_OPTIONS also end up in the container log (docker logs): the start-up script prints the variable, and the Azure key is logged when it is set.

  • Prefer mounted, read-only key files over keys in environment variables.

  • Leave secrets out of the environment file and copy them from your shell, as described above.

  • Use a Variable Resolver to read secrets from AWS Secrets Manager, Azure Key Vault, Google Secret Manager or HashiCorp Vault at runtime.

Hop Web image

The apache/hop-web image does not read HOP_CONFIG_OPTIONS. The provider SDK variables (AWS_*, GOOGLE_APPLICATION_CREDENTIALS) work as described above. For Azure, Google Drive and Dropbox, set the defaults in the Plugins section of the configuration perspective in Hop Web. They are stored in hop-config.json, so keep that file on a persistent volume. See Hop Web in Docker.

Custom Entrypoint Extension Shell Script

To make the Hop Docker image even more flexible, we added a HOP_CUSTOM_ENTRYPOINT_EXTENSION_SHELL_FILE_PATH variable that accepts a path to a custom shell script (that you provide).This shell script will run when you start the container before your Hop project is registered with the container’s Hop config and before your Hop workflow or pipeline gets kicked off. This feature might come in handy when you want to run some custom logic upfront, e.g. source Hop project files from S3 or clone them from GitHub.

The custom shell file can be provided in several ways (this is not a full list):

  • via the mount point (/files)

  • You create your own Dockerfile, define this image as the base and then use the COPY instruction to copy your custom shell file in your Docker image.

For the last scenario mentioned, it could be something like this:

We create a simple bash script called clone-git-repo.sh in a sub-folder called resources:

shell
#!/bin/bash
cd /home/hop
git clone ${GIT_REPO_URI}
chown -R hop:hop /home/hop/${GIT_REPO_NAME}

We also make it parameter-driven, so it any other team can use it.We create our custom Dockerfile like so:

dockerfile
FROM apache/hop:Development
ENV GIT_REPO_URI=https://...
# example value: https://github.com/diethardsteiner/apache-hop-minimal-project.git
ENV GIT_REPO_NAME=repo-name
# example value: apache-hop-minimal-project
USER root
RUN apk update \
  && apk add --no-cache git
# copy custom entrypoint extension shell script
COPY --chown=hop:hop ./resources/clone-git-repo.sh /home/hop/clone-git-repo.sh
USER hop

Note that apart from defining the new environment variables (that go in line with the parameters we defined in the clone-git-repo.sh earlier on ), we also COPY the clone-git-repo.sh file to user hop’s home folder.

Next let’s build a small script which builds our custom image and then tests it by spinning up a container and running a workflow:

shell
#!/bin/zsh

DOCKER_IMG_CHECK=$(docker images | grep ds/custom-hop)

if [ ! -z "${DOCKER_IMG_CHECK}" ]; then
  echo "removing existing ds/custom-hop image"
  docker rmi ds/custom-hop:latest
fi

docker build . -f custom.Dockerfile -t ds/custom-hop:latest

echo " ==== TESTING ====="


HOP_DOCKER_IMAGE=ds/custom-hop:latest
PROJECT_DEPLOYMENT_DIR=/home/hop/apache-hop-minimal-project

docker run -it --rm \
  --env HOP_LOG_LEVEL=Basic \
  --env HOP_FILE_PATH='${PROJECT_HOME}/main.hwf' \
  --env HOP_PROJECT_FOLDER=${PROJECT_DEPLOYMENT_DIR} \
  --env HOP_PROJECT_NAME=apache-hop-minimum-project \
  --env HOP_ENVIRONMENT_NAME=dev \
  --env HOP_ENVIRONMENT_CONFIG_FILE_NAME_PATHS=${PROJECT_DEPLOYMENT_DIR}/dev-config.json \
  --env HOP_RUN_CONFIG=local \
  --env HOP_CUSTOM_ENTRYPOINT_EXTENSION_SHELL_FILE_PATH=/home/hop/clone-git-repo.sh \
  --env GIT_REPO_URI=https://github.com/diethardsteiner/apache-hop-minimal-project.git \
  --env GIT_REPO_NAME=apache-hop-minimal-project \
  --name my-simple-hop-container \
  ${HOP_DOCKER_IMAGE}