---
title: "Self-hosting"
description: "Run the full Pug stack (Go services, Postgres, ClickHouse, NATS and Dragonfly) on your own infrastructure."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.pug.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Self-hosting

Run the full Pug stack on your own infrastructure. Self-hosting gives you complete data ownership, custom deployment topology, and air-gapped operation.

## What you'll run

A working Pug instance has **two deployables**, the backend and the dashboard, plus **four backing stores**. They live in two repositories:

| Part | Repo | What it is | You deploy it as |
|------|------|-----------|------------------|
| **Backend** | [`pug-sh/pug`](https://github.com/pug-sh/pug) | The Go API server, the background workers, and the `pug` CLI - all one binary | Long-running server + worker processes |
| **Dashboard** | [`pug-sh/app`](https://github.com/pug-sh/app) | The React UI ("Pug UI") that reads and manages your data | Static files behind a web server / CDN |

Everything else (Postgres, ClickHouse, NATS, and Dragonfly) you either run yourself or point at a managed equivalent.

Once both are up, you do one more thing: **[point your SDKs](/self-hosting/connect-sdks) at your own server** instead of Pug Cloud. That's the whole job.

  <Stage title="Deploy the backend" note="pug-sh/pug">Run the API server, the workers, and migrations against your four stores.</Stage>
  <Stage title="Deploy the dashboard" note="pug-sh/app">Build the React SPA and serve it, pointed at your backend's URL.</Stage>
  <Stage title="Connect your SDKs" note="browser / node / flutter">Set the SDK endpoint to your server so events flow to your instance.</Stage>

## Get the code

The backend (the server, every worker, and the `pug` CLI) builds from one repo:

```bash
git clone git@github.com:pug-sh/pug.git
cd pug
```

The dashboard is a separate repo; see [Dashboard](/self-hosting/dashboard) for its build. To build from source you need a **Go >= 1.26** toolchain (backend) and **Bun** (dashboard); to run from prebuilt container images you need neither. Full prerequisites are in [Requirements](/self-hosting/requirements).

**Recommended reading order:** [Requirements](/self-hosting/requirements) -> [Configuration](/self-hosting/configuration) -> [Deployment](/self-hosting/deployment) -> [Dashboard](/self-hosting/dashboard) -> [Connect your SDKs](/self-hosting/connect-sdks). To run the whole stack on one machine for local work, follow [Development](/self-hosting/development) instead.

## When to self-host

| Self-host when... | Use Pug Cloud when... |
|-----------------|----------------------|
| Data must stay in your VPC | You want the fastest path to production |
| Compliance or regulatory requirements | You prefer managed infrastructure and upgrades |
| You have an existing Postgres / ClickHouse / NATS cluster | You don't want to operate stateful services |
| Air-gapped or on-premise environments | |

## Architecture

The backend is two kinds of process (the **API server** and a set of **background workers**), backed by four stores. The **dashboard** is a static single-page app that talks to the same API server.

  <Tier label="Clients"><Node>Browser / Mobile SDK</Node><Node>Dashboard - React SPA</Node></Tier>
  <Tier label="API"><Node>pug server - Connect RPC :3000</Node><Node muted>Dragonfly - cache / rate-limit</Node></Tier>
  <Tier label="Queue"><Node>NATS - JetStream</Node></Tier>
  <Tier label="Workers"><Node>events</Node><Node>profiles x3</Node><Node>compliance</Node><Node>email</Node></Tier>
  <Tier label="Storage"><Node>ClickHouse - analytics events</Node><Node>PostgreSQL - config + profiles</Node></Tier>

Both the SDKs (ingest) and the dashboard (read/manage) hit the **same** `pug server` on port `3000` - they differ only in which RPC services they call and how they authenticate ([public key](/get-started/authentication) for SDKs, JWT for the dashboard). Dragonfly (a Redis-compatible store) backs caching and rate limiting; it is never on the durable event path.

Tracing one event end-to-end:

  <Stage title="SDK -> pug server" note="x-api-key">An SDK POSTs the event to the API server, authenticated with your public key.</Stage>
  <Stage title="pug server -> NATS" note="enrich + publish">The server enriches the event (geo, user-agent, bot detection), validates it, and publishes it onto a JetStream stream.</Stage>
  <Stage title="events worker -> ClickHouse" note="persist">The events worker consumes the stream and writes the events to ClickHouse.</Stage>
  <Stage title="Dashboard <- pug server" note="reads">The dashboard queries the same server for insights, which read from ClickHouse and PostgreSQL.</Stage>

## Processes at a glance

Every runtime process is a sub-command of the single `pug` binary: the API server (`pug server`) plus **7 worker processes** - `events`, `email`, `compliance`, `demo`, and three profile workers (`identify`, `alias`, `upsert`).

You can run these three ways, mixed and matched:

| Way | What it is | Best for |
|-----|-----------|----------|
| **`pug dev`** (alias `pug start`) | One process that runs the server **and every worker** together | Local dev, or a small single-node instance |
| **Sub-commands** | `pug server`, `pug worker events`, ...: one process each | Production, when you want to scale and restart processes independently |
| **Standalone binaries / images** | A single-purpose binary (`pug-worker-events`) or container image per role | Kubernetes, systemd - see [Deployment](/self-hosting/deployment) |

For the **complete command tree**, every flag, and the build output, see the [CLI reference](/self-hosting/cli). [Deployment](/self-hosting/deployment) is the canonical runbook for running each process in production.

> The `demo` worker only generates the public demo dataset and stays idle unless `PUG_DEMO_ENABLED=true` - a normal self-host doesn't run it. The other six workers are the real pipeline.

## Sub-pages

- **Requirements** - Backing services, toolchains, ports, and sizing before you deploy.
[Read more](/self-hosting/requirements)
- **Configuration** - Every environment variable for the server and workers.
[Read more](/self-hosting/configuration)
- **Deployment** - Build the binaries or images, migrate, run each process, and harden.
[Read more](/self-hosting/deployment)
- **Dashboard** - Build, configure, and deploy the React UI, pointed at your backend.
[Read more](/self-hosting/dashboard)
- **Authentication** - Add Google or any OIDC identity provider with `PUG_CONFIG_FILE`.
[Read more](/self-hosting/authentication)
- **Connect your SDKs** - Repoint the browser, Node, and Flutter SDKs at your own instance.
[Read more](/self-hosting/connect-sdks)
- **CLI reference** - Every `pug` sub-command, flag, and the make targets that wrap them.
[Read more](/self-hosting/cli)
- **Development** - Run the whole stack locally with `pug dev` and Docker infra.
[Read more](/self-hosting/development)

Source: https://docs.pug.sh/self-hosting/index.mdx
