Skip to content

Install

Fanout ships as a single binary and as a multi-architecture container image. Neither needs anything else installed: there is no runtime, no database and no collector to place first.

Terminal window
docker run -d --name fanout \
-p 7520:7520 -p 4317:4317 -p 4318:4318 \
-v fanout-data:/var/lib/fanout/data \
-e FANOUT_AUTH_CODE_SECRET=$(openssl rand -hex 32) \
labstack/fanout:latest

Images are published to Docker Hub as labstack/fanout and mirrored to GitHub Container Registry as ghcr.io/labstack/fanout. The two carry the same digests; pick whichever registry your hosts already pull from.

FANOUT_AUTH_CODE_SECRET is required in the default local auth mode and must be at least 32 characters — the container refuses to start without it. It is the only setting the command above adds; the image ships listener and data-directory defaults of its own. Add FANOUT_AI_API_KEY to enable the chat investigator, which is optional: without a key the process starts normally and logs that the agent is disabled.

The image binds every listener on all interfaces so the published ports work. The native binary does not — see the table below.

The install script checks the archive for you. If you took one from the releases page by hand, check it yourself — both the checksum and the build provenance:

Terminal window
sha256sum -c SHA256SUMS
gh attestation verify fanout_v2026.8.0_linux_amd64.tar.gz \
--repo labstack/fanout

For containers, record or pin the digest the registry returns rather than trusting a moving tag:

Terminal window
docker buildx imagetools inspect labstack/fanout:2026.8.0

Release images are multi-architecture for linux/amd64 and linux/arm64, and archives cover Linux and macOS on both. Every artifact is built on a native runner, because DuckDB needs cgo.

Image tagPoints at
labstack/fanout:latestthe newest release
labstack/fanout:2026.8.0that exact release
labstack/fanout:mainthe tip of main
labstack/fanout:sha-<commit>one specific commit

Every tag above also exists under ghcr.io/labstack/fanout.

Standalone signatures and SBOMs are deliberately not published yet — the reasoning is in the repository’s release contract.

Port or pathPurposeNative default
7520Browser client, HTTP API, chat, and MCP:7520, all interfaces
4317OTLP ingest over gRPC127.0.0.1:4317, loopback only
4318OTLP ingest over HTTP127.0.0.1:4318, loopback only
./dataTelemetry, query state, users, sessions, dashboards, alerts and agent history./data

The two ingest listeners bind to loopback by default in the native binary. That is deliberate: an ingest port reachable from the network before you have set a token is worse than one you have to open on purpose. Set FANOUT_OTLP_GRPC_ADDR and FANOUT_OTLP_HTTP_ADDR when you are ready to accept telemetry from other hosts, and read authenticate exporters first.

The process validates its whole configuration before it opens any listener, so a setting it will not accept is a refusal to start rather than a failure later. First boot covers what it checks, and what it prints once it is running.