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
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 serverStarts 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 aliasRuns 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.
| Command | Consumes / does |
|---|---|
pug worker events | Consumes ingested events from JetStream and writes them to ClickHouse. The one to scale horizontally. |
pug worker email | Sends transactional email (magic links, invites, notifications). |
pug worker compliance | GDPR/DPDP data-subject erasure, export, and retention. |
pug worker profile identify | Applies identify calls to profiles. |
pug worker profile alias | Merges identities via alias. |
pug worker profile upsert | Writes profile property updates. |
pug worker demo | Generates 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.
| Command | What it does | Flags |
|---|---|---|
pug postgres migrate | Applies Postgres schema migrations. | --direction/-d up|down (default up), --num/-n N (steps; 0 = all) |
pug nats migrate | Creates the JetStream streams and consumers. | — |
pug clickhouse migrate | Applies 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 migrationConnection 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 laptopSeeds 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.)
| Flag | Default | Description |
|---|---|---|
--count / -c | 500000 | Total number of events to generate. |
--batch / -b | 10000 | Events per ClickHouse insert batch. |
--no-reset | off | Skip the migrate down/up reset; truncate the demo tables and re-seed instead. |
Run migrations first (or let
seedreset 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.htmlRenders 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 emailtooling group — distinct frompug worker email, which is the process that actually delivers mail.
Further reading
- Deployment — run these commands as production processes
- Development — the local workflow and
maketargets that wrap them - Configuration — the environment every command reads