Self-host overview
Run the full Smartizy backend in your own environment. Five Docker Compose stacks make up the platform: two datastores, the ingest receiver, the admin console, and an edge proxy. This page explains how they fit together and the order to bring them up.
Self-hosting puts every beacon and every dashboard query inside your own infrastructure. The browser SDK and the dashboards are unchanged, so this track is purely about deploying and wiring the backend. If you only want to instrument a site against the hosted service, start at Quickstart instead.
How the stacks fit together #
Each stack lives under docker/<stack>/ and is one independent
docker compose unit. The build context for every app image is the repo root, so the
Dockerfiles can copy from src/. The five stacks are:
- ClickHouse (
docker/clickhouse): the analytics datastore. Holds therum.eventstable and the rollups that power the dashboards. - PostgreSQL (
docker/pg): the config datastore. Holds tenants, apps, ingest tokens, policies, and routing in therum_configdatabase. - Ingest receiver (
docker/ingest): accepts beacons at/v1/eventsand serves the collector bundle at/v1/rum/*. Writes events to ClickHouse and reads its per-app config from Postgres. - Admin console (
docker/admin): one image carrying the control-plane API and the SPA. Reads and writes Postgres, and reads ClickHouse for dashboards. - Edge proxy (
docker/front): terminates TLS and routes byHostheader to the admin console and the ingest receiver.
The two app stacks (ingest, admin) talk to the datastores; the edge proxy sits in front of both app stacks. Browsers reach the ingest receiver to send beacons, and operators reach the admin console through the same edge proxy.
Prerequisites #
- A host with Docker Engine and the Docker Compose plugin.
- The repository checked out. The build context for the app images is the repo root.
- An OIDC issuer for the admin console (the admin stack validates tokens against it).
- A TLS certificate in Azure Key Vault if you use the edge proxy (
docker/front).
Deployment order #
Bring the stacks up in dependency order. Datastores first, then the apps, then the edge.
Create the shared network
Every stack joins an externally created Docker network so containers reach each other by service name.
# Create the shared network once, before bringing up any stack.
docker network create ambilobe Start the datastores
Bring up docker/clickhouse and docker/pg. ClickHouse bootstraps the rum schema on first start; Postgres boots an empty rum_config database. See Datastores.
Start the ingest receiver
Build and start docker/ingest. It applies pending rum_config migrations on startup and begins accepting beacons. See Ingest receiver.
Start the admin console
Build and start docker/admin. It also applies pending migrations on startup and serves the SPA plus the control-plane API. See Admin console.
Start the edge proxy
Build and start docker/front to terminate TLS and route public traffic. See Edge & TLS.
The per-stack flow is the same everywhere:
# Each stack follows the same flow from the repo root.
cd docker/<stack>
cp .env.example .env # first time only, then fill in credentials
docker compose build # only for the app images (ingest, admin, front)
docker compose up -d The shared Docker network #
Every stack attaches to one external network named ambilobe. Containers address each
other by service name over it: the ingest receiver reaches Postgres at host postgres and
ClickHouse at host clickhouse; the edge proxy reaches the apps at admin and
ingest. Create the network once before the first docker compose up, or every
stack will fail to start.
What stays the same #
Self-hosting changes only where the data lives. Apps still embed the same browser SDK, and analysts still read the same dashboards. Once the receiver is up, register it as an ingest service and point apps at it, then embed the snippet exactly as the hosted track describes in Install the snippet. The link between a deployed receiver and the snippet an app embeds is covered in Routing.