Skip to main content

Configuration

SolidPing is configured primarily through environment variables. All environment variables use the SP_ prefix. Configuration uses hierarchical precedence: Environment variables > config.local.yml > config.yml > defaults.

Configuration Methods

  1. Environment Variables - Recommended for Docker and production
  2. Configuration File - config.yml in the working directory (with config.local.yml for local overrides)
  3. Command Line - Some options can be passed via CLI flags

Quick Reference

Essential Variables

VariableDefaultDescription
SP_DB_TYPEsqliteDatabase type: postgres, sqlite, sqlite-memory, postgres-embedded
SP_DB_URL-PostgreSQL connection string
SP_DB_DIR.SQLite database directory
SP_DB_RESETfalseReset database on startup
SP_SERVER_LISTEN:4000Server address and port
SP_BASE_URLhttp://localhost:4000Public URL where SolidPing is accessible

Server Configuration

VariableDefaultDescription
SP_SERVER_LISTEN:4000Listen address (e.g., :4000, 0.0.0.0:8080)
SP_SERVER_JOB_WORKER_NB2Number of job runner goroutines
SP_SERVER_CHECK_WORKER_NB3Number of check runner goroutines
SP_SHUTDOWN_TIMEOUT30sGraceful shutdown timeout
SP_EXIT_WITH_PARENTfalseShut down when the process that started SolidPing disappears, instead of being reparented to PID 1. For servers spawned by a test harness or a wrapper script; leave off under a normal supervisor
PORT-Alternative to SP_SERVER_LISTEN (for PaaS compatibility)

Custom Domains & TLS

VariableDefaultDescription
SP_CUSTOM_DOMAIN_CNAME_TARGEThost of base_urlHostname customers point their status-page CNAME at
SP_CUSTOM_DOMAIN_CNAME_MODEsharedshared (plain target) or token (per-page <token>.cname.<target>)
SP_ACME_ENABLEDfalseTerminate TLS in-server with Let's Encrypt certificates obtained on demand
SP_ACME_EMAIL-ACME account contact — required when SP_ACME_ENABLED=true
SP_ACME_CA_URLLet's Encrypt prodACME directory URL (point at LE staging while testing)
SP_ACME_LISTEN_HTTP:80HTTP-01 challenge listener; redirects everything else to HTTPS
SP_ACME_LISTEN_HTTPS:443TLS listener, feeding the normal routing
SP_ACME_FALLBACK_UPSTREAM_HTTPS-host:port of a second instance to hand unknown-SNI TLS connections to
SP_ACME_FALLBACK_UPSTREAM_HTTP-Same next hop for plaintext :80 (HTTP-01 for the downstream's domains)
SP_ACME_FALLBACK_UPSTREAM_PROXY_PROTOCOLtrueSend a PROXY v2 header with the original client to that next hop
SP_ACME_PROXY_PROTOCOLfalseRead a PROXY protocol (v1/v2) preamble on both ACME listeners — needed behind a TLS passthrough, which has no X-Forwarded-For
SP_ACME_PROXY_PROTOCOL_TRUSTED_CIDRS-Comma-separated CIDRs/IPs whose PROXY header is honored; headers from anywhere else are ignored. Required when SP_ACME_PROXY_PROTOCOL=true (empty fails startup)

Enabling SP_ACME_ENABLED makes the process bind two extra ports and removes the need for a TLS-terminating reverse proxy. Leave it off to keep TLS at your own edge. See Custom Domains for the full setup.

Distributed Workers

VariableDefaultDescription
SP_NODE_ROLEallNode role: all, api, jobs, checks — or a comma-separated combination (api,jobs)
SP_NODE_REGION-Worker region (required when the role includes checks)
SP_NODE_NAMEhostnameWorker identity (workers.slug and workers.name) — overrides the OS hostname
SP_REGIONS-Region display definitions, as a JSON list of {slug, emoji, name}

Use SP_NODE_ROLE to run SolidPing in a distributed configuration:

  • all - Single node running everything (default)
  • api - Only serve the API and dashboard
  • jobs - Only run background jobs (scheduling, cleanup)
  • checks - Only execute health checks (worker mode)

api, jobs and checks can also be combined in one value, as a comma-separated list:

SP_NODE_ROLE=api,jobs

That node serves the API/dashboard and processes background jobs, but runs no check executor — the checks are left to separate SP_NODE_ROLE=checks nodes. This is what you want when the check workers need a network setup the public-facing node should not have: on a single-stack (IPv4-only) Kubernetes cluster, check workers need hostNetwork: true to reach IPv6-only targets, and putting the pod that serves your dashboard on the host network namespace is a much more sensitive change than doing it for a checks-only worker. Run the main pod as api,jobs and add a checks-only hostNetwork Deployment per region.

Rules:

  • all and agent are whole-node modes and cannot be combined with anything — all already means api + jobs + checks.
  • A role listed twice, an unknown role, or an empty entry (api,) aborts startup with a message naming the offending value. A typo never silently disables a subsystem.
  • SP_NODE_REGION is required as soon as checks is in the list.
  • Every single-value spelling keeps its exact historic behavior, so existing deployments need no change.

SP_NODE_NAME pins the identity a node registers under. By default the slug is the OS hostname, lowercased and cut to 15 characters, and it must match ^[a-z][a-z0-9-]{2,20}$. Registration is an upsert on that slug, so set SP_NODE_NAME whenever the hostname is not stable, not unique within its first 15 characters, or not slug-legal:

SP_NODE_NAME=solidping-eu2

Two cases where it is required rather than nice to have:

  • Kubernetes with hostNetwork: true. The pod shares the host UTS namespace, so spec.hostname is ignored and the container sees the node name — typically dotted (eu2.example.com), which the slug pattern rejects. This is the setup you need to give check workers the node's IPv6 stack on a single-stack (IPv4-only) cluster, so an IPv6-only target can be checked at all.
  • Pod names that collide in the first 15 characters. Deployment-generated names such as solidping-checks-eu2-… and solidping-checks-us1-… both cut down to solidping-check, and the two workers then silently share one workers row. A truncated hostname logs a WARN naming the resulting slug.

An invalid effective slug (override or hostname-derived) aborts startup with a message naming the offending value, rather than failing later against the database constraint.

SP_REGIONS names your regions declaratively: the dashboard renders {emoji} {name} wherever a region appears (check form, results, worker load), falling back to the raw slug for undefined regions. Set it on the main server; it seeds the regions system parameter at startup:

SP_REGIONS='[{"slug": "default", "emoji": "🇪🇺", "name": "EU1 (default)"}, {"slug": "us-1", "emoji": "🇺🇸", "name": "US1"}]'

When unset, the stored parameter (or the built-in default region) is used, so edits made through the API are preserved across restarts.

Check Types

VariableDefaultDescription
SP_CHECKERS_BROWSER_CDP_URL-Remote headless Chrome (CDP) endpoint for browser checks, e.g. ws://browser:9222. Required in containers — the image ships no browser
SP_CHECKERS_BROWSER_CHROME_PATH-Local Chrome/Chromium binary used when no CDP URL is set. Empty means "probe the usual names"; nothing is ever downloaded

Logging

VariableDefaultDescription
SP_LOG_LEVELinfoLog level: debug, info, warn, error

Authentication

VariableDefaultDescription
SP_AUTH_JWT_SECRETauto-generatedJWT signing secret
SP_AUTH_REGISTRATION_EMAIL_PATTERN-Restrict registration by email regex
SP_AUTH_PASSWORD_ALGORITHMargon2idPassword hashing algorithm (argon2id or bcrypt) — see Password Hashing for cost parameters

OAuth Providers

Set both _CLIENT_ID and _CLIENT_SECRET to enable each provider:

ProviderVariables
GoogleSP_GOOGLE_CLIENT_ID, SP_GOOGLE_CLIENT_SECRET
GitHubSP_GITHUB_CLIENT_ID, SP_GITHUB_CLIENT_SECRET
GitLabSP_GITLAB_CLIENT_ID, SP_GITLAB_CLIENT_SECRET
MicrosoftSP_MICROSOFT_CLIENT_ID, SP_MICROSOFT_CLIENT_SECRET, SP_MICROSOFT_TENANT_ID (default common)
SlackSP_SLACK_CLIENT_ID, SP_SLACK_CLIENT_SECRET
DiscordSP_DISCORD_CLIENT_ID, SP_DISCORD_CLIENT_SECRET

Users can also enable TOTP two-factor authentication on their accounts. See Authentication for details.

Run Mode

VariableDefaultDescription
SP_RUN_MODE-Runtime mode: test (seed test data), demo

Encryption

VariableDefaultDescription
SP_ENCRYPTION_MASTER_KEY-Base64-encoded 32-byte key for credential encryption at rest
SP_ENCRYPTION_MASTER_KEY_FILE-Path to a file holding the base64 master key
SP_ENCRYPTION_AUTO_MIGRATEtrueEncrypt existing plaintext credentials on startup

See Security & Encryption for the full guide.

Product Analytics

Analytics is off by default — with no project API key set, the server sends nothing and the dashboard loads no analytics code whatsoever.

VariableDefaultDescription
SP_POSTHOG_PROJECT_API_KEY-Public phc_… PostHog browser key. Empty = analytics entirely off
SP_POSTHOG_HOSThttps://eu.i.posthog.comPostHog ingestion endpoint
SP_POSTHOG_PERSONAL_API_KEY-Optional server-side key (stored as a secret, never sent to the browser)
SP_POSTHOG_ENABLEDtrueKill switch — never enables anything on its own

See Product Analytics for exactly what is and is not sent.

Observability

VariableDefaultDescription
SP_PROMETHEUS_ENABLEDtrueEnable the Prometheus /metrics endpoint
SP_PROMETHEUS_PATH/metricsMetrics endpoint path
SP_SENTRY_DSN-Sentry DSN for error tracking
SP_OTEL_ENABLEDfalseEnable OpenTelemetry export
SP_OTEL_ENDPOINT-OTLP collector endpoint

See Observability for Sentry and OpenTelemetry details.

Development

VariableDescription
SP_REDIRECTSDev proxy redirects (format: /path:host:port/target,...)

Example Configuration

Environment Variables

# Database (PostgreSQL)
SP_DB_TYPE=postgres
SP_DB_URL=postgresql://solidping:password@localhost:5432/solidping?sslmode=disable

# Server
SP_BASE_URL=https://monitoring.example.com
SP_SERVER_LISTEN=:4000

# Workers
SP_SERVER_JOB_WORKER_NB=4
SP_SERVER_CHECK_WORKER_NB=8

# Authentication
SP_AUTH_JWT_SECRET=your-secure-random-secret
SP_GOOGLE_CLIENT_ID=your-google-client-id
SP_GOOGLE_CLIENT_SECRET=your-google-client-secret

# Logging
SP_LOG_LEVEL=info

Configuration File (config.yml)

db:
type: postgres
url: postgresql://solidping:password@localhost:5432/solidping?sslmode=disable

base_url: https://monitoring.example.com

server:
listen: ":4000"
job_worker_nb: 4
check_worker_nb: 8
shutdown_timeout: 30s

auth:
jwt_secret: your-secure-random-secret

email:
enabled: true
host: smtp.example.com
port: 587
username: noreply@example.com
password: smtp-password
from: noreply@example.com
from_name: SolidPing

slack:
app_id: your-slack-app-id
client_id: your-slack-client-id
client_secret: your-slack-client-secret
signing_secret: your-slack-signing-secret

CLI Configuration

The SolidPing CLI client (sp) uses its own configuration:

VariableDefaultDescription
SOLIDPING_CONFIG~/.config/solidping/settings.jsonCLI config file path
SOLIDPING_URL-Server URL override
SOLIDPING_ORG-Organization override
SOLIDPING_VERBOSEfalseVerbose CLI logging

Sections

Security Recommendations

Production Security

Always change these in production:

  • Set SP_AUTH_JWT_SECRET to a strong random value
  • Database passwords - Use strong, unique passwords
  • Set SP_BASE_URL to your public URL
  • Email credentials - Store securely, never commit to version control