Configuration
Environment variables for the backend (the server and workers). The dashboard is configured separately at build time — see Dashboard.
Copy .env.example from the repo root as your starting point and fill in the values for your environment. Every pug command loads .env if present, then falls back to the process environment — so in production you can skip the file and inject these variables directly.
cp .env.example .envThe sections below document every variable, grouped by concern. Required variables must be set; the server will not start correctly without them.
Stores
The backend requires four backing services. See Requirements for compatible versions and ports.
| Variable | Required? | Default / Example | Description |
|---|---|---|---|
DATABASE_URL | Yes | postgres://postgres:postgres@localhost:5433/pug?sslmode=disable | Postgres connection string (DSN). Standard postgres:// URL including database name and sslmode. |
CLICKHOUSE_URL | Yes | clickhouse://default:@localhost:9000/pug | ClickHouse connection string using the native protocol (clickhouse://). |
NATS_URL | Yes | nats://localhost:4222 | NATS server URL. JetStream must be enabled on the server (--jetstream). |
REDIS_URL | Yes | redis://localhost:6380 | Dragonfly (Redis-compatible) connection URL. Dev default maps host port 6380 to container port 6379. |
Server
| Variable | Required? | Default / Example | Description |
|---|---|---|---|
PUG_SERVER_PORT | No | 3000 | Port the Connect RPC API server listens on. |
PUG_JWT_SECRET_KEY | Yes | (generate with openssl rand -hex 32) | Secret used to sign and verify dashboard JWTs. Use a long random string and never reuse it between environments. |
PUG_CORS_ORIGINS | No | http://localhost:5173 | Comma-separated list of allowed CORS origins (e.g. https://app.example.com). Must include your dashboard’s origin. When set to *, credentials are not sent per the CORS spec — set specific origins to enable credentialed requests. |
PUG_DASHBOARD_BASE_URL | No | http://localhost:5173 | Base URL of the dashboard, used when constructing links in outgoing emails (magic-link, invites, notifications). |
PUG_OAUTH_GOOGLE_CLIENT_ID | No | (empty) | Google OAuth client ID for “Sign in with Google”. Leave empty to disable. Must match the dashboard’s VITE_GOOGLE_CLIENT_ID. |
Workers
| Variable | Required? | Default / Example | Description |
|---|---|---|---|
PUG_WORKER_HEALTH_ADDR | No | :8090 | Address each worker process serves its /healthz (liveness) and /readyz (readiness) probes on. Set to off to disable. When running several worker binaries on one host, give each a distinct port. pug dev forces this off. See Health checks. |
Pug sends transactional email (magic links, invites, notifications). Configure a provider and the sender identity before users can sign in.
| Variable | Required? | Default / Example | Description |
|---|---|---|---|
PUG_EMAIL_FROM | Yes | [email protected] | From address for all outgoing email. |
PUG_EMAIL_REPLY_TO | No | (empty) | Reply-To address. Leave empty to omit the header. |
PUG_EMAIL_LOGO_URL | No | https://pug.sh/logo.png | URL of a logo image shown in the email header. When empty, a wordmark-only header is rendered. |
PUG_EMAIL_PROVIDER | Yes | resend | Email delivery provider. Supported values: resend or ses. |
PUG_RESEND_API_KEY | Conditional | — | Resend API key. Required when PUG_EMAIL_PROVIDER=resend. |
PUG_SES_REGION | Conditional | us-east-1 | AWS region for SES. Optional when PUG_EMAIL_PROVIDER=ses if AWS_REGION is already set. |
AWS_REGION | Conditional | us-east-1 | Standard AWS SDK region. Required for SES. |
AWS_ACCESS_KEY_ID | Conditional | — | Standard AWS SDK access key. Required for SES. |
AWS_SECRET_ACCESS_KEY | Conditional | — | Standard AWS SDK secret key. Required for SES. |
AWS_SESSION_TOKEN | No | (empty) | AWS session token for temporary (STS) credentials. Optional. |
PUG_EMAIL_PROVIDER_SECRET_KEY | No | (empty) | Encryption key for per-tenant email provider configuration stored at rest. Generate with openssl rand -base64 32. Leave empty to disable per-tenant providers — the operator-level provider handles all sends. |
You can preview any transactional email without sending it:
pug email preview magic_linkrenders it to HTML on stdout. See the CLI reference.
Telemetry
The backend emits OpenTelemetry traces, metrics, and logs. Export mode is auto-detected once at process start: if an OTLP endpoint variable is set, Pug exports to that collector; otherwise it logs to stdout as plain text (no collector needed).
| Variable | Required? | Default / Example | Description |
|---|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT | No | (empty) | OTLP collector endpoint, e.g. http://localhost:4317. When set, Pug exports traces/metrics/logs there. When unset, it logs to stdout. |
OTEL_SERVICE_NAME | No | pug | Service name reported in OpenTelemetry spans. Only used when exporting via OTLP. |
The standard OTEL SDK environment variables (OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_PROTOCOL, …) are also honored. For a ready-made local collector, see make clickstack.
Demo dataset (optional)
Off by default — these power the public “Pug & Pals” demo and are irrelevant to a normal self-host. PUG_DEMO_ENABLED is the single switch: it gates both the demo worker and the credential-less demo sign-in RPC on the server. Leave it false everywhere unless you’re intentionally hosting a public demo.
| Variable | Default | Description |
|---|---|---|
PUG_DEMO_ENABLED | false | Master switch. When true, the demo worker streams synthetic traffic and pug server exposes a read-only demo sign-in. Set on every pod (server + worker) of a demo deployment. |
PUG_DEMO_PEAK_SESSIONS_PER_MIN | 6 | Peak sessions/min at the busiest hour (≈30–50k events/day at 6); off-peak follows a diurnal curve. |
PUG_DEMO_SEED_COUNT | 500000 | One-time backfill volume when the demo project is empty. |
PUG_DEMO_SEED_BATCH | 10000 | ClickHouse insert batch size for the backfill. |
Minimal .env example
A minimal configuration for local development. Production deployments need real secrets and a working email provider.
# Stores
DATABASE_URL=postgres://postgres:postgres@localhost:5433/pug?sslmode=disable
CLICKHOUSE_URL=clickhouse://default:@localhost:9000/pug
NATS_URL=nats://localhost:4222
REDIS_URL=redis://localhost:6380
# Server
PUG_SERVER_PORT=3000
PUG_JWT_SECRET_KEY=change_me_use_openssl_rand_hex_32
PUG_CORS_ORIGINS=http://localhost:5173
PUG_DASHBOARD_BASE_URL=http://localhost:5173
# Email (Resend)
[email protected]
PUG_EMAIL_PROVIDER=resend
PUG_RESEND_API_KEY=re_your_resend_api_keyFurther reading
- Requirements — backing services, ports, and sizing
- Deployment — production build, run, and hardening
- Dashboard — the separate
VITE_*build-time config