Analytics cookies only (Google Analytics, PostHog). No ad networks, no cross-site tracking. See our privacy policy.
An on-call scheduling, alerting and escalation tool: define services, on-call schedules with rotations and escalation policies, accept alerts from monitoring through integration keys and notify the person on call, with most settings in an admin page of the web UI. Apache-2.0 Go and TypeScript; a single binary or container that needs only a PostgreSQL database.
Runs on a VPS from $6/mo (Kamatera 2GB, 2 GB RAM) · prices checked Sep 2026
Pick GoAlert when the question is not whether something is down but who gets woken up for it. Your monitoring sends an alert to a GoAlert service, an escalation policy decides who to notify and how long to wait before trying the next person, and on-call schedules and rotations say who that is this week; notification providers are configured in the admin page. That is the job hosted tools like PagerDuty and Opsgenie do. It pairs with the catalog's Gatus, Kener and Zabbix, which detect problems and then need something to page a human. It is Apache-2.0 Go with a TypeScript front end and the only hard requirement is PostgreSQL. Our snippet follows the Getting Started guide with PostgreSQL 17, the image pinned to a release tag, and the admin user created for you. We did not find an upstream RAM minimum, so our 512 MB floor is an estimate.
Paid link — we earn a commission if you shop through it.
Run these commands on your server:
# GoAlert — on-call schedules, escalation policies and alert notifications — based on the project's Getting Started guide, pinned to v0.35.0
echo "DB_PASSWORD=$(openssl rand -hex 16)" > .env
echo "ENCRYPTION_KEY=$(openssl rand -hex 32)" >> .env
echo "ADMIN_PASSWORD=$(openssl rand -hex 12)" >> .env
cat > docker-compose.yml <<'EOF'
services:
goalert:
image: goalert/goalert:v0.35.0
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
GOALERT_DB_URL: postgres://goalert:${DB_PASSWORD}@db:5432/goalert?sslmode=disable
GOALERT_DATA_ENCRYPTION_KEY: ${ENCRYPTION_KEY}
GOALERT_PUBLIC_URL: http://SERVER_IP:8081
ports:
- 8081:8081
db:
image: postgres:17
restart: unless-stopped
environment:
POSTGRES_USER: goalert
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: goalert
volumes:
- db_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U goalert -d goalert"]
interval: 5s
timeout: 5s
retries: 10
volumes:
db_data:
EOF
docker compose up -d
timeout 120 bash -c 'until curl -fsS http://localhost:8081/health >/dev/null; do sleep 5; done'
. ./.env
docker compose exec -T goalert goalert add-user --db-url "postgres://goalert:${DB_PASSWORD}@db:5432/goalert?sslmode=disable" --admin --user admin --email admin@example.com --pass "$ADMIN_PASSWORD"
# → http://SERVER_IP:8081 — sign in as admin with ADMIN_PASSWORD from .envGoAlert's Getting Started guide flags these before you rely on it for paging: