Skip to Content
DocsSelf-HostingCLI reference

CLI reference

Everything Pug’s backend does at runtime is a sub-command of a single binary, pug. The server, every worker, the database migrations, seeding, and email tooling all live in it — there’s nothing else to install. This page is the complete command tree.

go run ./cmd/pug <command> # from a source checkout ./bin/pug <command> # after `make build`

Every command loads .env from the working directory if present, then falls back to the process environment (see Configuration).

Command tree

pugthe unified binary
serverAPI server — Connect RPC on :3000
dev · startserver + ALL workers in one process
workerrun a single worker process
eventsconsume JetStream → write to ClickHouse
emailtransactional email
complianceGDPR/DPDP erasure, export, retention
demorolling demo traffic — gated by PUG_DEMO_ENABLED
profile
identify
alias
upsert
postgres migrate-d up|down -n N
nats migrateinit JetStream streams + consumers
clickhouse migrate-d up|down -n N
seed-c count -b batch --no-reset
email previewmagic_link|invite|provider_test [--text --out]

The same binary runs three ways — see Overview → Processes: everything-in-one (pug dev), one process per sub-command (production), or single-purpose standalone binaries / images (pug-worker-events, …) that each map to one of these commands.

server

pug server

Starts the Connect RPC API server on :3000 (override with PUG_SERVER_PORT). Handles both SDK ingestion and dashboard/API reads, and serves /healthz and /readyz probes. On ingestion it enriches events (geo, user-agent, bot detection) from the request headers before publishing them to NATS — so enrichment happens here, not in the events worker. This is the only process that listens for public traffic.

dev

pug dev # `pug start` is an alias

Runs the API server and every worker together in one process — the fastest way to get a complete, working stack up. On boot it prints the server URL, the reachable infrastructure, and the active worker list; Ctrl+C stops everything cleanly.

It starts the server plus the events, compliance, and three profile workers unconditionally; the email worker starts only if email is configured, and the demo worker only if PUG_DEMO_ENABLED=true. Worker health endpoints are disabled here (probing is for orchestrated deployments).

pug dev is built for local development, but it’s also a legitimate way to run a small single-node instance. The trade-off versus separate processes is that you can’t scale or restart components independently — for production at any real volume, run one process per role instead (Deployment).

worker …

Each worker is a standalone NATS JetStream consumer. Run one per command; scale the events worker with multiple replicas for high ingest.

CommandConsumes / does
pug worker eventsConsumes ingested events from JetStream and writes them to ClickHouse. The one to scale horizontally.
pug worker emailSends transactional email (magic links, invites, notifications).
pug worker complianceGDPR/DPDP data-subject erasure, export, and retention.
pug worker profile identifyApplies identify calls to profiles.
pug worker profile aliasMerges identities via alias.
pug worker profile upsertWrites profile property updates.
pug worker demoGenerates rolling demo traffic. Idles unless PUG_DEMO_ENABLED=true — a normal self-host does not run it.

Each worker serves /healthz + /readyz on PUG_WORKER_HEALTH_ADDR (default :8090; off to disable) — see Health checks.

Migrations

Run once before the first boot and again on every upgrade; all are idempotent.

CommandWhat it doesFlags
pug postgres migrateApplies Postgres schema migrations.--direction/-d up|down (default up), --num/-n N (steps; 0 = all)
pug nats migrateCreates the JetStream streams and consumers.
pug clickhouse migrateApplies ClickHouse schema migrations.--direction/-d up|down (default up), --num/-n N
pug postgres migrate pug nats migrate pug clickhouse migrate pug postgres migrate --direction down --num 1 # roll back one Postgres migration

Connection details come from DATABASE_URL, NATS_URL, and CLICKHOUSE_URL.

seed

pug seed # ~500k demo events by default pug seed --count 10000 # keep it light on a laptop

Seeds the demo project with synthetic data so you have something to query immediately. It resets Postgres and ClickHouse, then runs the demo flow: ensures the demo account, backfills events, seeds profiles only for the users those events belong to, and copies them into ClickHouse. (This is the one-shot version of what the demo worker does continuously.)

FlagDefaultDescription
--count / -c500000Total number of events to generate.
--batch / -b10000Events per ClickHouse insert batch.
--no-resetoffSkip the migrate down/up reset; truncate the demo tables and re-seed instead.

Run migrations first (or let seed reset the stores). Not for production — it targets the demo project specifically.

email preview

pug email preview magic_link # render to HTML on stdout pug email preview invite --text # render the plaintext twin pug email preview provider_test --out test.html

Renders a transactional email to HTML (or --text for the plaintext version) without sending anything — useful for checking branding (PUG_EMAIL_LOGO_URL, PUG_DASHBOARD_BASE_URL) before going live. Kinds: magic_link, invite, provider_test. --out FILE writes to a file instead of stdout.

This is the top-level pug email tooling group — distinct from pug worker email, which is the process that actually delivers mail.

Further reading

  • Deployment — run these commands as production processes
  • Development — the local workflow and make targets that wrap them
  • Configuration — the environment every command reads
Last updated on