---
title: "Requirements"
description: "Hardware, dependency versions and network prerequisites for a self-hosted Pug deployment."
---

> 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.

# Requirements

Backing services, toolchains, ports, and sizing for self-hosting Pug.

## Toolchains

What you need depends on whether you build from source or run prebuilt container images.

| Tool | Version | Needed for | Why |
|------|---------|-----------|-----|
| Go | ≥ 1.26 | Building the backend | Compiles the `pug` server, workers, and CLI. The repo targets `1.26.3`. |
| Bun | Latest | Building the dashboard | Installs deps and builds the React SPA. Node 22 is the runtime baseline. |
| Docker | Any recent release | Local infra **or** container builds | Runs the four backing services locally, and builds the backend images. |

If you deploy from published container images instead of building, you need **neither Go nor Bun** — only a container runtime. See [Deployment](/self-hosting/deployment).

```bash
git clone git@github.com:pug-sh/pug.git      # backend: server, workers, pug CLI
cd pug
```

The dashboard lives in a separate repo (`pug-sh/app`) and is covered in [Dashboard](/self-hosting/dashboard).

## Backing services

The backend requires four backing services: **PostgreSQL**, **ClickHouse**, **NATS**, and **Dragonfly**. The versions below are what the project develops and tests against (from the dev Docker Compose); you may run managed equivalents (e.g. Amazon RDS for Postgres, ClickHouse Cloud) at compatible versions. The Pug server itself appears in the table only for its listening port.

| Component | Image / Version | Container port(s) | Role |
|-----------|----------------|-------------------|------|
| PostgreSQL | `postgres:18` | `5432` | Auth, orgs, projects, dashboards, and config. Dev host mapping: `5433→5432`. |
| ClickHouse | `clickhouse/clickhouse-server:26.5` | `8123` (HTTP / `/ping`), `9000` (native), `9009` (interserver) | Analytics event storage and queries. Requires `ulimits.nofile` ≥ 262144. |
| NATS | `nats:2.14-alpine` | `4222` (client), `6222` (cluster), `8222` (monitoring) | JetStream message queue. Must be started with `--jetstream`. |
| Dragonfly | `docker.dragonflydb.io/dragonflydb/dragonfly:v1.38.1` | `6379` | Redis-compatible cache / rate-limit. Dev host mapping: `6380→6379`. |
| Pug server | — | `3000` | The Connect RPC API server. Override with `PUG_SERVER_PORT`. |

> **NATS JetStream is required.** Start NATS with `--jetstream` (and `--store_dir` for a durable volume). The monitoring server (`-m 8222`) exposes `/healthz` on port 8222. Without JetStream, event ingestion will not function.

For how the dev Compose file wires these up locally — health checks, volumes, and the observability overlay — see [Development](/self-hosting/development).

## Ports summary

Only the Pug server (and your static dashboard host) need to be reachable from outside your private network. All backing services should be kept on an internal network:

| Port | Service | Exposure |
|------|---------|----------|
| `3000` | Pug server (Connect RPC) | Public — behind a TLS terminator |
| `8090` | Worker health / readiness | Internal only — probes (configurable via `PUG_WORKER_HEALTH_ADDR`) |
| `5432` | PostgreSQL | Internal only |
| `4222` | NATS client | Internal only |
| `8123` / `9000` | ClickHouse HTTP / native | Internal only |
| `6379` | Dragonfly | Internal only |

## Sizing guidance

These are **starting-point ballparks, not hard requirements**. Actual resource needs depend heavily on event volume and retention.

### Development / staging

| Component | CPU | RAM | Disk |
|-----------|-----|-----|------|
| Pug server + workers | 2 vCPU | 2 GB | — |
| PostgreSQL | 1 vCPU | 2 GB | 20 GB |
| ClickHouse | 2 vCPU | 4 GB | 50 GB |
| NATS | 1 vCPU | 1 GB | 10 GB (JetStream store) |
| Dragonfly | 1 vCPU | 1 GB | — |

### Production (small — up to ~1 k events/s)

| Component | CPU | RAM | Disk |
|-----------|-----|-----|------|
| Pug server | 2 vCPU | 2 GB | — |
| Workers (per type) | 2 vCPU | 2 GB | — |
| PostgreSQL | 2 vCPU | 8 GB | 100 GB SSD |
| ClickHouse | 4 vCPU | 16 GB | 500 GB SSD |
| NATS | 2 vCPU | 2 GB | 20 GB SSD |
| Dragonfly | 1 vCPU | 2 GB | — |

The dashboard is static files — it needs no compute of its own, only a web server or CDN.

### Production (larger workloads)

Scale the **events worker** horizontally for higher ingest throughput — each replica is an independent JetStream consumer. Give ClickHouse more CPU, RAM, and disk as event volume and retention grow. NATS benefits from a 3-node cluster for JetStream HA.

## Optional: geo enrichment (Cloudflare)

Server-side geo auto-properties (`$country`, `$region`, `$city`, `$continent`, and related fields) are resolved **at ingestion by the server** — it reads them from **Cloudflare proxy headers** (`CF-IPCountry`, `CF-Region`, `CF-IPCity`, `CF-IPContinent`, etc.) on the inbound request. So this needs Cloudflare (or a proxy that sets the same headers) in front of the server; the visitor IP itself is never persisted.

- `CF-IPCountry` is added automatically when Cloudflare IP Geolocation is enabled on your zone.
- `CF-Region`, `CF-IPCity`, and the remaining location headers require the **"Add visitor location headers"** [Managed Transform](https://developers.cloudflare.com/rules/transform/managed-transforms/reference/) to be enabled.

Geo lookup sits behind a small `Provider` interface (`internal/geo`), and Cloudflare headers are the **only implementation today**. The interface is designed to also accept a local database lookup — e.g. MaxMind (MMDB) — from the client IP in a future release. Until then, if Pug runs behind a different proxy or without these headers, geo auto-properties are simply absent from events; there's no built-in GeoIP database yet.

## Further reading

- [Configuration](/self-hosting/configuration) — environment variables and secrets
- [Deployment](/self-hosting/deployment) — production deployment guide
- [Development](/self-hosting/development) — local dev stack setup

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