Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

APP_HOSTNAME=dhis2-127-0-0-1.nip.io
LETSENCRYPT_ACME_EMAIL=<your@email.org>
# ACME CA server - use staging for testing to avoid rate limits
# Uncomment the line below to use Let's Encrypt staging
# LETSENCRYPT_ACME_CASERVER=https://acme-staging-v02.api.letsencrypt.org/directory

# Set this to the exact version you want to use. Example: 42.3.1
DHIS2_VERSION=42
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ Thumbs.db
# IDE
.vscode/

.ansible/

traefik/acme.json
backups/
12 changes: 10 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
PRE_COMMIT_VERSION ?= 4.3.0

.PHONY: init playwright test reinit check backup-database backup-file-storage backup restore-database restore-file-storage restore docs launch clean config get-backup-timestamp
.PHONY: init playwright test reinit check backup-database backup-file-storage backup restore-database restore-file-storage restore docs launch clean clean-all config get-backup-timestamp

init:
@test -d .venv || python3 -m venv .venv
Expand All @@ -22,7 +22,7 @@ reinit:
$(MAKE) init

install-loki-driver:
docker plugin ls --format '{{.Name}}' | grep -q 'loki:latest' || ./scripts/install-loki-driver.sh
docker plugin ls --format '{{.Name}}' | grep -q 'loki' || ./scripts/install-loki-driver.sh
docker plugin ls

check:
Expand Down Expand Up @@ -69,6 +69,14 @@ launch: install-loki-driver
$(COMPOSE_CMD) up $(COMPOSE_OPTS)

clean:
$(COMPOSE_CMD) down --remove-orphans

clean-all:
@if [ -t 0 ]; then \
echo "WARNING: This will destroy all Docker volumes (database, file storage, monitoring data, etc.)."; \
echo "This action is irreversible."; \
read -p "Are you sure? [y/N] " confirm && [ "$$confirm" = "y" ] || (echo "Aborted." && exit 1); \
fi
$(COMPOSE_CMD) down --remove-orphans --volumes

config:
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ This repository provides a Docker-based deployment for the DHIS2 application, de
- [Backup](#backup)
- [Backup Timestamp](#backup-timestamp)
- [Restore](#restore)
- [Let's Encrypt Certificate Management](#lets-encrypt-certificate-management)
- [Production vs Staging](#production-vs-staging)
- [Monitoring](#monitoring)
- [Prerequisites](#prerequisites)
- [Monitoring Deployment](#monitoring-deployment)
Expand Down Expand Up @@ -227,6 +229,19 @@ make restore
make restore-file-storage
```

### Let's Encrypt Certificate Management

#### Production vs Staging

- **Production (default):** trusted certificates with standard Let's Encrypt rate limits.
- **Staging:** untrusted test certificates with much higher rate limits for validation and CI/testing workflows.

To use staging, set this in `.env`:

```dotenv
LETSENCRYPT_ACME_CASERVER=https://acme-staging-v02.api.letsencrypt.org/directory
```

### Monitoring

The monitoring stack is crucial for understanding the health and performance of your production DHIS2 deployment. It includes Grafana, Loki, and Prometheus for logs and metrics collection.
Expand Down
4 changes: 3 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,10 @@ services:
TRAEFIK_CERTIFICATESRESOLVERS_LETSENCRYPT_ACME_EMAIL: ${LETSENCRYPT_ACME_EMAIL}
# -- ACME storage file
TRAEFIK_CERTIFICATESRESOLVERS_LETSENCRYPT_ACME_STORAGE: /cert/acme.json
# -- ACME DNS challenge
# -- ACME TLS challenge
TRAEFIK_CERTIFICATESRESOLVERS_LETSENCRYPT_ACME_TLSCHALLENGE: true
# -- ACME CA server
TRAEFIK_CERTIFICATESRESOLVERS_LETSENCRYPT_ACME_CASERVER: ${LETSENCRYPT_ACME_CASERVER:-https://acme-v02.api.letsencrypt.org/directory}
# -- Hostname
APP_HOSTNAME: ${APP_HOSTNAME}
ports:
Expand Down
2 changes: 2 additions & 0 deletions scripts/init-cert.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/usr/bin/env sh

set -eu

touch /cert/acme.json
chown nobody:nobody /cert/acme.json
chmod 600 /cert/acme.json
1 change: 0 additions & 1 deletion server-tools/roles/deploy/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
file:
path: "{{ deploy_dir }}/traefik/acme.json"
state: touch
# Make sure this matches with the user running DHIS2
owner: "65534"
group: "65534"
mode: 0600
Expand Down
8 changes: 5 additions & 3 deletions tests/test_backup_restore.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def test_create_backup(backup_timestamp: str):

@pytest.mark.order(5)
def test_clean_environment():
run_make_command("clean")
run_make_command("clean-all")

assert_no_services_running()

Expand Down Expand Up @@ -77,5 +77,7 @@ def verify_restored_app(page: Page):
iframe.locator("body").wait_for(state="visible")

iframe.get_by_role("menuitem", name="Custom apps").click()
expect(iframe.get_by_role("heading", name="All installed custom apps")).to_be_visible()
expect(iframe.get_by_role("button", name="Android Settings")).to_be_visible()
expect(iframe.get_by_role("heading", name="All installed custom apps")).to_be_visible(
timeout=30000
)
expect(iframe.get_by_role("button", name="Android Settings")).to_be_visible(timeout=30000)
Loading