Docker
Quick start
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
# edit config/config.yaml for non-secret settings (sources, schedule, etc.) —
# compose mounts this file; the defaults point at the bundled Prometheus
docker compose up -d
The bundled docker-compose.yml starts four services:
| Service | Image | Port |
|---|---|---|
| infrasigns | built from Dockerfile |
— |
| postgres | postgres:17-alpine |
— (compose network only) |
| prometheus | prom/prometheus:v3.4.0 |
9090 |
| node-exporter | prom/node-exporter:v1.9.1 |
9100 |
Postgres stores its data in the named volume postgres_data and uses fixed
dev-only credentials matching the default DATABASE_DSN in .env.example.
Its port is not published to the host; add a ports: mapping if you need
psql access. For production, point DATABASE_DSN at your own database.
Using your own Prometheus
If you already have Prometheus running, make a config copy, point it at your instance, and skip the bundled one:
# config/local.yaml
sources:
- name: production
url: http://your-prometheus:9090
# Or pull from AWS CloudWatch (type: cloudwatch, region, IAM role),
# DigitalOcean (type: digitalocean, token), or Hetzner Cloud (type: hetzner,
# token); probe any HTTP URL (type: healthcheck, endpoints); or run LogQL
# metric queries against Loki (type: loki, url) —
# see docs/configuration.md#sources.
Then start only InfraSigns (a standalone container still needs a reachable Postgres — pass its DSN):
docker run -v $(pwd)/config/local.yaml:/etc/infrasigns/config.yaml \
-e DATABASE_DSN=postgres://user:pass@your-db:5432/infrasigns?sslmode=disable \
ghcr.io/infrasigns/infrasigns:latest serve --config /etc/infrasigns/config.yaml
(Passing any arguments overrides the image's default command entirely, so
--config must be repeated alongside serve.)
Config volume
The container reads config from /etc/infrasigns/config.yaml. The bundled
compose mounts ./config/config.yaml; to use a different file, override the
mount:
# docker-compose.yml override
services:
infrasigns:
volumes:
- ./config/local.yaml:/etc/infrasigns/config.yaml:ro
Building locally
The image uses a multi-stage build:
- Stage 1 (
golang:1.26-alpine) — compiles the binary with-ldflags="-s -w" -trimpath - Stage 2 (
gcr.io/distroless/static-debian12) — minimal runtime, no shell