The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the SolidPing listing page.
Distributed, self-hostable uptime monitoring. 40 check types, multi-region workers, private agents, status pages, incidents and on-call escalation — in a single Go binary.
docker run to the first resulthttps://github.com/user-attachments/assets/471694b0-b136-4764-86c1-5f85615c45f4
The whole thing, start to finish: docker run, the first sign-in and its forced password change, an HTTP check created against https://solidping.io/api/mgmt/health, and its first response times plotted from two regions. Regenerated from the live dashboard with make showcase — nothing here is a mock-up. The same cut plays on the Tour page if the player above does not load.
| Checks list | New-check form | Check detail |
|---|---|---|
![]() | ![]() | ![]() |
| Hosted | www.solidping.io — sign up, no card needed |
| Live status page | status.solidping.io — a real SolidPing instance watching the production one, from another provider in another country |
| Documentation | docs.solidping.io |
| Self-host | docker run -p 4000:4000 --hostname solidping ghcr.io/fclairamb/solidping — SQLite by default, no other service needed. First login is admin@solidping.io / solidpass, and you must change it (see Default Credentials). Prefer a bare binary? Every release also publishes one for Linux, macOS and Windows — see the installation guides. |
SolidPing is a multi-tenant monitoring system that enables organizations to monitor their infrastructure through distributed workers executing health checks. It's designed for low resource consumption and easy self-hosting.
/metrics, Sentry integration, OpenTelemetryadmin@solidping.iosolidpassdefaultBoth halves of that pair are published here, so the first login on a fresh
database must set a new password before the account can do anything else.
The dashboard takes you straight to the form; over the API the login succeeds
and every endpoint except POST /api/v1/auth/change-password,
GET /api/v1/auth/me and POST /api/v1/auth/logout answers 403 with code
PASSWORD_CHANGE_REQUIRED until you rotate it.
| Protocol | Description |
|---|---|
| HTTP/HTTPS | Status codes, body matching, JSON assertions, Basic Auth |
| TCP | Port connectivity |
| UDP | Port reachability |
| ICMP | Ping |
| DNS | Record resolution |
| DNSBL | DNS blocklist (RBL) membership |
| NTP | Time server reachability and clock drift |
| WebSocket | Connection check |
| SIP | VoIP SIP server (OPTIONS ping) |
| Protocol | Description |
|---|---|
| SSL/TLS | Certificate validity and expiration |
| Domain | Domain name expiration (WHOIS) |
| Protocol | Description |
|---|---|
| SMTP | Server connectivity, STARTTLS, AUTH |
| POP3 | Server availability |
| IMAP | Server availability |
| Email (JMAP) | Passive inbox monitoring — receive a known message via JMAP and assert delivery |
| Protocol | Description |
|---|---|
| PostgreSQL | Connection + query execution |
| MySQL/MariaDB | Connection + query execution |
| MSSQL | Connection + query execution |
| Oracle | Connection + query execution |
| ClickHouse | Connection + query execution |
| MongoDB | Ping command |
| Redis | PING command |
| Protocol | Description |
|---|---|
| SSH | Server availability |
| RDP | Pre-auth RDP negotiation handshake (no credentials) |
| FTP | Server availability |
| SFTP | Server availability |
| Protocol | Description |
|---|---|
| Kafka | Broker connectivity |
| RabbitMQ | Broker connectivity |
| MQTT | Broker connectivity |
| Type | Description |
|---|---|
| Docker | Container health |
| Kubernetes | Cluster / API server health |
| SNMP | Device monitoring |
| gRPC | Service health |
| A2S | Source / Steam game server query (Valve A2S) |
| Minecraft | Minecraft server query |
| Prometheus | Scrape a Prometheus endpoint and assert on a metric |
| Type | Description |
|---|---|
| Heartbeat | Passive monitoring via incoming pings |
| JavaScript | Sandboxed custom monitoring logic |
| Browser | Headless Chrome (Rod) — JS, CSS, full render |
| Freebox Line | Freebox xDSL/fiber line quality (via connected Freebox) |
Everything is configured with SP_-prefixed environment variables. Precedence:
environment variables > config.local.yml > config.yml > defaults.
You only need the database settings to get started — the defaults cover the rest.
Nothing to configure. The image already stores the SQLite database and every
uploaded blob (org logos, status-page assets, screenshots) under /data, so a
single mounted named volume is enough:
--hostname solidping is not optional: the worker name is derived from the
hostname and must match ^[a-z][a-z0-9-]{2,20}$. Docker's default hostname is
the random container ID, which starts with a digit most of the time, and the
server then refuses to start. Pass --hostname, or set SP_NODE_NAME instead.
If you use a bind mount instead of a named volume (-v ./solidping-data:/data),
the host directory keeps its own ownership, which is usually not writable by
the image's nonroot user (uid/gid 65532). Either chown 65532:65532 the
host directory first, or run with -u "$(id -u):$(id -g)". A named volume, as
used above, doesn't have this problem — Docker seeds it from the image with
the right ownership.
Schema migrations run on first boot, so point it at an empty database and let it create its own tables:
sslmode=disable is right for a database on the same private network, and is
what a stock postgres container accepts — it serves no TLS, so sslmode=require
fails against one with SSL is not enabled on the server. For a managed or
remote database, use sslmode=require (or verify-full) instead.
| Variable | Default | Description |
|---|---|---|
SP_DB_TYPE | sqlite | sqlite or postgres |
SP_DB_URL | — | PostgreSQL connection string (required when SP_DB_TYPE=postgres) |
SP_DB_DIR | /data in the image, . for the bare binary | Where the SQLite file lives — set it to a volume |
SP_SERVER_LISTEN | :4000 | Listen address |
SP_BASE_URL | http://localhost:4000 | Public URL, used in links and notifications |
SP_NODE_NAME | the hostname | Worker name, ^[a-z][a-z0-9-]{2,20}$. Set it, or pass --hostname — the server will not start if the hostname does not match |
SP_LOG_LEVEL | info | debug, info, warn, error |
That is the whole getting-started surface. Everything else — authentication and SSO, email and the other notification channels, custom domains and TLS, multi-region workers, data retention, storage — is optional and documented at docs.solidping.io:
| Configuration overview | every variable, grouped by area |
| Database | connection strings, SSL modes, pooling, backups |
| Authentication | OAuth providers, OIDC, SAML, LDAP, 2FA |
| Notifications | Slack, Discord, email, webhooks and the rest |
web/dash0): Admin UI (React + TanStack Router + shadcn/ui)web/status0): Public-facing status dashboardBug reports and pull requests are welcome — see CONTRIBUTING.md
for local setup and PR conventions. Found a security issue? See
SECURITY.md rather than opening a public issue.
AGPL-3.0 - See LICENSE.