zechtz / docker-dhis2

DHIS2 on Tomcat

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

dhis2 image

DHIS2 run by Tomcat.

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.

Features

Entry point

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

  • 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_FQDN is empty or not set, it will be exported as the output of hostname --fqdn.

  • 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 and the command starts with remco or catalina.sh:

  • Use WAIT_HOSTS, WAIT_PATHS, and others as documented to wait for other hosts or file paths before proceeding. If none are provided, wait will exit with code 0 immediately and the container will proceed.

  • If FORCE_HEALTHCHECK_WAIT is set to 1, netcat will listen on port 8080 and respond to a single http request with "200 OK" and an empty body. This is to allow an orchestrator to mark a new container as healthy before proceeding to start Tomcat, to which subsequent health checks will actually hit DHIS2.

  • 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 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, 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.

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. If WAIT_HOSTS or WAIT_PATHS are provided, it will wait for hosts or file paths before proceeding. 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. If WAIT_HOSTS or WAIT_PATHS are provided, it will wait for hosts or file paths before proceeding. 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:

  • 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.

The following OPTIONAL environment variables are used in docker-entrypoint.sh and container command begins with remco or catalina.sh:

  • FORCE_HEALTHCHECK_WAIT: if set to 1, netcat will listen on port 8080 and respond to a single http request with "200 OK" to allow for an external health check to initialize before proceeding.

Generating dhis.conf with Remco

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

See the DHIS2 documentation and source for valid values in dhis.conf. Unless otherwise mentioned, no default value is provided:

  • 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_SERVER_BASEURL: Value of server.base.url.

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

  • 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_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 DHIS2 2.37 or higher and any DEBEZIUM_* option is set, this option will be ignored.

  • DHIS2_CLUSTER_CACHE_PORT: Value of cluster.cache.port. NOTE: If running DHIS2 2.37 or higher and any DEBEZIUM_* option is set, this option will be ignored.

  • 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 DHIS2 2.37 or higher and any DEBEZIUM_* option is set, this option will be ignored.

  • 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 DHIS2 2.37 or higher and any DEBEZIUM_* option is set, this option will be ignored.

  • 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 DHIS2 2.37 or higher and any DEBEZIUM_* option is set, this option will be ignored.

  • DHIS2_NODE_ID: Value of node.id. If not provided, node.id is set by SYSTEM_FQDN, which is provided by the entry point.

  • DHIS2_LOGGING_FILE_MAXSIZE: Value of logging.file.max_size.

  • DHIS2_LOGGING_FILE_MAXARCHIVES: Value of logging.file.max_archives.

  • DHIS2_MONITORING_API_ENABLED: Value of monitoring.api.enabled.

  • DHIS2_MONITORING_JVM_ENABLED: Value of monitoring.jvm.enabled.

  • DHIS2_MONITORING_DBPOOL_ENABLED: Value of monitoring.dbpool.enabled.

  • DHIS2_MONITORING_HIBERNATE_ENABLED: Value of monitoring.hibernate.enabled.

  • DHIS2_MONITORING_UPTIME_ENABLED: Value of monitoring.uptime.enabled.

  • DHIS2_MONITORING_CPU_ENABLED: Value of monitoring.cpu.enabled.

  • DHIS2_SYSTEM_MONITORING_URL: Value of system.monitoring.url.

  • DHIS2_SYSTEM_MONITORING_USERNAME: Value of system.monitoring.username.

  • DHIS2_SYSTEM_MONITORING_PASSWORD: Value of system.monitoring.password.

  • DHIS2_SYSTEM_READ_ONLY_MODE: Value of system.read_only_mode.

  • DHIS2_SYSTEM_SESSION_TIMEOUT: Value of system.session.timeout.

  • DHIS2_SYSTEM_SQL_VIEW_TABLE_PROTECTION: Value of system.sql_view_table_protection.

  • DHIS2_CHANGELOG_AGGREGATE: Value of changelog.aggregate.

  • DHIS2_CHANGELOG_TRACKER: Value of changelog.tracker.

  • DHIS2_AUDIT_LOGGER: Value of audit.logger.

  • DHIS2_AUDIT_DATABASE: Value of audit.database.

  • DHIS2_AUDIT_METADATA: Value of audit.metadata.

  • DHIS2_AUDIT_TRACKER: Value of audit.tracker.

  • DHIS2_AUDIT_AGGREGATE: Value of audit.aggregate.

  • DHIS2_CONNECTION_DIALECT: Value of connection.dialect; default is "org.hibernate.dialect.PostgreSQLDialect".

  • DHIS2_CONNECTION_DRIVERCLASS: Value of connection.driver_class; default is "org.postgresql.Driver".

  • DHIS2_CONNECTION_SCHEMA: Value of connection.schema; default is "update".

  • DHIS2_CONNECTION_POOL_MAXSIZE: Value of connection.pool.max_size.

  • DHIS2_ENCRYPTION_PASSWORD: Value of encryption.password.

  • DHIS2_FILESTORE_PROVIDER: Value of filestore.provider.

  • DHIS2_FILESTORE_CONTAINER: Value of filestore.container.

  • DHIS2_FILESTORE_LOCATION: Value of filestore.location.

  • DHIS2_FILESTORE_IDENTITY: Value of filestore.identity.

  • DHIS2_FILESTORE_SECRET: Value of filestore.secret.

  • DHIS2_ANALYTICS_CACHE_EXPIRATION: Value of analytics.cache.expiration.

2.35.2 and up

  • DHIS2_SYSTEM_PROGRAM_RULE_SERVER_EXECUTION: Value of system.program_rule.server_execution.

2.36 and up

  • DHIS2_SYSTEM_AUDIT_ENABLED: Value of system.audit.enabled.

  • DHIS2_SYSTEM_CACHE_MAX_SIZE_FACTOR: Value of system.cache.max_size.factor.

2.37 and up

  • 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'.

  • DHIS2_SYSTEM_CACHE_CAP_PERCENTAGE: Value of system.cache.cap.percentage.

Generating Tomcat server.xml with Remco

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_BASEURL is set, the value will be derived from the URL port in DHIS2_SERVER_BASEURL.

  • TOMCAT_CONNECTOR_SCHEME: For the primary Connector, value of scheme. If not provided and DHIS2_SERVER_BASEURL 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".

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.

Quick

Start

docker compose pull

docker compose up --detach

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

Watch logs

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 bash -c 'for i in pg_dhis pg_postgres ; do echo -n "pass_${i}.txt: "; cat "/pass_${i}/pass_${i}.txt"; 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 rm --force --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 up --detach 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.38/dhis2-db-sierra-leone.sql.gz

# Stop Tomcat
docker compose rm --force --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'

# If the previous command didn't work, try the steps below which will copy the file into the container before importing
#docker cp dhis2-db-sierra-leone.sql.gz "$( docker compose ps -q 'database' | head -n1 )":/tmp/db.sql.gz
#docker compose exec database bash -c "gunzip -c /tmp/db.sql.gz | psql -v 'ON_ERROR_STOP=1' --username='postgres' --dbname='dhis2' && rm -v /tmp/db.sql.gz"

# Re-initialize DHIS2
docker compose run --rm --env 'DHIS2_INIT_FORCE=1' dhis2_init dhis2-init.sh

# Start Tomcat
docker compose up --detach dhis2

Export the database to a file on your system

An included helper script will run pg_dump with generated tables excluded and perform some minor changes to increase the likelihood of being imported on 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.36.0:

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

docker compose up --detach

# Later, upgrade to 2.38.0:

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

docker compose rm --force --stop dhis2 dhis2_init

docker compose pull

docker compose up --detach --remove-orphans

About

DHIS2 on Tomcat

License:MIT License


Languages

Language:Shell 69.8%Language:Dockerfile 19.9%Language:Python 10.3%