Skip to content

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.

  • 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 .env block from the dashboard: Connections → Connect data plane → Docker / bare-metal
  1. Create a working directory.

    Terminal window
    mkdir origamy-dp && cd origamy-dp
  2. Create .env from 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 you
    CONTROL_PLANE_ADDR=tunnel.origamy.io:443
    CONFIG_URL=https://v1.origamy.io/api/v1/config
    TELEMETRY_URL=https://v1.origamy.io/api/v1/telemetry
    CONTROL_PLANE_HTTP_URL=https://v1.origamy.io
    DATA_PLANE_ID=<YOUR_DATA_PLANE_ID>
    AUTH_TOKEN=dpt_<PASTE_YOUR_TOKEN_HERE>
    TLS_ENABLED=true
    LOG_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=full
    INGEST_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_URL and TELEMETRY_URL are full endpoint URLs; CONTROL_PLANE_HTTP_URL is the bare base. Leaving a password empty runs that datastore without authentication, which is only acceptable on an isolated host. Never commit .env to git.

  3. Download the bundle. The control plane serves it at /byod/*:

    Terminal window
    B=https://app.origamy.io/byod
    curl -fsSLO $B/docker-compose.yml
    curl -fsSLO $B/clickhouse-init.sql # event schema
    curl -fsSLO $B/clickhouse-users.xml # applies CLICKHOUSE_PASSWORD
    curl -fsSLO $B/Caddyfile # only needed for the ingress profile
  4. 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
    full Postgres + workflow-engine — journeys, broadcasts, human tasks DB_PASSWORD
    agentic The AI engine (a gated package) Postgres; ORCH_KEK, ORCH_ENGINE_API_TOKEN, ORCHESTRATOR_ENGINE_URL — see AI engine
    ingress Caddy terminating HTTPS for your event endpoint INGEST_DOMAIN, ports 80 and 443
  5. Start all services.

    Terminal window
    docker compose --env-file .env up -d
  6. Verify the tunnel connected.

    Terminal window
    docker compose logs portal-agent --tail=30

    Look for portal-agent connected to control plane. The Connections page in the dashboard updates automatically once it’s seen.

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:

Terminal window
# .env: a domain whose DNS A record points at this host, and the profile
INGEST_DOMAIN=events.acme.com
COMPOSE_PROFILES=full,ingress
docker compose --env-file .env up -d

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

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:

Terminal window
COMPOSE_PROFILES=full,agentic
ORCH_KEK=$(openssl rand -base64 32) # encrypts per-workspace LLM keys at rest — never rotate it
ORCH_ENGINE_API_TOKEN=$(openssl rand -base64 32)
ORCHESTRATOR_ENGINE_URL=http://orchestrator-engine:18090

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

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.

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.

Terminal window
origamy upgrade # to the release this CLI was built for
origamy upgrade --version 0.1.17 # to a specific release
origamy upgrade --channel edge # or track the moving :main images
origamy 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.

Rotate your token from the Connections page, then update .env and restart only portal-agent:

Terminal window
# edit .env: replace AUTH_TOKEN=dpt_<OLD> with AUTH_TOKEN=dpt_<NEW>
docker compose restart portal-agent
docker compose logs portal-agent --tail=20 --follow
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.