diff --git a/.env.template b/.env.template
index d4010f1..8238a78 100644
--- a/.env.template
+++ b/.env.template
@@ -6,6 +6,9 @@ LETSENCRYPT_ACME_EMAIL=<your@email.org>
 # Set this to the exact version you want to use. Example: 42.3.1
 DHIS2_VERSION=42
 
+# CPU architecture for healthcheck binary (amd64 or arm64)
+ARCH=amd64
+
 DHIS2_ADMIN_USERNAME=admin
 DHIS2_ADMIN_PASSWORD=<some very secure password>
 
@@ -13,7 +16,9 @@ DHIS2_ADMIN_PASSWORD=<some very secure password>
 DHIS2_MONITOR_USERNAME=monitor
 DHIS2_MONITOR_PASSWORD=<another very secure password>
 
-POSTGRES_VERSION=16-master
+# PostgreSQL image. For ARM compatibility use baosystems image:
+# POSTGRES_IMAGE=ghcr.io/baosystems/postgis:16
+POSTGRES_IMAGE=postgis/postgis:16-master
 POSTGRES_PASSWORD=<another very secure password>
 POSTGRES_DB=dhis
 POSTGRES_DB_USERNAME=dhis
diff --git a/docker-compose.yml b/docker-compose.yml
index 13e9674..8f03c64 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,23 +1,52 @@
 x-database-image: &database-image
-  image: postgis/postgis:${POSTGRES_VERSION:-16-master}
+  image: ${POSTGRES_IMAGE:-postgis/postgis:16-master}
 
 x-file-storage-image: &file-storage-image
   image: rclone/rclone:${RCLONE_VERSION:-1.68}
 
 services:
+  healthcheck-init:
+    image: curlimages/curl:${CURL_VERSION:-8.10.1}
+    volumes:
+      - healthcheck:/healthcheck
+    environment:
+      ARCH: ${ARCH:-amd64}
+      HEALTHCHECK_VERSION: ${HEALTHCHECK_VERSION:-1.0.0}
+      HEALTHCHECK_SHA256_AMD64: ${HEALTHCHECK_SHA256_AMD64:-d4542505894c0f5e1692ea282fecf75290a3893538a165d571e4c1a15724eb1b}
+      HEALTHCHECK_SHA256_ARM64: ${HEALTHCHECK_SHA256_ARM64:-df6382f871f02f48fac81893500aa8578ae21fb985819f6a19af21918c352f92}
+    command:
+      - sh
+      - -c
+      - |
+        if [ ! -f /healthcheck/healthcheck ]; then
+          if [ "$${ARCH}" = "arm64" ]; then
+            EXPECTED_SHA="$${HEALTHCHECK_SHA256_ARM64}"
+          else
+            EXPECTED_SHA="$${HEALTHCHECK_SHA256_AMD64}"
+          fi
+          curl -sL -o /healthcheck/healthcheck "https://github.com/netroms/simple_healthcheck/releases/download/v$${HEALTHCHECK_VERSION}/healthcheck-$${ARCH}"
+          echo "$${EXPECTED_SHA}  /healthcheck/healthcheck" | sha256sum -c -
+          chmod +x /healthcheck/healthcheck
+        fi
+    user: root
+    security_opt:
+      - no-new-privileges:true
+
   app:
     image: dhis2/core:${DHIS2_VERSION:-42}
     depends_on:
       database:
         condition: service_healthy
+      healthcheck-init:
+        condition: service_completed_successfully
     volumes:
       - dhis2:/opt/dhis2/
-      #- ./config/dhis2/log4j2.xml:/opt/dhis2/log4j2.xml:ro
       - ./config/dhis2/dhis.conf:/opt/dhis2/dhis.conf:ro
+      - healthcheck:/opt/dhis2/healthcheck-bin:ro
       - type: tmpfs
         target: /tmp
         tmpfs:
-          size: 1000000
+          size: 300000000
       - type: tmpfs
         target: /usr/local/tomcat/temp
         tmpfs:
@@ -43,7 +72,7 @@ services:
       - database
     restart: unless-stopped
     healthcheck:
-      test: [ "CMD", "curl", "-f", "http://127.0.0.1:8080/dhis-web-login/" ]
+      test: [ "CMD", "/opt/dhis2/healthcheck-bin/healthcheck", "http://localhost:8080/api/ping" ]
       interval: 10s
       timeout: 3s
       retries: 3
@@ -309,3 +338,4 @@ volumes:
   dhis2: {}
   postgres: {}
   cert: {}
+  healthcheck: {}
diff --git a/docs/environment-variables.md b/docs/environment-variables.md
index 5682627..01295cb 100644
--- a/docs/environment-variables.md
+++ b/docs/environment-variables.md
@@ -33,7 +33,7 @@
 
 | Variable | Description | Default Value |
 |----------|-------------|---------------|
-| `POSTGRES_VERSION` |  | `16-master` |
+| `POSTGRES_IMAGE` |  | `postgis/postgis:16-master` |
 
 ### Service: database
 
@@ -52,7 +52,7 @@
 
 | Variable | Description | Default Value |
 |----------|-------------|---------------|
-| `POSTGRES_VERSION` |  | `16-master` |
+| `POSTGRES_IMAGE` |  | `postgis/postgis:16-master` |
 
 ### Service: traefik
 
@@ -82,7 +82,7 @@
 
 | Variable | Description | Default Value |
 |----------|-------------|---------------|
-| `POSTGRES_VERSION` |  | `16-master` |
+| `POSTGRES_IMAGE` |  | `postgis/postgis:16-master` |
 
 ### Service: backup-file-storage
 
@@ -116,7 +116,7 @@
 
 | Variable | Description | Default Value |
 |----------|-------------|---------------|
-| `POSTGRES_VERSION` |  | `16-master` |
+| `POSTGRES_IMAGE` |  | `postgis/postgis:16-master` |
 
 ### Service: restore-file-storage
 
diff --git a/scripts/generate-env.sh b/scripts/generate-env.sh
index 9f5e92b..ebed396 100755
--- a/scripts/generate-env.sh
+++ b/scripts/generate-env.sh
@@ -44,6 +44,17 @@ generate_password() {
   echo "$password" | fold -w1 | shuf | tr -d '\n'
 }
 
+# Detect CPU architecture for healthcheck binary
+detect_arch() {
+  local arch
+  arch=$(uname -m)
+  case "$arch" in
+    x86_64)        echo "amd64" ;;
+    aarch64|arm64) echo "arm64" ;;
+    *)             echo "amd64" ;;  # fallback to amd64
+  esac
+}
+
 # Validate required inputs for ungeneratable values
 : "${GEN_APP_HOSTNAME:?Environment variable GEN_APP_HOSTNAME must be set}"
 : "${GEN_LETSENCRYPT_ACME_EMAIL:?Environment variable GEN_LETSENCRYPT_ACME_EMAIL must be set}"
@@ -54,6 +65,7 @@ POSTGRES_DB_PASSWORD=$(generate_password)
 POSTGRES_METRICS_PASSWORD=$(generate_password)
 GRAFANA_ADMIN_PASSWORD=$(generate_password)
 DHIS2_MONITOR_PASSWORD=$(generate_password)
+ARCH=$(detect_arch)
 
 # Detect GNU vs BSD sed
 if sed --version >/dev/null 2>&1; then
@@ -81,6 +93,7 @@ update_env_var "GRAFANA_ADMIN_PASSWORD" "$GRAFANA_ADMIN_PASSWORD"
 update_env_var "DHIS2_MONITOR_PASSWORD" "$DHIS2_MONITOR_PASSWORD"
 update_env_var "APP_HOSTNAME" "$GEN_APP_HOSTNAME"
 update_env_var "LETSENCRYPT_ACME_EMAIL" "$GEN_LETSENCRYPT_ACME_EMAIL"
+update_env_var "ARCH" "$ARCH"
 
 chmod u+rw,go-rwx "$OUTPUT_FILE"
 
diff --git a/scripts/update-admin-password.sh b/scripts/update-admin-password.sh
index 06af8af..0d8dec4 100755
--- a/scripts/update-admin-password.sh
+++ b/scripts/update-admin-password.sh
@@ -3,6 +3,9 @@
 set -o errexit
 set -o nounset
 
+# Install curl (not included in baosystems/postgis image)
+apt update && apt install -y --no-install-recommends curl
+
 URL="https://github.com/shoenig/bcrypt-tool/releases/download/v1.1.7/bcrypt-tool_1.1.7_linux_amd64.tar.gz"
 EXPECTED_SHA="7eb3f0cc159a54e4a1efb0fc56c11a5eb80efa5c88b482d0034eceea4cdf936e"
 
diff --git a/tools/README.md b/tools/README.md
new file mode 100644
index 0000000..9006576
--- /dev/null
+++ b/tools/README.md
@@ -0,0 +1,61 @@
+# Healthcheck Binary
+
+Lightweight static binary for Docker container health checks. Works in minimal/distroless images that lack curl, wget, or bash.
+
+## Source
+
+The binary is from: <https://github.com/netroms/simple_healthcheck>
+
+## Download at Runtime
+
+The healthcheck binary is downloaded at container startup by the `healthcheck-init` service. This avoids storing large binary files in the repository.
+
+### Environment Variables
+
+| Variable | Default | Description |
+|----------|---------|-------------|
+| `ARCH` | `amd64` | CPU architecture (`amd64` or `arm64`) |
+| `HEALTHCHECK_VERSION` | `1.0.0` | Version to download |
+| `HEALTHCHECK_SHA256_AMD64` | (see docker-compose.yml) | SHA256 for amd64 binary |
+| `HEALTHCHECK_SHA256_ARM64` | (see docker-compose.yml) | SHA256 for arm64 binary |
+
+The `ARCH` variable is auto-detected by `scripts/generate-env.sh`.
+
+## Usage
+
+```bash
+healthcheck [options] <url>
+```
+
+### Options
+
+| Flag | Default | Description |
+|------|---------|-------------|
+| `-timeout` | 5s | Request timeout |
+| `-status` | 200 | Expected HTTP status code (0 = accept any 2xx) |
+| `-json-field` | | JSON field to check (dot notation) |
+| `-json-value` | | Expected value for the JSON field |
+
+### Exit Codes
+
+| Code | Meaning |
+|------|---------|
+| 0 | Health check passed |
+| 1 | Health check failed |
+
+## Docker Compose Integration
+
+The binary is downloaded to a volume and mounted into the DHIS2 container:
+
+```yaml
+healthcheck:
+  test: [ "CMD", "/opt/dhis2/healthcheck-bin/healthcheck", "http://localhost:8080/api/ping" ]
+```
+
+## Updating
+
+To update to a new version:
+
+1. Find the latest release at <https://github.com/netroms/simple_healthcheck/releases>
+2. Get the SHA256 checksums for both architectures
+3. Update `HEALTHCHECK_VERSION` and the SHA256 variables in your `.env` file or docker-compose.yml
