Skip to content

Gatus

Gatus probes endpoints on a schedule, evaluates conditions on each answer — status code, response time, body content, certificate expiry — shows the results on a status page and alerts when a condition fails. Everything it does is defined in config/config.yaml, which can live in version control beside the rest of your setup. One container; the result history is a SQLite file.

Last run on a host 8 Nov 2026

Pinned at v5.38.0 (released 28 Oct 2026) · the newest upstream release

In the upstream images: 0 CRITICAL · 5 HIGH with a published fix — per image

To try it: Docker, nothing else. See Try it locally.

To deploy it behind the proxy: Traefik running and a domain.

On your own machine, with no proxy, domain or certificate. From monitoring/gatus/:

Terminal window
cp .env.local.example .env.local
mkdir -p config
cp config.example.yaml config/config.yaml
docker compose -f docker-compose.local.yml --env-file .env.local up -d

Then open http://localhost:8080. The example endpoints point at example.com hostnames and show red until you replace them with your own in config/config.yaml; Gatus reloads the file on save. Stop it again with the same command and down.

From monitoring/gatus/:

  1. Copy the environment file and set APP_TRAEFIK_HOST and TZ:

    Terminal window
    cp .env.example .env
  2. List gatus-edge in EDGE_NETWORKS in core/traefik/.env, then render and restart Traefik — see edge networks.

  3. Create the directories and the configuration:

    Terminal window
    mkdir -p config volumes/data
    cp config.example.yaml config/config.yaml

    Keep config.example.yaml where it is, next to docker-compose.yml. Gatus merges every .yaml file in config/, and two files with the same top-level keys stop it at startup.

  4. Replace the example endpoints in config/config.yaml with yours, and set up at least one alerting channel before adding alerts: to an endpoint:

    endpoints:
    - name: vaultwarden
    url: "https://vault.example.com"
    interval: 5m
    conditions:
    - "[STATUS] == 200"
    - "[CERTIFICATE_EXPIRATION] > 240h"
  5. Start it:

    Terminal window
    docker compose up -d
    docker compose logs gatus-app --follow

    Wait for Listening on :8080.

Terminal window
docker compose ps # one service, running — the image has no healthcheck

Open https://<APP_TRAEFIK_HOST>: every endpoint in the file appears with its results. Then break one condition on purpose — a wrong expected status, for example — save the file and watch the endpoint fail and the alert arrive.

The stack ships access-vpn, with limit-standard and headers-standard. The page and /api/v1/endpoints/statuses show every target URL, condition and alert destination. A login of Gatus’s own is configured under security: in config.yaml; a login in front of it is APP_TRAEFIK_AUTH=auth-authentik@file (Authentik). Make the page public only after checking what the configuration reveals.

config.yaml reads ${NAME} from the container’s environment. Put webhook URLs and SMTP passwords there instead of into the file, and the file can go into version control as it is. Each name has to reach the container: add it to the service’s environment: block in docker-compose.yml, with its value in .env.

alerting:
ntfy:
url: "https://ntfy.example.com"
topic: "alerts"
token: "${NTFY_TOKEN}"

ntfy, Gotify, Matrix, webhooks and email are all supported. metrics: true adds a Prometheus /metrics endpoint with per-endpoint availability, response times and certificate expiry.

SQLite carries about a hundred endpoints. For several hundred, or long retention, switch storage.type to postgres and add a database service.

Configuration config/config.yaml — the endpoints and alert rules
State volumes/data — SQLite result history
Rebuildable the history; losing it costs graphs, not function

For borgmatic:

sqlite_databases:
- name: gatus
path: /srv/docker/monitoring/gatus/volumes/data/data.db

The path is the one config.example.yaml sets under storage:. Restore order: config.yaml, then the database if the history matters, then start.

  1. Read the release notes.

  2. Raise APP_TAG in .env, then:

    Terminal window
    docker compose pull && docker compose up -d
  3. Open the page and check that every endpoint shows its status.

Gatus exits at start with only maps and slices/arrays can be merged. A second .yaml file sits in config/ — usually a copy of the example. Move it out.

A change to config.yaml has no effect. The reload hit a syntax error and kept the previous configuration. docker compose logs gatus-app names the line; check the log after every save.

An alert never fires. The endpoint has alerts: but the channel it names is not configured under alerting:, or the referenced ${NAME} is not set in the container’s environment.