Skip to main content

Gatus

A self-hosted uptime and health monitoring dashboard.

Gatus is an open-source health dashboard that periodically checks HTTP, TCP, and DNS endpoints and displays uptime status. It stores historical data in PostgreSQL and supports alerting via various channels. Self-hosting means no usage limits and full control over which internal services are monitored.

Alternatives considered

Cloud Hosted

ToolOpen SourceFree TierMonthly Cost
UptimeRobotNoLimitedFrom $7/mo
PingdomNoNoFrom $15/mo

Self Hosted

ToolOpen SourceFull FeaturesNotes
Uptime KumaYesYesSimpler UI, less config flexibility

Installation

Architecture

  • Deployment: Single gatus deployment in the gatus namespace; NetBird sidecar for VPN connectivity
  • Images: ghcr.io/twin/gatus:v5.35.0, netbirdio/netbird:latest (both digest-pinned)
  • Database: CNPG PostgreSQL cluster for uptime history
  • Config: Multiple ConfigMaps with endpoint definitions (arr services, internal tools, public web services)
  • Networking: HTTPRoute via public gateway

Security

  • Gatus container: readOnlyRootFilesystem: true, allowPrivilegeEscalation: false, capabilities dropped
  • NetBird sidecar requires NET_ADMIN capability (VPN tunnel)
  • runAsNonRoot: false on the pod level (namespace PSS set to privileged)

Updates

Managed by Renovate. Both images are digest-pinned.

Data Management

  • Database: CNPG PostgreSQL cluster (Longhorn-encrypted PVCs) for uptime history
  • Backups: k8up Schedule (schedule-hetzner) backs up to Hetzner S3 (workload-talos-gatus-f4b5c644). CNPG cluster annotated with k8up.io/backupcommand: pg_dump for consistent dumps. Retention: 7 daily, 4 weekly, 12 monthly, 5 yearly.

User Management

OIDC configured — OPENID_CLIENT_ID and OPENID_CLIENT_SECRET injected from SOPS secret. Issuer and redirect URL set in the Gatus config ConfigMap.

Configuration Management

  • Endpoint definitions from multiple ConfigMaps (arr services, internal tools, public web)
  • OIDC credentials from SOPS-encrypted secret
  • Database connection string from CNPG-generated secret

Administration

Usage

View the uptime dashboard to see current status of all monitored endpoints grouped by category (Arr, Int, Web, Talos). Configure new endpoints by editing the ConfigMap YAML files. Alerts can be triggered via the configured channels when checks fail.

Cluster-specific deviations from the above live in the per-cluster README — see k8s/apps/talos/gatus/README.md.

Cluster Deployment

Gatus — Talos cluster

Cluster-specific notes only. General product info, "why we use it", and alternatives live in docusaurus/docs/apps/gatus.mdx.

Deviations from defaults

Defaults live in docusaurus/docs/apps/gatus.mdx — document anything this cluster does differently here, with a one-line reason.

Kubernetes Metadata
  • Image: ghcr.io/twin/gatus:v5.36.0@sha256:c5f210d095fa78e6efaa20ffeb14803f2ba4f10615e16a6d12087697149617f0
  • Image: netbirdio/netbird:0.72.4@sha256:6c6c20baffae4a3ec50f29ec9361608a420625185505e8cd6f0c44d71c5d4798
Rendered manifests (kustomize build)
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kustomize.toolkit.fluxcd.io/force: enabled
labels:
app: gatus
name: gatus
namespace: gatus
spec:
replicas: 1
selector:
matchLabels:
app: gatus
ingress: public
strategy:
type: Recreate
template:
metadata:
labels:
app: gatus
ingress: public
spec:
containers:
- env:
- name: GATUS_CONFIG_PATH
value: /config
- name: POSTGRES_PATH
valueFrom:
secretKeyRef:
key: uri
name: cnpg-app
envFrom:
- secretRef:
name: gatus
image: ghcr.io/twin/gatus:v5.36.0@sha256:c5f210d095fa78e6efaa20ffeb14803f2ba4f10615e16a6d12087697149617f0
livenessProbe:
failureThreshold: 5
httpGet:
path: /
port: 8080
initialDelaySeconds: 15
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 5
name: gatus
ports:
- containerPort: 8080
name: web
protocol: TCP
readinessProbe:
failureThreshold: 5
httpGet:
path: /
port: 8080
initialDelaySeconds: 15
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 5
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
startupProbe:
failureThreshold: 5
httpGet:
path: /
port: 8080
initialDelaySeconds: 15
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 5
volumeMounts:
- mountPath: /config
name: gatus-config
readOnly: true
initContainers:
- env:
- name: NB_SETUP_KEY
valueFrom:
secretKeyRef:
key: NB_SETUP_KEY
name: gatus-netbird
image: netbirdio/netbird:0.72.4@sha256:6c6c20baffae4a3ec50f29ec9361608a420625185505e8cd6f0c44d71c5d4798
name: sidecar-netbird
restartPolicy: Always
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_ADMIN
startupProbe:
exec:
command:
- sh
- '-c'
- netbird status | grep -q Connected
failureThreshold: 30
periodSeconds: 2
volumes:
- configMap:
name: gatus-config-mc474787mb
name: gatus-config