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.
Try it locally
Section titled “Try it locally”On your own machine, with no proxy, domain or certificate. From monitoring/gatus/:
cp .env.local.example .env.localmkdir -p configcp config.example.yaml config/config.yamldocker compose -f docker-compose.local.yml --env-file .env.local up -dThen 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.
Installation
Section titled “Installation”From monitoring/gatus/:
-
Copy the environment file and set
APP_TRAEFIK_HOSTandTZ:Terminal window cp .env.example .env -
List
gatus-edgeinEDGE_NETWORKSincore/traefik/.env, then render and restart Traefik — see edge networks. -
Create the directories and the configuration:
Terminal window mkdir -p config volumes/datacp config.example.yaml config/config.yamlKeep
config.example.yamlwhere it is, next todocker-compose.yml. Gatus merges every.yamlfile inconfig/, and two files with the same top-level keys stop it at startup. -
Replace the example endpoints in
config/config.yamlwith yours, and set up at least one alerting channel before addingalerts:to an endpoint:endpoints:- name: vaultwardenurl: "https://vault.example.com"interval: 5mconditions:- "[STATUS] == 200"- "[CERTIFICATE_EXPIRATION] > 240h" -
Start it:
Terminal window docker compose up -ddocker compose logs gatus-app --followWait for
Listening on :8080.
Verify
Section titled “Verify”docker compose ps # one service, running — the image has no healthcheckOpen 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.
Going further
Section titled “Going further”Who can reach it
Section titled “Who can reach it”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.
Secrets in the configuration
Section titled “Secrets in the configuration”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.
Many endpoints
Section titled “Many endpoints”SQLite carries about a hundred endpoints. For several hundred, or long
retention, switch storage.type to postgres and add a database service.
Backup
Section titled “Backup”| 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.dbThe path is the one config.example.yaml sets under storage:. Restore order:
config.yaml, then the database if the history matters, then start.
Updates
Section titled “Updates”-
Read the release notes.
-
Raise
APP_TAGin.env, then:Terminal window docker compose pull && docker compose up -d -
Open the page and check that every endpoint shows its status.
Troubleshooting
Section titled “Troubleshooting”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.
Repository files
Section titled “Repository files”monitoring/gatus/README.md— setup, security model, integration patternsmonitoring/gatus/config.example.yaml— storage, UI, alerting and endpoint examplesmonitoring/gatus/.env.examplemonitoring/gatus/UPSTREAM.md— upgrade checklist
Official sources
Section titled “Official sources”- Gatus
- Gatus on GitHub — the configuration reference
© 2026 SecDockBlueCode Apache-2.0Site content CC BY-NC 4.0