Ir para o conteúdo
For the complete DHIS2 documentation index, see llms.txt.

Introduction

DHIS2 stands as a freely accessible, open-source, and adaptable software platform. It serves the purpose of collecting, managing, visualizing, and analyzing health data derived from diverse sources and programs. DHIS2 components are proxy (Nginx/Apache2), Tomcat Server, PostgreSQL database and optional APM and Server monitoring tools. This quick start shows you how to install dhis2 and its components to a single sever with dhis2-server tools.

Prerequisites

  1. Server running Ubuntu 22.04 or 24.04
  2. SSH Access with non-root user with sudo privileges

Installing DHIS2

  1. Make sure your server’s firewall is active and the SSH port is allowed. Replace {ssh_port} with your actual SSH port number.
    sudo ufw limit {ssh_port}/tcp
    sudo ufw enable
    
  2. Connect to your server via SSH and clone the repository from "https://github.com/dhis2/dhis2-server-tools".
    git clone https://github.com/dhis2/dhis2-server-tools.git
    
  3. Run the installation
    cd dhis2-server-tools/deploy
    cp inventory/hosts.template inventory/hosts
    sudo ./deploy.sh
    
  4. Open the DHIS2 web interface at https://{server_ip}/dhis, replacing {server_ip} with your actual IP address. Use the default credentials: admin for the username and district for the password.
    https://{server_ip}/dhis
    

Next steps

Configure fully qualified domain name

  • Edit your inventory hosts file and set the fqdn variable, use an editor of your choice.
    vim inventory/hosts
    fqdn=dhis.example.com
    
  • Save your changes and run the install again,
sudo ./deploy.sh

Important

To use Let's Encrypt, ensure the domain is mapped to your server's public IP address before setting fqdn. Alternatively, you can use a custom TLS certificate.

Adding an instance

You can run multiple instances on a single server. Adding an instance will create a separate lxd container.

  • Edit dhis2-server-tools/deploy/inventory/hosts file in
    vim dhis2-server-tools/deploy/inventory/hosts
    
  • Add a new line line under [instances] section, should look like the line below,
    [instances]
    dhis    ansible_host=172.19.1.11   database_host=postgres # your first instance
    hmis    ansible_host=172.19.1.12   database_host=postgres # your second instance
    

Note

The name hmis and ansible_host 172.19.1.12 should be unique.

Deploying custom TLS certificate to the reverse proxy

On some occasions, you could have your own TLS certificate and you are not using LetsEncrypt. Here is how you can instruct the tools to use your own TLS certificate.

Note

You'll need to have your TLS certificate file and its corresponding key.

  • Copy TLS certificate and key to dhis2-server-tools/deploy/roles/proxy/files/ They should be named customssl.crt and customssl.key respectively.

  • Configure the tools to use the copied TLS certificate and key by editing your inventory/hosts file and setting SSL_TYPE parameter to customssl , see below,

SSL_TYPE=customssl

DHIS2 Instance variables

These are variables specific to the dhis2 instance, like PostgreSQL variables, you can either define them in inventory host or in the file you create in dhis2-server-tools/deploy/inventory/host_vars/, there is dhis.template that ships with the tools, create a file from the template with e.g.

cp dhis2-server-tools/deploy/inventory/host_vars/dhis.template dhis2-server-tools/deploy/inventory/host_vars/dhis

The list of variables can be found here: Instance Config variables

Nginx Configuration

Ansible generates Nginx configuration files based on whether a Fully Qualified Domain Name (FQDN) is defined:

Condition Ansible-Generated File
fqdn is defined /etc/nginx/conf.d/{{ fqdn }}.conf
fqdn not defined /etc/nginx/conf.d/default.conf

These files are fully managed by Ansible, meaning any manual changes will be lost when the playbook is re-applied.

Safe Manual Customization

Each Ansible-generated config file includes an explicit static file, which is created during the initial setup and never modified by Ansible after that.

Condition Included Static File (safe for manual edits)
fqdn is defined /etc/nginx/static/{{ fqdn }}.conf
fqdn not defined /etc/nginx/static/default.conf

Customize only the static file included in your dynamic configuration. Since this is not touched by Ansible, it will persist across playbook runs.

Important: After making changes, manually reload Nginx:

sudo systemctl reload nginx

Apache2 Configuration

Apache2 uses a similar setup to Nginx, with a slightly different directory structure.

Ansible-Managed Files

Ansible generates the main configuration file based on whether a Fully Qualified Domain Name (FQDN) is defined.
These files are overwritten on every playbook run — do not edit them manually.

Condition Ansible-Generated File
fqdn is defined /etc/apache2/sites-enabled/{{ fqdn }}.conf
fqdn not defined /etc/apache2/sites-enabled/default.conf

Static Files for Manual Edits

Each Ansible config includes a static file created at setup and never modified afterward.
Place all manual changes here.

Condition Static File (safe for manual edits)
fqdn is defined /etc/apache2/static/{{ fqdn }}.conf
fqdn not defined /etc/apache2/static/default.conf

Note

Always make manual changes in the static file. These are explicitly included in the main Ansible config.

Reload Apache After Edits

sudo systemctl reload apache2

PostgreSQL Configuration

The tools provide options to configure certain PostgreSQL variables for improved performance (see PostgreSQL performance tuning). These variables can be defined in your inventory file, in-line with your host line in key=value format. For more details, refer to Ansible host variables documentation. Alternatively, if your host is named postgres in the hosts file, you can create a file named postgres in the dhis2-server-tools/deploy/inventory/host_vars/ directory and define the variables, in key: value format . Templates are available in the directory to help you get started.

The list of variables can be found here: PostgreSQL Optimization Variables

Manually Override PostgreSQL Parameters

In this setup, PostgreSQL configuration is partially managed by Ansible. Some configuration files are automatically generated during playbook runs. This guide explains how to safely override PostgreSQL settings without having your changes lost during future deployments.

Note:

This example assumes you are using PostgreSQL version 16, so all paths reference /etc/postgresql/16/main/. The actual version depends on the value of the postgresql_version variable defined in your Ansible inventory or host vars.


Configuration File Structure

  • Ansible-managed file: /etc/postgresql/16/main/conf.d/dhispg.conf → Automatically generated by Ansible. → Do not edit directly — changes will be overwritten on each Ansible run.

  • User-managed override file: /etc/postgresql/16/main/conf.d/customSafe to edit manually. → Included at the end of dhispg.conf, so it takes precedence.


Inclusion Order and Override Behavior

PostgreSQL processes configuration files in the following sequence:

  1. postgresql.conf
  2. → includes dhispg.conf (Ansible-managed)
  3. → which includes custom (user-managed)

The last defined value for any parameter wins. Any setting in custom will override values from both dhispg.conf and postgresql.conf.


Steps to Safely Override Settings

  1. Open or create the custom config file:
sudo nano /etc/postgresql/16/main/conf.d/custom
  1. Add or override parameters. For example:
work_mem = '32MB'
max_connections = 200
  1. Save and exit the file.

  2. Reload PostgreSQL for changes to take effect:

sudo systemctl reload postgresql

Summary Table

File Path Managed By Editable? Notas
/etc/postgresql/16/main/postgresql.conf PostgreSQL No Includes Ansible-managed configs
/etc/postgresql/16/main/conf.d/dhispg.conf Ansible No Automatically overwritten on every playbook run
/etc/postgresql/16/main/conf.d/custom User (you) Yes Safely used for manual overrides