Skip to content
STACK IT FAST

Gatus

Curated OSSClassicAutomated Health Dashboard & Status Monitorsolo

Audited from github.com/TwiN/gatus

Gatus is a self-hosted, developer-oriented health dashboard that runs configurable HTTP, ICMP, TCP, DNS, gRPC and other checks against services and turns failing conditions into Slack, PagerDuty and other alerts.

Language
Go
Database
SQLite
Hosting
Docker
License
Apache-2.0
Running for
4 years
Team
solo

Why this architecture

The whole product ships as one Go binary with the Vue dashboard embedded via go:embed and YAML-defined check conditions, so a status page needs no separate frontend server and, by default, no external database.

Tech stack by layer

9 technologies · audited Sep 17, 2026
Frontend & UI
  • VueVue 3 dashboard (web/app) built with vue-cli-service; the compiled bundle is embedded into the Go binary.
  • Chart.jsResponse-time and uptime graphs via vue-chartjs, chartjs-adapter-date-fns and chartjs-plugin-annotation.
  • Tailwind CSSUtility CSS for the dashboard, composed with class-variance-authority and tailwind-merge for shadcn-style variants.
Backend & APIs
  • GoThe entire server, health-check engine and alerting logic is a single Go module (main.go, go.mod requires go1.26).
  • FiberHTTP framework (gofiber/fiber/v2, backed by valyala/fasthttp) serving the API and the embedded dashboard.
  • PrometheusExposes check results as Prometheus metrics via prometheus/client_golang.
Data & Persistence
  • SQLiteDefault storage backend for endpoint status history (modernc.org/sqlite, pure-Go driver, no CGO).
  • PostgreSQLAlternative storage backend for status history via lib/pq, documented for multi-replica setups.
Infrastructure & Deploy
  • DockerMulti-stage build: golang:alpine compiles the binary, then a scratch image runs it with the frontend baked in.
  • GitHub Actionstest.yml, test-ui.yml, benchmark.yml and four publish-*.yml workflows build and push images per branch/tag.
Tooling, Testing & Ops
  • Go testingUnit tests and benchmarks live alongside every package (api/*_test.go, jsonpath/jsonpath_bench_test.go).

Gatus architecture diagram

Open SVG
Gatus architecture diagramDashboard users → gatus binary (HTTP); Badges & API → gatus binary (badges); gatus binary → Embedded dashboard (serves SPA); Health checks → Monitored endpoints (probe); Health checks → Status history (results); Health checks → Alerting (on failure); gatus binary → Status history (read history); Prometheus → gatus binary (scrape)CLIENTSSERVICESWORKERS & JOBSDATA & STORAGEEXTERNALDashboard usersstatus pageBadges & APIREADME badges · JSONgatus binaryGo · FiberEmbedded dashboardVue 3 · Chart.jsHealth checksendpoint suitesAlerting30+ providersStatus historySQLite / PostgreSQLMonitored endpointsHTTP · TCP · DNS …Prometheus/metricsserves SPAon failureHTTPbadgesresultsproberead historyscrape
How the main components of Gatus connect, drawn from the audited repository.
Diagram as text
  • Dashboard users (status page) → gatus binary (Go · Fiber): HTTP
  • Badges & API (README badges · JSON) → gatus binary (Go · Fiber): badges
  • gatus binary (Go · Fiber) → Embedded dashboard (Vue 3 · Chart.js): serves SPA
  • Health checks (endpoint suites) → Monitored endpoints (HTTP · TCP · DNS …): probe
  • Health checks (endpoint suites) → Status history (SQLite / PostgreSQL): results
  • Health checks (endpoint suites) → Alerting (30+ providers): on failure
  • gatus binary (Go · Fiber) → Status history (SQLite / PostgreSQL): read history
  • Prometheus (/metrics) → gatus binary (Go · Fiber): scrape

Key architectural decisions

6 decisions
  1. 01

    Single Go binary embeds the entire Vue frontend

    web/static.go serves the vue-cli-service build output from inside the Go binary, so a Gatus deployment is one executable plus a YAML config file; the Makefile frontend-build target compiles web/app before the Go build runs.

  2. 02

    Endpoint checks are configuration, not code

    config/endpoint, config/suite and config/connectivity define a YAML schema (config.yaml) where each check is a list of string conditions like "[STATUS] == 200"; jsonpath/jsonpath.go and pattern/pattern.go implement the condition language without an external expression engine.

  3. 03

    Fiber over the standard library net/http

    api/api.go builds on gofiber/fiber/v2 (valyala/fasthttp underneath) rather than net/http, trading some standard-library compatibility for lower overhead on the badge and chart endpoints that render per-request.

  4. 04

    Storage is pluggable but defaults to embedded SQLite

    storage/config.go and storage/store select between SQLite (modernc.org/sqlite, no CGO required) and PostgreSQL (lib/pq); the .examples directory ships a docker-compose file for each, plus one for sharing state across multiple remote instances.

  5. 05

    Alerting providers are a plugin-style package, not a webhook wrapper

    alerting/provider implements native clients for over 30 destinations (Slack, PagerDuty, Discord, Twilio, Teams, AWS SES via aws-sdk-go-v2, Gitea via code.gitea.io/sdk/gitea, and a generic custom provider), so watchdog/alerting.go can dispatch structured alerts without shelling out to curl.

  6. 06

    Author-maintained micro-libraries replace common third-party deps

    go.mod pulls in TwiN/gocache, TwiN/health, TwiN/logr, TwiN/whois and TwiN/deepmerge — small single-purpose packages by the same maintainer (TwiN) instead of heavier general-purpose alternatives, keeping the dependency tree narrow for a project shipped as a single static binary.

How Gatus is built

How Gatus is structured

The repository is a single Go module (github.com/TwiN/gatus/v5) with a web/app subtree holding the Vue frontend. There is no monorepo tooling: the Makefile's frontend-build target runs npm --prefix web/app run build, and web/static.go embeds the resulting assets so the compiled Go binary serves both the API and the dashboard from one process. Domain logic is split into small, single-purpose packages: config (YAML schema and endpoint/suite/maintenance definitions), watchdog (the scheduling loop that runs checks and fires alerts), alerting (per-provider alert clients), storage (the pluggable persistence layer), api (Fiber HTTP handlers for the dashboard, badges and raw data), jsonpath and pattern (the condition language's own JSONPath and glob-pattern implementations), and security (basic auth, OIDC, sessions).

Frontend

The dashboard lives in web/app and is a Vue 3.5 single-page app built with vue-cli-service (Vue CLI, not Vite), styled with Tailwind CSS 3 and class-variance-authority/tailwind-merge for component variants. Charts are rendered with vue-chartjs on top of Chart.js, using chartjs-adapter-date-fns for time axes and chartjs-plugin-annotation for maintenance-window overlays. lucide-vue-next supplies icons, dompurify sanitizes any HTML rendered from config, and marked renders Markdown in announcements. vue-router handles client-side navigation between the endpoint list and detail views.

Backend & APIs

api/api.go wires up a Fiber (gofiber/fiber/v2, built on valyala/fasthttp) application rather than the standard library's net/http. Handlers in api/badge.go, api/chart.go, api/raw.go and api/endpoint_status.go render per-endpoint uptime and response-time badges and JSON status data, some generated with wcharczuk/go-chart/v2 for the response-time badge images. api/spa.go serves the embedded Vue build for everything else. security/basic.go and security/oidc.go (via coreos/go-oidc/v3) protect the dashboard, and security/sessions.go manages cookie sessions. client/client.go and client/grpc.go implement the protocol clients used to actually run checks — HTTP, TCP, ICMP (prometheus-community/pro-bing), DNS (miekg/dns), gRPC, WebSocket, SSH, STARTTLS/TLS and SCTP (ishidawataru/sctp) — and config/remote lets one Gatus instance aggregate results from others.

Data & persistence

storage/config.go and storage/store select the persistence backend at startup. The default is embedded SQLite through modernc.org/sqlite, a CGO-free driver, which keeps the Docker image a single static binary with no external database dependency. lib/pq provides a PostgreSQL option for teams that want shared storage across replicas or persistence independent of the container filesystem; .examples/docker-compose-sqlite-storage and .examples/docker-compose-postgres-storage show both configurations end to end.

Build, test & deploy

test.yml and test-ui.yml run Go tests (go test ./... -cover, per the Makefile) and frontend checks in GitHub Actions; benchmark.yml runs the Go benchmark suite present in packages like jsonpath and pattern. Four publish-*.yml workflows push Docker images for latest, release, experimental and custom builds. The Dockerfile is a two-stage build: golang:alpine compiles the binary with CGO_ENABLED=0, then a scratch image copies in the binary, the default config.yaml and CA certificates, exposing PORT (default 8080).

Self-hosting notes

Because the image is built FROM scratch with CGO_ENABLED=0, a self-hosted Gatus needs no runtime dependencies beyond the container itself and a mounted config file (GATUS_CONFIG_PATH). The .examples directory documents the common deployment shapes: plain docker-compose, a minimal Docker setup, Kubernetes manifests, a NixOS module, multiple config files merged together, mutual TLS between Gatus and monitored services, and both storage backends. For anything beyond a single-node deployment, the choice is PostgreSQL storage plus config/remote to federate multiple instances, rather than a built-in clustering mode.

What to copy (and what not to)

The single-binary-with-embedded-frontend pattern (web/static.go) is worth copying for any small self-hosted tool: it removes an entire class of "frontend build didn't match backend version" deployment bugs. The condition-as-string configuration language (config/endpoint, jsonpath, pattern) is a reasonable way to expose flexible logic to YAML users without embedding a scripting language, though it means the condition grammar itself becomes a maintenance surface. Be cautious about copying the very long list of native alert-provider integrations (alerting/provider) unless alerting destinations are genuinely central to the product — for many tools, a single generic webhook provider covers the same ground with far less code to keep in sync with each vendor's API.

Sources & repo audit

Audited
Sep 17, 2026
Commit
7f3873d
License
Apache-2.0

Independent analysis of repository at github.com/TwiN/gatus. Spotted an inaccuracy? Use the claim form to request a correction.

Show this stack on your README or website
Tech stack of Gatus
[![Tech stack of Gatus on STACK IT FAST](https://stackitfast.com/badge/gatus.svg)](https://stackitfast.com/project/gatus)

Paste it into your README. It shows your current stack and links to this page.

Use this stack

Scaffold it with your agent

Paste this prompt into Claude Code, Cursor, Windsurf or AGY to start a project with Gatus's architecture.

  1. 1Copy the promptThe full markdown spec, with every layer and decision.
  2. 2Open your AI toolClaude Code, Cursor, Windsurf or Copilot, in a new repo.
  3. 3Paste and scaffoldUse it as the first instruction; review before you ship.
use-this-stack.md · 61 lines · 7.3 KB
# MISSION: Scaffold "Gatus" Production Architecture
You are an expert Senior Staff Software Architect and Full-Stack Engineer. Your mission is to scaffold and implement a production-grade, highly reliable, and modular codebase following the proven architecture of **Gatus**.
---
## 1. PROJECT SPECIFICATIONS & BENCHMARK
- **Reference Architecture**: Gatus
- **What It Does**: Gatus is a self-hosted, developer-oriented health dashboard that runs configurable HTTP, ICMP, TCP, DNS, gRPC and other checks against services and turns failing conditions into Slack, PagerDuty and other alerts.
- **Domain & Category**: Automated Health Dashboard & Status Monitor
- **Production Scale**: solo
- **Development Mode**: CLASSIC
- **Architectural Rationale**: The whole product ships as one Go binary with the Vue dashboard embedded via go:embed and YAML-defined check conditions, so a status page needs no separate frontend server and, by default, no external database.
- **Live Website Reference**: https://gatus.io
- **Source Repository**: https://github.com/TwiN/gatus
---
## 2. PRODUCTION TECH STACK
- **Full Stack Array**: Go, Vue, Fiber, SQLite, PostgreSQL, Chart.js, Tailwind CSS, Prometheus, Docker
- **Primary Language(s)**: Go, Vue
- **License of the reference repo**: Apache-2.0
- **Frontend**: Vue — Vue 3 dashboard (web/app) built with vue-cli-service; the compiled bundle is embedded into the Go binary.; Chart.js — Response-time and uptime graphs via vue-chartjs, chartjs-adapter-date-fns and chartjs-plugin-annotation.; Tailwind CSS — Utility CSS for the dashboard, composed with class-variance-authority and tailwind-merge for shadcn-style variants.
- **Backend & APIs**: Go — The entire server, health-check engine and alerting logic is a single Go module (main.go, go.mod requires go1.26).; Fiber — HTTP framework (gofiber/fiber/v2, backed by valyala/fasthttp) serving the API and the embedded dashboard.; Prometheus — Exposes check results as Prometheus metrics via prometheus/client_golang.
- **Data & persistence**: SQLite — Default storage backend for endpoint status history (modernc.org/sqlite, pure-Go driver, no CGO).; PostgreSQL — Alternative storage backend for status history via lib/pq, documented for multi-replica setups.
- **Infrastructure & deploy**: Docker — Multi-stage build: golang:alpine compiles the binary, then a scratch image runs it with the frontend baked in.; GitHub Actions — test.yml, test-ui.yml, benchmark.yml and four publish-*.yml workflows build and push images per branch/tag.
- **Tooling, testing & ops**: Go testing — Unit tests and benchmarks live alongside every package (api/*_test.go, jsonpath/jsonpath_bench_test.go).
---
## 3. KEY ARCHITECTURAL DECISIONS (audited from https://github.com/TwiN/gatus @ 7f3873d)
1. **Single Go binary embeds the entire Vue frontend**: web/static.go serves the vue-cli-service build output from inside the Go binary, so a Gatus deployment is one executable plus a YAML config file; the Makefile frontend-build target compiles web/app before the Go build runs.
2. **Endpoint checks are configuration, not code**: config/endpoint, config/suite and config/connectivity define a YAML schema (config.yaml) where each check is a list of string conditions like "[STATUS] == 200"; jsonpath/jsonpath.go and pattern/pattern.go implement the condition language without an external expression engine.
3. **Fiber over the standard library net/http**: api/api.go builds on gofiber/fiber/v2 (valyala/fasthttp underneath) rather than net/http, trading some standard-library compatibility for lower overhead on the badge and chart endpoints that render per-request.
4. **Storage is pluggable but defaults to embedded SQLite**: storage/config.go and storage/store select between SQLite (modernc.org/sqlite, no CGO required) and PostgreSQL (lib/pq); the .examples directory ships a docker-compose file for each, plus one for sharing state across multiple remote instances.
5. **Alerting providers are a plugin-style package, not a webhook wrapper**: alerting/provider implements native clients for over 30 destinations (Slack, PagerDuty, Discord, Twilio, Teams, AWS SES via aws-sdk-go-v2, Gitea via code.gitea.io/sdk/gitea, and a generic custom provider), so watchdog/alerting.go can dispatch structured alerts without shelling out to curl.
6. **Author-maintained micro-libraries replace common third-party deps**: go.mod pulls in TwiN/gocache, TwiN/health, TwiN/logr, TwiN/whois and TwiN/deepmerge — small single-purpose packages by the same maintainer (TwiN) instead of heavier general-purpose alternatives, keeping the dependency tree narrow for a project shipped as a single static binary.
---
## 4. NON-NEGOTIABLE ARCHITECTURAL GUARDRAILS
1. **Monorepo & Modular Separation**:
   - Structure as a Turborepo monorepo with strict package boundaries:
     - `apps/web`: Application UI, routing, layouts, and server endpoints.
     - `packages/ui`: Shared design tokens, CSS variables, and Radix UI primitive components.
     - `packages/db`: Database schemas, client singleton, declarative migrations, and seed scripts.
     - `packages/config`: Shared TypeScript, ESLint, and build configurations.
2. **Strict Type Safety & Zero `any` Policy**:
   - Enable `strict: true`, `noImplicitAny: true`, and `strictNullChecks: true`.
   - Validate ALL external inputs, API request bodies, and query parameters with **Zod** schemas before execution.
3. **Frontend & Rendering Guidelines**:
   - Isolate interactive UI state to leaf components. Keep core pages lightweight and performant.
4. **Design System & Aesthetics**:
   - Keep every color, radius, shadow and font in a single token file (CSS variables) and consume tokens everywhere; never hardcode hex values in components.
   - Prefer crisp 1px borders and one subtle shadow scale over blurry default shadows. Pair one sans-serif for body/headings with one monospace for tags, badges, metrics, and code.
5. **Data Layer & Reliability**:
   - Write declarative schema definitions with foreign keys, composite indexes on queried filters, and automated timestamp triggers.
   - Use connection pooling and prepared statements for serverless database execution.
---
## 5. STEP-BY-STEP SCAFFOLDING ROADMAP
- **Phase 1: Workspace & Root Config**: Initialize package manager, monorepo configuration (`turbo.json`, `tsconfig.base.json`, `package.json`).
- **Phase 2: Database Schema & Client**: Set up the data layer (SQLite, PostgreSQL): client, connection pool, models, and migration scripts.
- **Phase 3: Design Tokens & UI Primitives**: Build accessible `Button`, `Input`, `Card`, `Badge`, and layout wrappers inside `packages/ui`.
- **Phase 4: Core Application Routes & Handlers**: Implement primary authentication, user session handling, and application routes.
- **Phase 5: Quality Assurance & Build Verification**: Run `tsc --noEmit`, ESLint, Prettier, and smoke test suites to ensure zero compilation or runtime errors.
---
## 6. EXECUTION INSTRUCTIONS
1. Review all specifications, architectural guardrails, and stack choices above.
2. Present the full monorepo directory tree structure.
3. Systematically generate the complete, production-ready codebase according to the 5-phase roadmap above — starting with the root workspace setup, followed by the database schema, UI design system package, and full-stack application routes until the repository is fully scaffolded and ready to run.
Scaffolded something with this prompt?
Would you pick this stack for a automated health dashboard & status monitor project?

Frequently asked about Gatus

What is Gatus built with?

Gatus is a Go backend (built on the Fiber web framework) with a Vue 3 dashboard compiled by vue-cli-service and embedded directly into the Go binary. Charts use Chart.js via vue-chartjs, and styling is Tailwind CSS.

Does Gatus need a database?

Not a separate one by default. Gatus stores endpoint status history in an embedded SQLite file (via the pure-Go modernc.org/sqlite driver); a PostgreSQL backend is available for deployments that need shared or multi-replica storage.

Can I self-host Gatus?

Yes, that is the primary use case. The repository ships a multi-stage Dockerfile producing a single static binary in a scratch image, plus .examples/ with docker-compose and Kubernetes manifests for SQLite storage, PostgreSQL storage, mTLS and NixOS.

What kinds of checks and alerts does Gatus support?

The config/endpoint package supports HTTP, TCP, ICMP, DNS, gRPC, WebSocket, SSH, STARTTLS/TLS and SCTP checks defined as YAML conditions (e.g. "[STATUS] == 200"). alerting/provider implements native clients for over 30 alert destinations including Slack, PagerDuty, Discord, Teams, Twilio and AWS SES.

Is there a managed version of Gatus?

Yes. The README points to Gatus.io as a managed SaaS built by the same maintainer, separate from the open-source, self-hosted server in this repository.

One email a month: new deep dives and stack trends

New source-audited architectures, head-to-head comparisons and the monthly stack report. No spam, unsubscribe anytime.

use-this-stack.md