New releases
Recipe version compared with the latest known upstream release. A version number, not a reading of what changed.
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.
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.
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.
These are stored results of separate checks, not real-time data. An unknown status means the check has not been performed yet.
Recipe version compared with the latest known upstream release. A version number, not a reading of what changed.
Result of a dedicated Docker image scan, not a Compose configuration check.
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.
Upstream Compose changes relative to the verified recipe.
Pinned image tags checked for newer versions.
From observation to action
The recipe already pins the latest known release. The steps below show the evidence retained for that version.
v5.37.0v5.37.0Open this release on GitHub ↗ The link is evidence to review, not proof of compatibility.
The version numbers do not cross a major compatibility boundary. No compatibility verdict has been recorded.
No image-tag change is currently planned.
Change the tag and restart. Release-specific migration steps still come from the release notes and installation guide.
No version change is currently planned. The recipe includes a backup procedure. Restore has been tested.
An exact Fully verified check for this target was recorded on 2026-10-09.
The status shows how fully the published recipe meets each level's requirements.
A minimal setup for a local network or access through a VPN.
The recipe covers every requirement at this level.
A public deployment with protected access and backups.
The recipe covers every requirement at this level.
A setup designed for predictable operations and observability.
You still need to add: separate database, healthcheck, external monitoring, cpu and memory limits.
Tailored to your server
Answer five questions and download a ready-to-run Gatus bundle.
Read the full guide first: it explains external access, backups, and data locations.
cp .env.example .envdocker compose up -ddocker compose psYou 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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Tell us how it went on your server
Opens a prefilled GitHub issue. A GitHub account is required; submitting the issue makes it public.
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.
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.
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.
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.
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.