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).
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.
docker compose pull
docker compose up --detach
You can access the site through http://localhost:8080/
View existing logs and watch for new lines:
docker compose logs --follow
Press Ctrl+c to exit logs
Stop the entire stack:
docker compose stop
Resume later with:
docker compose start
Delete containers and data storage volumes:
docker compose down --volumes
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'
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
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
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
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
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 ofDHIS2_DATABASE_PASSWORD_FILE
will be set asDHIS2_DATABASE_PASSWORD
. -
If
DHIS2_REDIS_PASSWORD
is empty or not set, the contents ofDHIS2_REDIS_PASSWORD_FILE
will be set asDHIS2_REDIS_PASSWORD
. -
If
SYSTEM_IP
is empty or not set, it will be exported as the output ofhostname --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.
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.
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 inDHIS2_DATABASE_PASSWORD_FILE
PGHOST
, orDHIS2_DATABASE_HOST
(default: "localhost")PGPORT
, orDHIS2_DATABASE_PORT
(default: "5432")PGDATABASE
(default: "postgres")PGUSER
(default: "postgres", must be a PostgreSQL superuser)PGPASSWORD
(optional, but strongly recommended, may be required forPGUSER
in most PostgreSQL installations) or contents inPGPASSWORD_FILE
-
10_dhis2-database.sh
: Create and initialize a PostgreSQL database with PostGIS. In addition to variousPG*
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 thePGDATABASE
. This module is included in the PostGIS container image. The variousPG*
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 of20_dhis2-initwar.sh
, this script will start and stop Tomcat and record its progress. It will usedocker-entrypoint.sh
andremco
to create dhis.conf before starting Tomcat, so read other sections of this README for any values to set (for most cases, if theDATABASE_*
values are set above for10_dhis2-database.sh
, this script will function as expected).
The following OPTIONAL environment variables are used in docker-entrypoint.sh
and container
command begins with remco (the image default):
-
DHIS2_DATABASE_PASSWORD_FILE
: ifDHIS2_DATABASE_PASSWORD
is empty or not set, the contents ofDHIS2_DATABASE_PASSWORD_FILE
will be set inDHIS2_DATABASE_PASSWORD
. -
DHIS2_REDIS_PASSWORD_FILE
: ifDHIS2_REDIS_PASSWORD
is empty or not set, the contents ofDHIS2_REDIS_PASSWORD_FILE
will be set inDHIS2_REDIS_PASSWORD
. -
DISABLE_TOMCAT_TEMPLATES
: If set to "1", the templates for Tomcat configuration files will not be generated.
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:
-
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: IfDHIS2_CONNECTION_URL
is provided, this option will be ignored. -
DHIS2_DATABASE_PORT
: If this andDHIS2_DATABASE_HOST
are provided, this is used to set the jdbc value in connection.url; default is "5432". NOTE: IfDHIS2_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: IfDHIS2_CONNECTION_URL
is provided, this option will be ignored. -
DHIS2_DATABASE_USERNAME
: Value of connection.username; default is "dhis". NOTE: IfDHIS2_CONNECTION_USERNAME
is provided, this option will be ignored. -
DHIS2_DATABASE_PASSWORD
: Value of connection.password. NOTE: IfDHIS2_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: IfDHIS2_CONNECTION_PASSWORD
orDHIS2_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.
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/orDHIS2_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/orDHIS2_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.
-
DHIS2_SERVER_BASE_URL
: Value of server.base.url. -
DHIS2_SERVER_HTTPS
: Value of server.https. If this is not set andDHIS2_SERVER_BASE_URL
begins with "https://", this will be set to "on".
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.
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 bothSERVICE_NAME
andSYSTEM_IP
are provided by the entry point, cluster.hostname will be set as the value ofSYSTEM_IP
. NOTE: If running any version of DHIS2 2.37 and anyDEBEZIUM_*
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 anyDEBEZIUM_*
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 andDHIS2_CLUSTER_HOSTNAME
is set, or if unset andSERVICE_NAME
andSYSTEM_IP
are both provided by the entry point. NOTE: If running any version of DHIS2 2.37 and anyDEBEZIUM_*
option is set, this option should not be used. -
DHIS2_CLUSTER_MEMBERS
: Value of cluster.members. If not provided and bothSERVICE_NAME
andSYSTEM_IP
are provided, cluster.members will be set as a list of the IP addresses from a DNS query ofSERVICE_NAME
withSYSTEM_ID
removed and cluster.cache.port added. NOTE: If running any version of DHIS2 2.37 and anyDEBEZIUM_*
option is set, this option should not be used. -
SERVICE_NAME
: DNS hostname used to generate the value of cluster.members ifDHIS2_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 anyDEBEZIUM_*
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 ofhostname --fqdn
in the entry point.
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. IfDHIS2_DEBEZIUM_ENABLED
is set to "on" and this value is not set, the value ofDHIS2_DATABASE_HOST
will be used. -
DHIS2_DEBEZIUM_DB_PORT
: Value of debezium.db.port. IfDHIS2_DEBEZIUM_ENABLED
is set to "on" and this value is not set, the value ofDHIS2_DATABASE_PORT
will be used. -
DHIS2_DEBEZIUM_DB_NAME
: Value of debezium.db.name. IfDHIS2_DEBEZIUM_ENABLED
is set to "on" and this value is not set, the value ofDHIS2_DATABASE_NAME
will be used. -
DHIS2_DEBEZIUM_CONNECTION_USERNAME
: Value of debezium.connection.username. IfDHIS2_DEBEZIUM_ENABLED
is set to "on" and this value is not set, the value ofDHIS2_DATABASE_USERNAME
will be used. -
DHIS2_DEBEZIUM_CONNECTION_PASSWORD
: Value of debezium.connection.password. IfDHIS2_DEBEZIUM_ENABLED
is set to "on" and this value is not set, the value ofDHIS2_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'.
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.
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
.
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 andDHIS2_SERVER_BASE_URL
is set, the value will be derived from the URL port inDHIS2_SERVER_BASE_URL
. -
TOMCAT_CONNECTOR_SCHEME
: For the primary Connector, value of scheme. If not provided andDHIS2_SERVER_BASE_URL
begins with "https://", the value will be "https". -
TOMCAT_CONNECTOR_SECURE
: For the primary Connector, value of secure. If not provided andDHIS2_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.