Getting Started
Prerequisites
| Requirement | Notes |
|---|---|
| PostgreSQL 13+ | History/state store (13+ required — the schema uses gen_random_uuid() and declarative partitioning). The Docker demo bundles it. |
| Prometheus | With node_exporter for CPU/memory/disk metrics |
| Telegram bot, Slack (incoming webhook or bot token), SMTP server, or PagerDuty | @BotFather / Slack incoming webhook or a chat:write bot token for threads in Slack (Telegram threads with no extra credential) / any SMTP relay / a PagerDuty Events API v2 key (paging only — alert groups and failing health checks) |
| LLM API key (optional) | OpenAI or Anthropic; llm.provider: none runs the built-in deterministic engine with no key |
| Docker (optional) | For the quickest setup |
Try the demo first
Before setting up with real credentials, see what InfraSigns output looks like:
This runs a full digest cycle with mock Prometheus data and prints the result to stdout.
Quick start with Docker
1. Clone and configure
git clone https://github.com/infrasigns/infrasigns
cd infrasigns
cp .env.example .env # fill in LLM_API_KEY and notification tokens;
# DATABASE_DSN already points at the bundled Postgres
2. Edit config/config.yaml for non-secret settings (sources, schedule, etc.) —
Compose mounts this file into the container. The default sources.url points at
the bundled Prometheus.
sources:
- name: production
url: http://prometheus:9090 # bundled Prometheus; or your own URL
# No self-hosted Prometheus? Add a `type: cloudwatch` (AWS),
# `type: digitalocean`, `type: hetzner`, `type: healthcheck` (probe any
# HTTP URL), or `type: loki` (LogQL metric queries) source instead —
# see docs/configuration.md#sources.
llm:
provider: openai
api_key: sk-...
model: gpt-4o-mini
notify:
telegram:
token: "123456:ABC-..."
chat_id: "-100123456789"
reports:
digest:
schedule: "0 8 * * *"
3. Start
The stack includes Postgres, Prometheus, and node_exporter. Point your existing
services at the bundled Prometheus or configure sources.url to point at your own.
Manual setup
Copy the config and replace the compose-specific values: sources.url (the
default points at the compose Prometheus) and database.dsn (replace
'${DATABASE_DSN}' with a literal DSN, or export that variable). Then run:
go build -o infrasigns ./cmd/infrasigns
cp config/config.yaml config/local.yaml # edit: sources.url, database.dsn
./infrasigns migrate up --config config/local.yaml # apply DB migrations
./infrasigns serve --config config/local.yaml # start the daemon
Requires Go 1.26+.
Getting your Telegram chat ID
- Start a chat with your bot or add it to a group
- Send any message
- Open
https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates - Find
"chat":{"id":...}in the response — that's yourchat_id
For groups and channels, the ID is negative (e.g. -100123456789).
Verifying the setup
Trigger a digest immediately without waiting for the cron schedule:
# Docker
docker compose exec infrasigns /infrasigns digest trigger --wait
# Manual
API_TOKEN=<your api.token> ./infrasigns digest trigger --wait
The trigger endpoint requires the bearer token from api.token (see
API authentication); the CLI reads it
from $API_TOKEN or --token. Inside the compose container the variable is
already set from .env.
--wait blocks until the cycle completes and reports the outcome: done when a
digest was delivered, or skipped_no_data when the source produced no metrics
and no alerts (nothing to summarize, so no digest is generated). Omit it for a
fire-and-forget trigger.
What's next
- Configuration reference — all available options
- LLM providers — OpenAI vs Anthropic, model recommendations
- Notifications — Telegram, Slack, email, and PagerDuty setup in detail
- Kubernetes — Helm chart install, secret management, ServiceMonitor