Fully verified12,128

Monitoring

Gatus

Gatus runs HTTP, TCP, DNS, ICMP, and certificate checks from a YAML configuration, evaluates explicit conditions, and displays their history on a status dashboard. This recipe keeps results in SQLite, protects the dashboard with Basic Auth, and needs one small container.

Overview

Gatus turns a YAML file into scheduled availability checks and a status dashboard. It can probe HTTP responses, TCP and UDP ports, DNS, ICMP, SSH, certificates, domain expiry, and multi-step API suites, then evaluate explicit conditions instead of treating any response as success.

It suits operators who want monitoring configuration in version control and do not need a form-driven editor. The dashboard shows response history and incidents, while alert providers cover email, chat systems, webhooks, and on-call services. This recipe uses the built-in SQLite storage so the check history survives restarts without a separate database.

The dashboard edits no endpoints. Change config/config.yaml, review the diff, and restart Gatus; this is the main difference from Uptime Kuma’s UI-first workflow.

Security assessment

The recipe publishes Gatus on 127.0.0.1, enables Basic Auth from .env, sets no-new-privileges, and grants no capabilities, host networking, or Docker socket. Public access belongs behind an HTTPS reverse proxy.

Gatus is an outbound probe by design. Anyone who can change config.yaml can make requests to addresses reachable from its container network, including private services. Limit write access to the recipe directory. The official image also runs as root by default; the recipe narrows what that process can reach on the host, but does not change its container user.

Update tracking

These are stored results of separate checks, not real-time data. An unknown status means the check has not been performed yet.

New releases

Recipe version compared with the latest known upstream release. A version number, not a reading of what changed.

Current version v5.37.0Oct 9, 2026, 1:58 PM UTC

Critical vulnerabilities

Result of a dedicated Docker image scan, not a Compose configuration check.

No critical vulnerabilities foundOct 9, 2026, 1:58 PM UTC

Breaking updates

A new major version is found by comparing version numbers. A compatibility verdict is entered by hand after reading the release notes and the migration steps.

Not checkedNot checked

compose.yaml

Upstream Compose changes relative to the verified recipe.

Not checkedNot checked

Outdated Docker images

Pinned image tags checked for newer versions.

All images are currentOct 9, 2026, 1:58 PM UTC

From observation to action

Update plan

The recipe already pins the latest known release. The steps below show the evidence retained for that version.

v5.37.0v5.37.0
  1. Open the release evidence

    Open this release on GitHub ↗ The link is evidence to review, not proof of compatibility.

  2. Review the version boundary

    The version numbers do not cross a major compatibility boundary. No compatibility verdict has been recorded.

  3. Prepare image-tag changes

    No image-tag change is currently planned.

  4. Follow the documented migration shape

    Change the tag and restart. Release-specific migration steps still come from the release notes and installation guide.

  5. Protect the rollback point

    No version change is currently planned. The recipe includes a backup procedure. Restore has been tested.

  6. Verify the updated recipe

    An exact Fully verified check for this target was recorded on 2026-10-09.

Read the update procedure in the installation guide ↓

Specifications

Security and exposure

Installation levels

The status shows how fully the published recipe meets each level's requirements.

Ready

For home

A minimal setup for a local network or access through a VPN.

  • Single server
  • Local access
  • Minimum components

The recipe covers every requirement at this level.

Ready

For a VPS

A public deployment with protected access and backups.

  • Domain
  • HTTPS via reverse proxy
  • Off-server backup

The recipe covers every requirement at this level.

Not supported

Reliable

A setup designed for predictable operations and observability.

  • Separate database
  • Healthcheck
  • External monitoring
  • CPU and memory limits

You still need to add: separate database, healthcheck, external monitoring, cpu and memory limits.

Tailored to your server

Configuration generator

Answer five questions and download a ready-to-run Gatus bundle.

Runs locally
01 Do you have a domain?
02 Which reverse proxy?
03 Server architecture
04 Where should data be stored?

Use an absolute path for a separate disk, such as /srv/gatus.

05 Is VPN access required?

Your bundle is ready

The archive is created in your browser. Your answers are never sent anywhere.

The same files as one shell script, written in plain heredocs so you can read the whole thing before it runs. It checks Docker, the architecture, memory, disk and the ports it needs, and writes nothing until you add --apply.

Screenshots

Quick start

Read the full guide first: it explains external access, backups, and data locations.

Prepare settingscp .env.example .env
Launchdocker compose up -d
Check statusdocker compose ps

Step-by-step guide

1. Check the server

You need Ubuntu 22.04+ or Debian 12+ with Docker Engine and Docker Compose v2.24+. Budget 1 CPU, 128 MB of RAM, and 1 GB of local disk; 256 MB of RAM leaves room for more checks and history. This recipe uses SQLite and needs no separate database.

docker --version
docker compose version

2. Prepare the files and variables

Put compose.yaml, .env.example, config/, backup.sh, restore.sh, and proxy/ in a directory of their own:

mkdir -p ~/services/gatus
cd ~/services/gatus
cp .env.example .env
chmod 600 .env

.env holds the pinned GATUS_VERSION, local GATUS_PORT, Docker volume name, GATUS_CONFIG_DIR, and the dashboard credentials. Keep the configuration directory at ./config unless you also want backups to read it elsewhere. Replace change-me. Gatus stores a bcrypt hash, not a plain password; these commands create a password and the Base64-encoded hash to put in GATUS_PASSWORD_BCRYPT_BASE64:

password="$(openssl rand -base64 32)"
printf 'Password: %s\n' "$password"
htpasswd -bnBC 9 "" "$password" | tr -d ':\n' | base64 -w0
printf '\n'

htpasswd comes from apache2-utils on Ubuntu and Debian. Save the printed password in a password manager; the hash in .env cannot be turned back into it.

The monitored targets live in config/config.yaml. The included self-check proves that scheduling, condition evaluation, SQLite storage, and the dashboard work before you add your own services. Keep secrets for alert providers in .env, pass them through compose.yaml, and reference their environment names from the configuration instead of writing tokens into YAML.

3. Start the container on a VPS

docker compose pull
docker compose up -d
docker compose ps
curl http://127.0.0.1:8080/health

The last command should print {"status":"UP"}. Gatus has no image-level Docker healthcheck, so verify both /health and a completed endpoint result in the dashboard after startup.

4. Open the dashboard and add checks

Use an SSH tunnel before the reverse proxy exists:

ssh -L 8080:127.0.0.1:8080 user@server.example

Open http://localhost:8080 and sign in with the credentials from .env. Wait for Gatus health to turn green and open it to see the successful conditions.

Add an endpoint to config/config.yaml, for example:

  - name: Public website
    group: Production
    url: https://www.example.com/
    interval: 1m
    conditions:
      - "[STATUS] == 200"
      - "[CERTIFICATE_EXPIRATION] > 48h"
      - "[RESPONSE_TIME] < 1000"

Run docker compose restart gatus and inspect the logs. Start with a status, certificate, and generous response-time condition; tighten the threshold only after observing normal traffic. A green HTTP check proves that this request worked, not that every feature of the target application works.

Local network

Keep the localhost bind and use an SSH tunnel. If the dashboard must be visible on a trusted LAN, replace 127.0.0.1 in compose.yaml with the server’s LAN address, such as 192.168.1.10, and block port 8080 on the external interface. Do not bind it to every interface merely for convenience.

Domain and HTTPS

The examples in proxy/ forward status.example.com to the local port. Replace that name with your domain. Caddy obtains a certificate automatically; the Nginx example expects Certbot files; the Traefik example uses a resolver named letsencrypt. For Traefik running in a container, replace 127.0.0.1 with a host gateway address that its container can reach.

Basic Auth remains enabled behind the proxy. Gatus also supports OIDC, but moving authentication to an identity provider requires an OIDC client secret and a deliberate edit of the security block; do not enable both modes by accident.

Backup

chmod +x backup.sh restore.sh
./backup.sh

The script stops Gatus so SQLite’s database, WAL, and shared-memory files form a consistent set, then archives the data volume together with config/. It starts the container again before returning. Keep an encrypted copy off the server; the archive contains monitored URLs and may contain alerting configuration.

Restore

Restoring replaces both the database and configuration:

./restore.sh ./backups/gatus-YYYYMMDDTHHMMSSZ.tar.gz
docker compose ps

The script validates the archive and takes a safety backup of the current state first. Afterward, check /health, sign in, and confirm that endpoint names, history, and announcements are the ones you expected.

Update

Back up the instance, read the upstream release notes, change GATUS_VERSION in .env, then recreate the container:

docker compose pull
docker compose up -d
docker compose logs --tail=100 gatus

Check /health and wait for every endpoint to produce a fresh result. Gatus applies SQLite schema changes on startup; an HTTP response alone does not prove that existing history remains readable.

Rollback

Put the previous GATUS_VERSION back in .env and run docker compose pull && docker compose up -d. If the old image cannot read a database changed by the new release, keep the old version selected and restore the pre-update archive.

Complete removal

docker compose down stops Gatus and keeps the database. To remove everything:

docker compose down
docker volume rm gatus-data
rm -rf ~/services/gatus

Sources: official Docker usage, configuration reference, storage, and security.

Report a recipe problem

Tell us how it went on your server

Opens a prefilled GitHub issue. A GitHub account is required; submitting the issue makes it public.

Troubleshooting

Gatus exits immediately

Gatus rejects an invalid configuration instead of starting with part of it:

docker compose ps --all
docker compose logs --tail=200 gatus

YAML indentation, a duplicate primitive setting split across files, and an invalid condition are common causes. Fix config/config.yaml, then run docker compose up -d again.

/health works but no check is green

/health only proves that Gatus serves requests. Inspect the endpoint result and container logs:

read -r -p 'Username: ' GATUS_USERNAME
read -r -s -p 'Password: ' GATUS_PASSWORD
curl --user "${GATUS_USERNAME}:${GATUS_PASSWORD}" \
  http://127.0.0.1:8080/api/v1/endpoints/statuses
docker compose logs --tail=200 gatus

Run the same DNS lookup or HTTP request from the server. A target that works in your browser may be blocked from the server, resolve to a private address, or present a different certificate there.

Port 8080 is taken

Change GATUS_PORT in .env, then recreate the container:

docker compose up -d

Update the reverse proxy’s upstream port too. Leave the bind on 127.0.0.1.

The dashboard returns 401

Use the current GATUS_USERNAME from .env and the plain password whose hash is stored in GATUS_PASSWORD_BCRYPT_BASE64. If you changed them, recreate rather than merely restarting the process:

docker compose up -d --force-recreate

Do not remove the security block to regain access on a public server. Set new credentials and verify them through the localhost address first.

History disappears after a restart

Confirm that Gatus uses SQLite at /data/data.db and that the expected volume is mounted:

docker compose config
docker volume inspect gatus-data

If storage.type became memory, new results were never persisted. Restore the configuration and database from backup before deleting any old volume.

Official sources

Latest release: 2026-05-19 · GitHub Stars: 12,128 · metadata checked Sep 22, 2026, 5:47 AM UTC

Disclaimer

Fossary is an independent informational catalog and is not affiliated with the developers of the listed applications. We collect information from public sources and verify published recipes, but we do not develop, distribute, or control these applications.

A listing or validation status is not a requirement, endorsement, or personal recommendation to use an application. You decide whether it is suitable and use it at your own risk. We do not warrant an application's security, availability, or fitness for purpose and, to the extent permitted by law, are not liable for resulting loss or damage. Review its license, security settings, data processing, and backup procedures before installation.