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
| Tool | Open Source | Free Tier | Monthly Cost |
|---|---|---|---|
| UptimeRobot | No | Limited | From $7/mo |
| Pingdom | No | No | From $15/mo |
Self Hosted
| Tool | Open Source | Full Features | Notes |
|---|---|---|---|
| Uptime Kuma | Yes | Yes | Simpler UI, less config flexibility |
Installation
Architecture
- Deployment: Single
gatusdeployment in thegatusnamespace; 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_ADMINcapability (VPN tunnel) runAsNonRoot: falseon 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 withk8up.io/backupcommand: pg_dumpfor 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.
- 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