Skip to content
This repository has been archived by the owner on Mar 19, 2024. It is now read-only.

baosystems/docker-dhis2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dhis2 image

This container image contains an entry-point script, bundled applications, and templates to generate configuration files for DHIS2 and Tomcat to streamline using DHIS2. The sample docker-compose.yml file allows for a "no-config" path to running DHIS2, as other bundled scripts can initialize the PostgreSQL database for you.

It also supports low-config clustering for running multiple Tomcat instances for a scalable, highly-available setup of DHIS2.

The container image default command is remco to generate the /opt/dhis2/dhis.conf and /usr/local/tomcat/conf/server.xml files from environment variables and then run catalina.sh run.

The container image and the sample Docker Compose file will work on amd64 and arm64 architectures, including support for Apple Silicon (M1/M2).

Example: Docker Compose

The included docker-compose.yml file provides a single-node experience with DHIS2 on Tomcat and PostgreSQL with PostGIS. Platform architectures amd64 and arm64 are supported.

The version of DHIS2 can be set in the .env file; see .env.example for an example.

See https://github.com/baosystems/docker-dhis2/pkgs/container/dhis2/versions for available versions of DHIS2.

Quick

Start

docker compose pull

docker compose up --detach

You can access the site through http://localhost:8080/

Watch logs

View existing logs and watch for new lines:

docker compose logs --follow

Press Ctrl+c to exit logs

Stop & Start

Stop the entire stack:

docker compose stop

Resume later with:

docker compose start

Delete All

Delete containers and data storage volumes:

docker compose down --volumes

Passwords

In this example, passwords are generated for the PostgreSQL database superuser (postgres) and the DHIS2 database user (dhis). The passwords should not be needed for common operations, but they can be accessed later via:

docker compose run --rm pass_init sh -c 'for i in pg_dhis pg_postgres ; do echo -n "pass_${i}.txt: "; cat "/pass_${i}/pass_${i}.txt"; echo; done'

Advanced

Recreate the database

You'll want an empty database for starting a new DHIS2 installation. Perform the steps below to remove existing data and re-initialize the database.

# Stop Tomcat
docker compose stop dhis2

# Drop and re-create the database using a helper script in the container image
docker compose run --rm dhis2_init db-empty.sh

# Start Tomcat
docker compose start dhis2

# Watch Tomcat logs (press Ctrl+c to exit logs)
docker compose logs --follow --tail='10' dhis2

Load a backup file from DHIS2

Sample database files from databases.dhis2.org contain the entire database and require superuser permissions on the database to import. The following will use an empty database and "convert" it to match the least-privilege approach used in this setup.

# Download database file to your system
wget -nc -O dhis2-db-sierra-leone.sql.gz https://databases.dhis2.org/sierra-leone/2.39/dhis2-db-sierra-leone.sql.gz

# Stop Tomcat
docker compose stop dhis2

# Drop and re-create the database using the db-empty.sh helper script
docker compose run --rm dhis2_init db-empty.sh

# Import the database backup into the empty database
gunzip -c dhis2-db-sierra-leone.sql.gz | docker compose exec -T database psql -q -v 'ON_ERROR_STOP=1' --username='postgres' --dbname='dhis2'

# Initialize the new database
docker compose run --rm --env DHIS2_INIT_FORCE=1 dhis2_init dhis2-init.sh

# Start Tomcat
docker compose start dhis2

Export the database to a file on your system

An included helper script will run pg_dump without generated tables and some other changes to increase import compatibility with other systems.

# Stop Tomcat
docker compose stop dhis2

# Export the database using the db-export.sh helper script and compress with gzip
docker compose run --rm dhis2_init db-export.sh | gzip > export.sql.gz

# Start Tomcat
docker compose start dhis2

Upgrade DHIS2 version

If the container tag changes in an updated copy of the Compose file, or if the .env file is changed, run docker compose up again to remove the containers with old images in favor of the new ones. Because two versions of DHIS2 should not be running at the same time, stop the dhis2 containers first.

# Let's say you started with 2.38.2:

cat > .env <<'EOF'
DHIS2_TAG=2.38.2
EOF

docker compose up --detach

# Later, upgrade to 2.39.1.1:

cat > .env <<'EOF'
DHIS2_TAG=2.39.1.1
EOF

docker compose rm --force --stop dhis2 dhis2_init

docker compose pull

docker compose up --detach --remove-orphans

Features

Entry point

The following occur when using docker-entrypoint.sh as the entry point and the command starts with remco, which are the defaults:

  • If DHIS2_DATABASE_PASSWORD is empty or not set, the contents of DHIS2_DATABASE_PASSWORD_FILE will be set as DHIS2_DATABASE_PASSWORD.

  • If DHIS2_REDIS_PASSWORD is empty or not set, the contents of DHIS2_REDIS_PASSWORD_FILE will be set as DHIS2_REDIS_PASSWORD.

  • If SYSTEM_IP is empty or not set, it will be exported as the output of hostname --ip-address.

The following occur when using docker-entrypoint.sh as the entry point (the image default) and the command starts with remco (the image default) or catalina.sh:

  • If the detected user is the root user, paths /opt/dhis2/files, /opt/dhis2/logs, and /usr/local/tomcat/logs will be owned by tomcat and the user will be given write access. This is to ensure the tomcat user always has the ability to write, even if those paths are volume mounts.

  • If the detected user is the root user, the full command will be run as the tomcat user via gosu.

If the command does not start with remco (the image default) or catalina.sh, then it will be run with exec so it can proceed as pid 1.

Remco

The default command is remco, NOT catalina.sh run. Remco is used to create dhis.conf and start Tomcat. It will periodically check to see if dhis.conf needs updated (primarily to support Ehcache clusters), and if so, restart Tomcat.

dhis2-init

When the container command is set to dhis2_init.sh, each script in /usr/local/share/dhis2-init.d/ will be run. If /dhis2-init.progress/ is shared with other instances of dhis2-init, only one instance of a script will be performed at a time. Environment variable DHIS2_INIT_SKIP can be set as a comma-seperated value for files in /usr/local/share/dhis2-init.d/ to skip. See docker-compose.yml in this repository for example use.

NOTE: If dhis2_init.sh is not run, it is the responsibility of the operator to ensure the database is initiated and ready prior to being used by DHIS2.

The following environment variables are set in dhis2_init.sh but can be changed as necessary:

  • DHIS2_DATABASE_NAME (default: "dhis2")
  • DHIS2_DATABASE_USERNAME (default: "dhis")
  • DHIS2_DATABASE_PASSWORD (optional, but strongly recommended) or contents in DHIS2_DATABASE_PASSWORD_FILE
  • PGHOST, or DHIS2_DATABASE_HOST (default: "localhost")
  • PGPORT, or DHIS2_DATABASE_PORT (default: "5432")
  • PGDATABASE (default: "postgres")
  • PGUSER (default: "postgres", must be a PostgreSQL superuser)
  • PGPASSWORD (optional, but strongly recommended, may be required for PGUSER in most PostgreSQL installations) or contents in PGPASSWORD_FILE

dhis2-init.d scripts

  • 10_dhis2-database.sh: Create and initialize a PostgreSQL database with PostGIS. In addition to various PG* values being set for connecting to the database, the script requires the following environment variables set:

    • DHIS2_DATABASE_NAME
    • DHIS2_DATABASE_USERNAME
    • DHIS2_DATABASE_PASSWORD
  • 15_pgstatstatements.sh: Add the pg_stat_statements extension to the PGDATABASE. This module is included in the PostGIS container image. The various PG* values can be set as needed to connect to the database.

  • 20_dhis2-initwar.sh: If the last line in /dhis2-init.progress/20_dhis2-initwar_history.csv does not contain a line stating that the current DHIS2 version and build revision started successfully during a previous run of 20_dhis2-initwar.sh, this script will start and stop Tomcat and record its progress. It will use docker-entrypoint.sh and remco to create dhis.conf before starting Tomcat, so read other sections of this README for any values to set (for most cases, if the DATABASE_* values are set above for 10_dhis2-database.sh, this script will function as expected).

Settings

The following OPTIONAL environment variables are used in docker-entrypoint.sh and container command begins with remco (the image default):

  • DHIS2_DATABASE_PASSWORD_FILE: if DHIS2_DATABASE_PASSWORD is empty or not set, the contents of DHIS2_DATABASE_PASSWORD_FILE will be set in DHIS2_DATABASE_PASSWORD.

  • DHIS2_REDIS_PASSWORD_FILE: if DHIS2_REDIS_PASSWORD is empty or not set, the contents of DHIS2_REDIS_PASSWORD_FILE will be set in DHIS2_REDIS_PASSWORD.

  • DISABLE_TOMCAT_TEMPLATES: If set to "1", the templates for Tomcat configuration files will not be generated.

Generating dhis.conf with Remco

The following environment variables can be used to create dhis.conf when using the remco command (the image default).

See the DHIS2 documentation and source for valid values in dhis.conf. Unless otherwise mentioned, no default value is provided by the container image, however, DHIS2 will often provide a default as specified in the previous link:

Database

  • DHIS2_DATABASE_HOST: Database hostname used to set the jdbc value in connection.url. If not provided, connection.url will be set to jdbc:postgresql:${DHIS2_DATABASE_NAME:-dhis2}. NOTE: If DHIS2_CONNECTION_URL is provided, this option will be ignored.

  • DHIS2_DATABASE_PORT: If this and DHIS2_DATABASE_HOST are provided, this is used to set the jdbc value in connection.url; default is "5432". NOTE: If DHIS2_CONNECTION_URL is provided, this option will be ignored.

  • DHIS2_DATABASE_NAME: Database name used to set the jdbc value in connection.url; default is "dhis2". NOTE: If DHIS2_CONNECTION_URL is provided, this option will be ignored.

  • DHIS2_DATABASE_USERNAME: Value of connection.username; default is "dhis". NOTE: If DHIS2_CONNECTION_USERNAME is provided, this option will be ignored.

  • DHIS2_DATABASE_PASSWORD: Value of connection.password. NOTE: If DHIS2_CONNECTION_PASSWORD is provided, this option will be ignored.

  • DHIS2_DATABASE_PASSWORD_FILE: Value of connection.password will be set as the content of the path provided. NOTE: If DHIS2_CONNECTION_PASSWORD or DHIS2_DATABASE_PASSWORD provided, this option will be ignored.

  • DHIS2_CONNECTION_DIALECT: Value of connection.dialect; default is set to "org.hibernate.dialect.PostgreSQLDialect" if not provided.

  • DHIS2_CONNECTION_DRIVER_CLASS: Value of connection.driver_class; default is set to "org.postgresql.Driver" if not provided.

  • DHIS2_CONNECTION_SCHEMA: Value of connection.schema; default is set to "update" if not provided.

Read replicas

DHIS2 supports up to 5 read-replica database servers. The following values are supported in this container image.

  • DHIS2_READ1_CONNECTION_URL: Value of read1.connection.url. If not provided, DHIS2_READ1_DATABASE_HOST, DHIS2_READ1_DATABASE_PORT, and/or DHIS2_READ1_DATABASE_NAME can be used similarly to the primary database as explained above.

  • DHIS2_READ1_CONNECTION_USERNAME: Value of read1.connection.username. If not provided, DHIS2_READ1_DATABASE_USERNAME can be used similarly to the primary database as explained above.

  • DHIS2_READ1_CONNECTION_PASSWORD: Value of read1.connection.password. If not provided, DHIS2_READ1_DATABASE_PASSWORD and/or DHIS2_READ1_DATABASE_PASSWORD_FILE can be used similarly to the primary database as explained above.

For additional read-replicas, repeat the values above replacing "1" with "2" through "5" as required.

Server

  • DHIS2_SERVER_BASE_URL: Value of server.base.url.

  • DHIS2_SERVER_HTTPS: Value of server.https. If this is not set and DHIS2_SERVER_BASE_URL begins with "https://", this will be set to "on".

Redis

Redis alone can be used with clusters of multiple Tomcat instances. It is required for all methods of clustering DHIS2.

  • DHIS2_REDIS_ENABLED: Value of redis.enabled.

  • DHIS2_REDIS_HOST: Value of redis.host.

  • DHIS2_REDIS_PORT: Value of redis.port.

  • DHIS2_REDIS_PASSWORD: Value of redis.password.

  • DHIS2_REDIS_USE_SSL: Value of redis.use.ssl.

  • DHIS2_LEADER_TIME_TO_LIVE_MINUTES: Value of leader.time.to.live.minutes.

  • DHIS2_REDIS_CACHE_INVALIDATION_ENABLED: Value of redis.cache.invalidation.enabled. Added in 2.38.2 and 2.39.0. Setting this to "true" is the recommended way to configure a cluster of Tomcat instances.

Ehcache clustering

All versions 2.35.0 and higher support clustering by specifying other Tomcat instances directly in dhis.conf. This works by having each Tomcat node notify each other of changes in Ehcache. If this method is used, ensure that the Tomcat instances are able to communicate with each other over the specified ports. Redis is still required, however.

Versions 2.38.2, 2.39.0 and higher now support improved clustering exclusively with Redis and this method should no longer be used. See redis.cache.invalidation.enabled above.

  • DHIS2_CLUSTER_HOSTNAME: Value of cluster.hostname. If not provided and both SERVICE_NAME and SYSTEM_IP are provided by the entry point, cluster.hostname will be set as the value of SYSTEM_IP. NOTE: If running any version of DHIS2 2.37 and any DEBEZIUM_* option is set, this option should not be used.

  • DHIS2_CLUSTER_CACHE_PORT: Value of cluster.cache.port. NOTE: If running any version of DHIS2 2.37 and any DEBEZIUM_* option is set, this option should not be used.

  • DHIS2_CLUSTER_CACHE_REMOTE_OBJECT_PORT: Value of cluster.cache.remote.object.port; default is "5001" if unset and DHIS2_CLUSTER_HOSTNAME is set, or if unset and SERVICE_NAME and SYSTEM_IP are both provided by the entry point. NOTE: If running any version of DHIS2 2.37 and any DEBEZIUM_* option is set, this option should not be used.

  • DHIS2_CLUSTER_MEMBERS: Value of cluster.members. If not provided and both SERVICE_NAME and SYSTEM_IP are provided, cluster.members will be set as a list of the IP addresses from a DNS query of SERVICE_NAME with SYSTEM_ID removed and cluster.cache.port added. NOTE: If running any version of DHIS2 2.37 and any DEBEZIUM_* option is set, this option should not be used.

  • SERVICE_NAME: DNS hostname used to generate the value of cluster.members if DHIS2_CLUSTER_MEMBERS is not provided. SYSTEM_IP must also be set as it is removed from the DNS query result to build cluster.members. NOTE: If running any version of DHIS2 2.37 and any DEBEZIUM_* option is set, this option should not be used.

  • DHIS2_NODE_ID: Value of node.id. If not provided, node.id is set to the value of hostname --fqdn in the entry point.

Debezium clustering

Debezium was introduced in 2.37.0 for use with clusters of multiple Tomcat instances as an alternative to the cluster.* options shown above. Redis is still required, however.

Versions 2.38.2, 2.39.0 and higher now support improved clustering exclusively with Redis and this method should no longer be used. See redis.cache.invalidation.enabled above.

  • DHIS2_DEBEZIUM_ENABLED: Value of debezium.enabled; default is 'off'.

  • DHIS2_DEBEZIUM_DB_HOSTNAME: Value of debezium.db.hostname. If DHIS2_DEBEZIUM_ENABLED is set to "on" and this value is not set, the value of DHIS2_DATABASE_HOST will be used.

  • DHIS2_DEBEZIUM_DB_PORT: Value of debezium.db.port. If DHIS2_DEBEZIUM_ENABLED is set to "on" and this value is not set, the value of DHIS2_DATABASE_PORT will be used.

  • DHIS2_DEBEZIUM_DB_NAME: Value of debezium.db.name. If DHIS2_DEBEZIUM_ENABLED is set to "on" and this value is not set, the value of DHIS2_DATABASE_NAME will be used.

  • DHIS2_DEBEZIUM_CONNECTION_USERNAME: Value of debezium.connection.username. If DHIS2_DEBEZIUM_ENABLED is set to "on" and this value is not set, the value of DHIS2_DATABASE_USERNAME will be used.

  • DHIS2_DEBEZIUM_CONNECTION_PASSWORD: Value of debezium.connection.password. If DHIS2_DEBEZIUM_ENABLED is set to "on" and this value is not set, the value of DHIS2_DATABASE_PASSWORD will be used.

  • DHIS2_DEBEZIUM_SLOT_NAME: Value of debezium.slot.name.

  • DHIS2_DEBEZIUM_EXCLUDE_LIST: Value of debezium.exclude.list.

  • DHIS2_DEBEZIUM_SHUTDOWN_ON_CONNECTOR_STOP: Value of debezium.shutdown_on.connector_stop; default is 'off'.

Azure OIDC

DHIS2 supports up to 10 Azure AD providers for OIDC. The following environment values can be used in configuring dhis.conf:

  • DHIS_OIDC_PROVIDER_AZURE_0_TENANT: Value of oidc.provider.azure.0.tenant.

  • DHIS_OIDC_PROVIDER_AZURE_0_CLIENT_ID: Value of oidc.provider.azure.0.client_id.

  • DHIS_OIDC_PROVIDER_AZURE_0_CLIENT_SECRET: Value of oidc.provider.azure.0.client_secret.

  • DHIS_OIDC_PROVIDER_AZURE_0_DISPLAY_ALIAS: Value of oidc.provider.azure.0.display_alias.

  • DHIS_OIDC_PROVIDER_AZURE_0_MAPPING_CLAIM: Value of oidc.provider.azure.0.mapping_claim.

  • DHIS_OIDC_PROVIDER_AZURE_0_REDIRECT_URL: Value of oidc.provider.azure.0.redirect_url.

For additional Azure AD providers, repeat the values above replacing "0" with "1" through "9" as required.

All configuration options

Any option defined in ConfigurationKey.java for the version fo DHIS2 can be set with an environment variable by transforming all letters to uppercase and changing all special periods to underscores. For example, to set analytics.cache.expiration in dhis.conf, set value for DHIS2_ANALYTICS_CACHE_EXPIRATION in the environment. Similarly, for oidc.provider.google.client_secret, set DHIS2_OIDC_PROVIDER_GOOGLE_CLIENT_SECRET.

Generating Tomcat server.xml

The following environment variables can be used to create Tomcat's server.xml when using the remco command.

  • TOMCAT_CONNECTOR_PROXYPORT: For the primary Connector, value of proxyPort. If not provided and DHIS2_SERVER_BASE_URL is set, the value will be derived from the URL port in DHIS2_SERVER_BASE_URL.

  • TOMCAT_CONNECTOR_SCHEME: For the primary Connector, value of scheme. If not provided and DHIS2_SERVER_BASE_URL begins with "https://", the value will be "https".

  • TOMCAT_CONNECTOR_SECURE: For the primary Connector, value of secure. If not provided and DHIS2_SERVER_HTTPS is "on", the value will be "true".

  • TOMCAT_CONNECTOR_RELAXEDQUERYCHARS: For the primary Connector, value of relaxedQueryChars. If not provided, the value will be \ { } | [ ].

  • TOMCAT_CONNECTOR_COMPRESSION: For the primary Connector, value of compression. If not provided, no value with be provided.

  • TOMCAT_CONNECTOR_COMPRESSIONMINSIZE: For the primary Connector, value of compressionMinSize. If not provided, no value with be provided.

  • TOMCAT_CONNECTOR_COMPRESSIBLEMIMETYPE: For the primary Connector, value of compressibleMimeType. If not provided, no value with be provided.

  • TOMCAT_CONNECTOR_NOCOMPRESSIONSTRONGETAG: For the primary Connector, value of noCompressionStrongETag. If not provided, no value with be provided.

  • TOMCAT_CONNECTOR_MAXHTTPHEADERSIZE: For the primary Connector, value of maxHttpHeaderSize. If not provided, no value with be provided.

  • TOMCAT_CONNECTOR_MAXTHREADS: For the primary Connector, value of maxThreads. If not provided, no value with be provided.