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 — 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 grpc.origamy.io
  • Your data plane token from the setup wizard (dashboard → Connections)
  1. Create a working directory.

    Terminal window
    mkdir origamy-dp && cd origamy-dp
  2. Create your .env file — paste the token from the setup wizard.

    .env
    CONTROL_PLANE_ADDR=grpc.origamy.io:443
    DATA_PLANE_ID=<YOUR_DATA_PLANE_ID>
    AUTH_TOKEN=dpt_<PASTE_YOUR_TOKEN_HERE>
    CONFIG_SERVER_URL=https://app.origamy.io
    TLS_ENABLED=true
    DP_IMAGE_TAG=main
    LOG_LEVEL=info
    CLICKHOUSE_PASSWORD=<PICK_A_STRONG_PASSWORD>

    Never commit .env to git — add it to .gitignore immediately.

  3. Download the compose file and ClickHouse init script.

    Terminal window
    curl -fsSL https://app.origamy.io/byod/docker-compose.yml -o docker-compose.yml
    curl -fsSL https://app.origamy.io/byod/clickhouse-init.sql -o clickhouse-init.sql
  4. Start all services.

    Terminal window
    docker compose --env-file .env up -d
  5. 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 inside the compose project). To receive events from browsers and servers, put HTTPS in front of it. The compose project ships a Caddy ingress profile that terminates TLS with an automatic Let’s Encrypt certificate:

Terminal window
curl -fsSL https://app.origamy.io/byod/Caddyfile -o Caddyfile
# add to .env — a domain whose DNS A record points at this host:
# INGEST_DOMAIN=events.acme.com
docker compose --profile ingress --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.

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.

Pull the latest images and restart. No data is lost — ClickHouse data lives in a named Docker volume.

Terminal window
docker compose pull
docker compose up -d

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://grpc.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. Verify CONFIG_SERVER_URL is set and reachable.