Skip to content

Configuration

NetPulse is configured almost entirely through environment variables. The repository ships a .env.dist that documents every supported variable with its default — copy it to .env and edit the values you care about:

bash
cp .env.dist .env

Some general and SSO settings can also be edited from the dashboard under Settings. When an administrator saves those in the UI they are persisted to the app_settings table and take precedence over the matching environment variable, which then only acts as a fallback. The tables below note where that applies.

INFO

All php/composer/console commands run inside the app Docker container. The one-off form is docker compose exec -T app <cmd>.

Core

VariableDefaultPurpose
APP_ENVdevSymfony environment (dev, prod, test).
APP_SECRETSymfony secret used for signing/CSRF. Set a unique random value.
DATABASE_URLsqlite:///%kernel.project_dir%/var/netpulse.sqliteDatabase DSN. SQLite for dev/test; a PostgreSQL DSN for production.
MESSENGER_TRANSPORT_DSNsync://Messenger transport for command/query buses.
NETPULSE_VERSIONVersion label surfaced in the UI and metrics.

MESSENGER_TRANSPORT_DSN

The default sync:// runs message handlers inline (in-process), so no worker is needed. Only switch to a real async transport (e.g. Doctrine/AMQP) if you also run a messenger:consume worker to drain it.

Metrics & observability

VariableDefaultPurpose
PROMETHEUS_METRICS_ENABLEDtrueEnables the /metrics endpoint.
PROMETHEUS_ALLOWED_IPS(empty)Empty = allow all. Set a CSV of IPs/CIDRs to restrict who may scrape /metrics.
MEASUREMENT_FRESHNESS_WINDOW3600Seconds a measurement is considered "fresh" for freshness/staleness metrics.

The docker-compose stack bundles Prometheus and Grafana services (Grafana is provisioned with a dashboard), and Prometheus scrapes /metrics out of the box. An optional VictoriaMetrics service is available under the vm compose profile.

If you'd rather push metrics to a remote store, enable Prometheus remote_write:

VariableDefaultPurpose
REMOTE_WRITE_ENABLEDfalseEnable Prometheus remote_write.
REMOTE_WRITE_URLTarget remote_write endpoint.
REMOTE_WRITE_AUTHAuthorization for the remote endpoint.
REMOTE_WRITE_EXTRA_LABELSExtra labels appended to remote-written series.

Probe agent

These variables are consumed by the agent process (app:agent:run), which polls the server and runs the Ookla Speedtest CLI.

VariableDefaultPurpose
NETPULSE_API_URLBase URL the agent calls (e.g. http://app:8080).
PROBE_IDUUID of the probe this agent represents.
PROBE_TOKENPer-probe Bearer token from app:probe:create.
OOKLA_BINARYspeedtestPath/name of the Ookla Speedtest CLI in the image.
AGENT_POLL_INTERVAL60Seconds between polls for due work.

TIP

These are read only by the agent process — the server image leaves them blank. AGENT_POLL_INTERVAL is the fallback poll cadence (how often the agent checks for work), not the test frequency. How often a connection is actually tested is set by its schedule (testsPerDay/cron). See How it works for the full flow.

Notifications

Configure these in the UI

Alert channels are managed at Settings → Notifications (saved values override the ENV defaults below, with secrets encrypted at rest). See the dedicated Notifications guide for per-channel setup and the Slack / Telegram / Discord DSN formats. The variables below are the fallbacks used until an admin saves a value.

VariableDefaultPurpose
NOTIFY_ENABLEDfalseMaster switch for alert/recovery/digest delivery.
NOTIFY_CONSECUTIVE_THRESHOLD3Consecutive bad measurements before an alert fires (edge-debounced).
NOTIFY_CHANNELSCSV of channels: email, chat, webhook.
NOTIFY_EMAIL_TORecipient address for the email channel.
MAILER_DSNnull://nullSymfony Mailer DSN (the default sends nothing).
NOTIFY_CHAT_DSNSymfony Notifier chatter DSN for the chat channel.
NOTIFY_WEBHOOK_URLTarget URL for the webhook channel.

Alert and recovery notifications fire on recorded measurements, debounced by NOTIFY_CONSECUTIVE_THRESHOLD. The periodic digest is not self-scheduled — run it from the host cron:

bash
docker compose exec -T app php bin/console app:notifications:digest --period=daily

A cron example (daily at 08:00, weekly digest Mondays at 08:05):

txt
0 8 * * *   cd /opt/netpulse && docker compose exec -T app php bin/console app:notifications:digest --period=daily
5 8 * * 1   cd /opt/netpulse && docker compose exec -T app php bin/console app:notifications:digest --period=weekly

Two-factor (TOTP)

VariableDefaultPurpose
TOTP_ENCRYPTION_KEY64 hex chars (32 bytes); encrypts stored TOTP secrets.

Generate a key:

bash
php -r "echo bin2hex(random_bytes(32));"

This is required only to actually enrol or use TOTP 2FA (Settings → Security).

WARNING

Losing or rotating TOTP_ENCRYPTION_KEY locks users out of TOTP — existing secrets can no longer be decrypted. Recovery codes remain the fallback in that case.

Single sign-on (OIDC)

VariableDefaultPurpose
OIDC_NAMEDisplay name for the SSO button.
OIDC_CLIENT_IDClient ID registered at the identity provider.
OIDC_CLIENT_SECRETClient secret (stored encrypted at rest — see below).
OIDC_AUTHORIZATION_URLProvider authorization endpoint.
OIDC_TOKEN_URLProvider token endpoint.
OIDC_USERINFO_URLProvider userinfo endpoint.
OIDC_SCOPESRequested scopes (e.g. openid profile email).
OIDC_REDIRECT_URLThe callback URL registered at the IdP.

INFO

SSO is an alternate login for an existing account, matched by verified email — it never auto-creates users. Register <app-base-url>/login/oidc/callback as the redirect URI at your IdP. The authorization/token/userinfo endpoints can be read from your provider's <issuer>/.well-known/openid-configuration document.

In-app settings & secret encryption

VariableDefaultPurpose
NETPULSE_SITE_NAMESite name (ENV fallback; overridden by Settings in app_settings).
NETPULSE_TIMEZONEDisplay timezone (ENV fallback; overridden by Settings).
SETTINGS_ENCRYPTION_KEY(falls back to TOTP_ENCRYPTION_KEY)64 hex chars; encrypts secret settings (e.g. the OIDC client secret) at rest.

NETPULSE_SITE_NAME and NETPULSE_TIMEZONE are fallbacks: once an administrator saves them in the dashboard Settings page they are written to app_settings and take precedence over the environment values.

SETTINGS_ENCRYPTION_KEY encrypts secret settings (such as the OIDC client secret) so they are not stored in plaintext. It is 64 hex chars and falls back to TOTP_ENCRYPTION_KEY if unset. With no key set at all, secret settings cannot be saved.

TIP

Reuse the same generation command for either key:

bash
php -r "echo bin2hex(random_bytes(32));"

See How it works for scheduling and the agent loop, and Getting started for first-run setup.

NetPulse is built and maintained by mrhdolek. Released under the MIT License.