--- # Gatus, deployed the way upstream distributes it: the container image. # # Upstream publishes NO binary release assets - the image is the only artefact # they ship, and therefore the only artefact they test. Building from source is # possible (`go build` alone is enough; the Vue dashboard is compiled in via # `//go:embed static`, and CGO_ENABLED=0 works because the sqlite driver is # pure-Go modernc.org/sqlite) but it produces a binary upstream never ran, and # it means a full compile of the AWS SDK and gRPC on the smallest box in the # estate. # ── Image ──────────────────────────────────────────────────────────────────── gatus_version: "v5.36.0" # Pinned by DIGEST, not by tag. A tag is mutable - `v5.36.0` can be repushed - # so pinning the tag alone is a weaker promise than it looks. The digest is the # content address: if it resolves, it is byte-for-byte the image reviewed here. # Both must be updated together; the tag is kept only so humans can read it. gatus_image_digest: "sha256:c5f210d095fa78e6efaa20ffeb14803f2ba4f10615e16a6d12087697149617f0" gatus_image: "ghcr.io/twin/gatus@{{ gatus_image_digest }}" # ── Paths (host side) ──────────────────────────────────────────────────────── gatus_dir: /opt/gatus gatus_config_dir: "{{ gatus_dir }}/config" gatus_data_dir: "{{ gatus_dir }}/data" # Gatus merges every *.yaml under GATUS_CONFIG_PATH and its subdirectories: # maps deep-merge, lists append. That is why this role ships a config DIRECTORY # rather than one file - each service contributes its own endpoint file, the # same way each service contributes a vhost through `caddy_site`. # # Primitives must be defined exactly once across all files or the merge is # ambiguous, so everything that is not a list lives in the base file and # nowhere else. gatus_base_config_file: "00-base.yaml" gatus_endpoints_dir: "{{ gatus_config_dir }}/endpoints" # ── Identity ───────────────────────────────────────────────────────────────── # The image is FROM scratch, so it has no /etc/passwd and no user to drop to by # name. Run it by numeric uid/gid instead, and own the data volume to match. gatus_uid: 10001 gatus_gid: 10001 # ── Web ────────────────────────────────────────────────────────────────────── gatus_port: 8080 # HOST-side address the container's port is published on. Gatus itself always # binds 0.0.0.0 inside the container - see the note in config.yaml.j2. Never # publish this on 0.0.0.0: the external-endpoint push API shares the dashboard's # listener, and Caddy is what should be in front of both. gatus_bind_address: "127.0.0.1" gatus_ui_title: "Status" gatus_ui_header: "Status" # ── Storage ────────────────────────────────────────────────────────────────── # sqlite, not memory: history has to survive a restart, or the dashboard lies # about uptime after every deploy. Path is INSIDE the container. gatus_storage_type: sqlite gatus_storage_path: "/data/gatus.db" gatus_storage_caching: true # Per-endpoint row caps. Gatus bounds the database by COUNT, not by time, and # trims inline on insert (storage/store/sql/sql.go, InsertEndpointResult) - so # there is no retention job to write and no way for this to fill a disk. # # History depth is therefore a function of check frequency, not of days: # 900 results is ~3 days of a 5-minute liveness check, and ~2.5 years of a daily # disk check. Upstream's default is 100, which would have been 8 hours of # liveness - not enough to still see a weekend incident on Monday. # # Note the uptime table is separate and its 30-day retention is hard-coded # upstream (uptimeRetention), so uptime percentages top out at 30 days whatever # this is set to. gatus_storage_max_results: 900 gatus_storage_max_events: 50 # ── Alerting ───────────────────────────────────────────────────────────────── # Pass-through: rendered verbatim under `alerting:`, so any provider Gatus # supports works without touching this role. Empty means "check and record, # alert nowhere" - valid, and the default until a provider is chosen. gatus_alerting: {} gatus_default_alerts: [] # ── Security ───────────────────────────────────────────────────────────────── # gatus_basic_auth: {username: admin, password-bcrypt-base64: "..."} gatus_basic_auth: {} gatus_maintenance: {} # Keep serving the previous config if a contributed endpoint file is malformed, # instead of panicking. See the note in config.yaml.j2. gatus_skip_invalid_config_update: true gatus_log_level: INFO # ── Self-check ─────────────────────────────────────────────────────────────── # Gatus panics on a config with no endpoints, so the role always ships one. # Turning this off is only safe once another file in endpoints/ provides one. gatus_self_check: true # ── ICMP ───────────────────────────────────────────────────────────────────── # Gatus supports icmp:// endpoints. Raw ICMP needs CAP_NET_RAW, which the # container would get free only if it ran as root; it does not. Set false if # you never use icmp:// checks and want the capability dropped entirely. gatus_allow_icmp: true