eBPF Observability
    Docker Compose

    Deploy Coroot on a VPS

    Self-host Coroot, an eBPF-based observability platform with metrics, traces, service maps, and anomaly detection, on a RamNode VPS with Docker Compose.

    Coroot is an open-source, eBPF-based observability platform (metrics, traces, service maps, anomaly detection) that ships as a single Docker Compose stack.

    Assumptions: Ubuntu 24.04 LTS RamNode VPS, root or sudo access, a domain name pointed at the VPS (e.g. coroot.example.com).


    1. Prerequisites

    shell
    sudo apt update && sudo apt upgrade -y
    sudo apt install -y ca-certificates curl gnupg git ufw

    Install Docker Engine + Compose plugin

    shell
    sudo install -m 0755 -d /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    sudo chmod a+r /etc/apt/keyrings/docker.gpg
    
    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
      https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" | \
      sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    
    sudo apt update
    sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    sudo systemctl enable --now docker

    Verify:

    shell
    docker --version
    docker compose version

    2. Get Coroot's Docker Compose stack

    shell
    sudo mkdir -p /opt/coroot
    cd /opt/coroot
    sudo curl -fsSL https://raw.githubusercontent.com/coroot/coroot/main/deploy/docker-compose/docker-compose.yaml -o docker-compose.yaml

    The stack includes:

    • coroot — the main UI/API server
    • coroot-node-agent — eBPF agent (runs as a daemon, needs privileged host access)
    • coroot-cluster-agent — collects cluster-level data
    • clickhouse — storage backend for traces/logs
    • prometheus (or your existing Prometheus if you have one)

    Review and adjust docker-compose.yaml:

    • Set a persistent data path (bind mounts under /opt/coroot/data)
    • Pin image versions instead of :latest for reproducibility
    • If you already run Prometheus elsewhere, point coroot at it via --prometheus-url instead of running the bundled one
    shell
    sudo mkdir -p /opt/coroot/data/{clickhouse,prometheus,coroot}

    3. Start the stack

    shell
    cd /opt/coroot
    sudo docker compose up -d

    Check status:

    shell
    sudo docker compose ps
    sudo docker compose logs -f coroot

    By default the Coroot UI listens on port 8080.


    4. Firewall

    shell
    sudo ufw allow OpenSSH
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    sudo ufw enable

    Do not expose port 8080 directly to the internet — put it behind a reverse proxy (below). The node-agent needs host/network privileges but no inbound ports need to be opened for it.


    5. Reverse proxy + TLS (Caddy)

    Caddy gets you automatic Let's Encrypt TLS with almost no config.

    shell
    sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
    sudo apt update && sudo apt install -y caddy

    Edit /etc/caddy/Caddyfile:

    shell
    coroot.example.com {
        reverse_proxy localhost:8080
    }
    shell
    sudo systemctl reload caddy

    Alternatively, if you're already running Warpgate or step-ca on this box, you can issue an internal cert instead — see the step-ca guide for integrating ACME/internal CAs with nginx or Caddy.


    6. Auto-start on boot

    Docker Compose services with restart: always (already set in the upstream compose file) will come back up after a reboot as long as the Docker daemon is enabled, which we did with systemctl enable docker.

    To be extra safe, you can also wrap it in a systemd unit:

    shell
    sudo tee /etc/systemd/system/coroot.service > /dev/null <<'EOF'
    [Unit]
    Description=Coroot observability stack
    Requires=docker.service
    After=docker.service
    
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    WorkingDirectory=/opt/coroot
    ExecStart=/usr/bin/docker compose up -d
    ExecStop=/usr/bin/docker compose down
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    sudo systemctl daemon-reload
    sudo systemctl enable coroot.service

    7. Verify

    • Visit https://coroot.example.com — you should see the Coroot onboarding screen.
    • Confirm the node-agent is reporting: sudo docker logs coroot-node-agent
    • Check ClickHouse has data flowing: sudo docker exec -it <clickhouse-container> clickhouse-client -q "SHOW TABLES"

    8. Updating

    shell
    cd /opt/coroot
    sudo docker compose pull
    sudo docker compose up -d

    9. Troubleshooting

    SymptomLikely cause
    Node agent crashes / no dataKernel too old for eBPF, or missing --privileged / pid: host in compose file
    UI unreachableCheck ufw status, confirm Caddy is proxying to localhost:8080
    ClickHouse OOMRamNode VPS undersized — Coroot + ClickHouse benefit from ≥4GB RAM
    High disk usageConfigure ClickHouse TTL / retention settings in the compose env vars