Self-hosting on Docker
Run the full data plane on one Linux host with Docker Compose. For a one-command install,
use origamy deploy instead — it downloads this same bundle, asks about
the optional services, generates the passwords, and writes the .env for you. This guide is
the manual equivalent.
Prerequisites
Section titled “Prerequisites”- Docker Engine 24+ and Compose V2 (
docker compose version) - A Linux host with at least 4 GB RAM free
- Outbound TCP 443 allowed to
tunnel.origamy.io - The
.envblock from the dashboard: Connections → Connect data plane → Docker / bare-metal
-
Create a working directory.
Terminal window mkdir origamy-dp && cd origamy-dp -
Create
.envfrom the dashboard’s block. It already carries your data-plane id, the one-time token, and the control-plane addresses. Add the release pin, the profiles you want, and generated datastore passwords:Terminal window # .env — the first block is what the dashboard gives youCONTROL_PLANE_ADDR=tunnel.origamy.io:443CONFIG_URL=https://v1.origamy.io/api/v1/configTELEMETRY_URL=https://v1.origamy.io/api/v1/telemetryCONTROL_PLANE_HTTP_URL=https://v1.origamy.ioDATA_PLANE_ID=<YOUR_DATA_PLANE_ID>AUTH_TOKEN=dpt_<PASTE_YOUR_TOKEN_HERE>TLS_ENABLED=trueLOG_LEVEL=info# Release to run. `main` tracks the moving edge; pin a published release for production.DP_IMAGE_TAG=0.1.17# Optional services (see the table below). Leave empty for the core pipeline only.COMPOSE_PROFILES=fullINGEST_DOMAIN=# Datastore passwords. Generate them once (openssl rand -base64 32) and never change them# after first start — the datastores hold your data under these credentials.DP_REDIS_PASSWORD=NATS_PASSWORD=CLICKHOUSE_PASSWORD=DB_PASSWORD=CONFIG_URLandTELEMETRY_URLare full endpoint URLs;CONTROL_PLANE_HTTP_URLis the bare base. Leaving a password empty runs that datastore without authentication, which is only acceptable on an isolated host. Never commit.envto git. -
Download the bundle. The control plane serves it at
/byod/*:Terminal window B=https://app.origamy.io/byodcurl -fsSLO $B/docker-compose.ymlcurl -fsSLO $B/clickhouse-init.sql # event schemacurl -fsSLO $B/clickhouse-users.xml # applies CLICKHOUSE_PASSWORDcurl -fsSLO $B/Caddyfile # only needed for the ingress profile -
Choose profiles. The core pipeline always runs; everything else is a Compose profile, listed in
COMPOSE_PROFILES(comma-separated) or passed with--profile:Profile Adds Needs fullPostgres + workflow-engine — journeys, broadcasts, human tasks DB_PASSWORDagenticThe AI engine (a gated package) Postgres; ORCH_KEK,ORCH_ENGINE_API_TOKEN,ORCHESTRATOR_ENGINE_URL— see AI engineingressCaddy terminating HTTPS for your event endpoint INGEST_DOMAIN, ports 80 and 443 -
Start all services.
Terminal window docker compose --env-file .env up -d -
Verify the tunnel connected.
Terminal window docker compose logs portal-agent --tail=30Look for
portal-agent connected to control plane. The Connections page in the dashboard updates automatically once it’s seen.
Expose your event endpoint
Section titled “Expose your event endpoint”Your SDKs send events to the ingestion gateway — port 8081 on the host, plain HTTP. For
browser and server traffic from the internet, put HTTPS in front of it. The bundle’s ingress
profile runs Caddy, which terminates TLS on your domain with an automatic Let’s Encrypt
certificate:
# .env: a domain whose DNS A record points at this host, and the profileINGEST_DOMAIN=events.acme.comCOMPOSE_PROFILES=full,ingress
docker compose --env-file .env up -dYour SDKs then post to https://events.acme.com/v1/track (and /v1/identify, /v1/batch, …).
Once it’s live, paste the URL into your source’s Setup tab in the dashboard so the SDK
snippets it generates use your endpoint.
AI engine
Section titled “AI engine”The orchestrator engine (agent runs, copilot) is a gated package that runs inside your data
plane under the agentic profile. It needs three more .env keys:
COMPOSE_PROFILES=full,agenticORCH_KEK=$(openssl rand -base64 32) # encrypts per-workspace LLM keys at rest — never rotate itORCH_ENGINE_API_TOKEN=$(openssl rand -base64 32)ORCHESTRATOR_ENGINE_URL=http://orchestrator-engine:18090On a self-hosted plane the engine only calls the model provider with a credential stored for
your workspace through the dashboard (ORCH_REQUIRE_TENANT_KEY=true, the default) — there
is no shared Origamy key to fall back to, so prompts never egress under anyone else’s account.
The engine stays inert until AI is enabled for the workspace and a credential is added.
origamy upgrade --enable-ai does all of the above for you.
Sizing
Section titled “Sizing”| Tier | CPU | RAM | Disk | Capacity |
|---|---|---|---|---|
| Dev / test | 2 vCPU | 4 GB | 20 GB | < 100k events/day |
| Production | 4–6 vCPU | 8–16 GB | 100–200 GB SSD | 100k – 2M events/day |
| High volume | 8–16 vCPU | 32–64 GB | 500 GB+ NVMe | 2M+ events/day |
ClickHouse is the most memory-hungry service. If you run close to the RAM limit, tune
clickhouse.max_memory_usage in the compose file.
Upgrades
Section titled “Upgrades”Use the CLI from your data-plane directory — it pins DP_IMAGE_TAG, pulls, and restarts. No
data is lost: your datastores live in named Docker volumes.
origamy upgrade # to the release this CLI was built fororigamy upgrade --version 0.1.17 # to a specific releaseorigamy upgrade --channel edge # or track the moving :main imagesorigamy upgrade --enable-ai # switch the AI engine on (or --disable-ai)By hand: set DP_IMAGE_TAG in .env, then docker compose --env-file .env pull && docker compose --env-file .env up -d --remove-orphans. The --remove-orphans stops containers of a
profile you turned off.
Token rotation
Section titled “Token rotation”Rotate your token from the Connections page, then update .env and restart only portal-agent:
# edit .env: replace AUTH_TOKEN=dpt_<OLD> with AUTH_TOKEN=dpt_<NEW>docker compose restart portal-agentdocker compose logs portal-agent --tail=20 --followTroubleshooting
Section titled “Troubleshooting”| Symptom | Fix |
|---|---|
| portal-agent keeps restarting | Check CONTROL_PLANE_ADDR resolves and outbound TCP 443 is open: curl -v telnet://tunnel.origamy.io:443 |
| Token rejected (auth error in logs) | The token was rotated without restarting portal-agent. Re-copy from the Connections page, update .env, restart portal-agent. |
| ClickHouse OOM / exits | Increase the host’s Docker memory limit, or add memory_limit: 2g under the clickhouse service. |
| Events sent but nothing in dashboard | Confirm DATA_PLANE_ID matches the Connections page. Then check docker compose logs ingestion-gateway --tail=50. |
| Sources/destinations not updating | Check docker compose logs config-sync. CONFIG_URL must be the full …/api/v1/config URL, not the bare host. |
authorization violation from NATS, or ClickHouse Authentication failed |
A datastore password in .env changed after first start. Restore the original value — the data lives under it. |
| A profile’s containers keep running after you removed it | docker compose --env-file .env up -d --remove-orphans. |
