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¶
- Server running Ubuntu 22.04 or 24.04
- Accès SSH avec un utilisateur
non rootavec les privilègessudo.
Installing DHIS2¶
- 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 - 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 - Run the installation
cd dhis2-server-tools/deploy cp inventory/hosts.template inventory/hosts sudo ./deploy.sh - Open the DHIS2 web interface at
https://{server_ip}/dhis,replacing{server_ip}with your actual IP address. Use the default credentials:adminfor the username anddistrictfor the password.https://{server_ip}/dhis
Next steps¶
Configure fully qualified domain name¶
- Edit your inventory hosts file and set the
fqdnvariable, 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/hostsfile invim 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
hmisand ansible_host172.19.1.12should 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 namedcustomssl.crtandcustomssl.keyrespectively. -
Configure the tools to use the copied TLS certificate and key by editing your
inventory/hostsfile and settingSSL_TYPEparameter tocustomssl, 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 thepostgresql_versionvariable 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/custom→ Safe to edit manually. → Included at the end ofdhispg.conf, so it takes precedence.
Inclusion Order and Override Behavior¶
PostgreSQL processes configuration files in the following sequence:
postgresql.conf- → includes
dhispg.conf(Ansible-managed) - → 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¶
- Open or create the custom config file:
sudo nano /etc/postgresql/16/main/conf.d/custom
- Add or override parameters. For example:
work_mem = '32MB'
max_connections = 200
-
Save and exit the file.
-
Reload PostgreSQL for changes to take effect:
sudo systemctl reload postgresql
Summary Table¶
| File Path | Managed By | Editable? | Notes |
|---|---|---|---|
/etc/postgresql/16/main/postgresql.conf | PostgreSQL | Non | Includes Ansible-managed configs |
/etc/postgresql/16/main/conf.d/dhispg.conf | Ansible | Non | Automatically overwritten on every playbook run |
/etc/postgresql/16/main/conf.d/custom | Utilisateur (vous) | Oui | Safely used for manual overrides |