Since v3, Langfuse is no longer a single container + Postgres. Traces now live in ClickHouse (a columnar OLAP database), the queue in Redis, and raw payloads in S3 storage — here, MinIO. Six services in total.
ClickHouse is required since v3. If it's missing, the web container crash-loops (it can't reach clickhouse:9000). We set it up in step 04.
Six containers, ClickHouse among them: be generous with RAM. Below 4 GB, startup fails silently.
Avoid t4g / Graviton (ARM64) instances: the official images target amd64, and ARM causes crash loops. Stick to t3.
Never expose 3005, 8123 or 9000 publicly — those are internal ports. Also point a DNS A record for langfuse.mondomaine.com at the instance's elastic IP before the HTTPS step.
Once connected over SSH, install Docker and the Compose plugin via the official script.
Recent Docker uses docker compose (with a space). Your docker-compose (with a hyphen) commands also work if you install the old v1 binary — this guide uses the plugin.
Create the folder and the file. Here's the full compose: Postgres, ClickHouse, Redis and MinIO, with healthchecks and ordered startup.
Key points: the clickhouse service and its chdata volume, healthchecks on db and clickhouse, and a conditional depends_on (condition: service_healthy) so web/worker wait for the databases to be ready.
Both web and worker read this .env. Start by generating the three secrets.
NEXTAUTH_URL must be the exact public HTTPS URL, otherwise login breaks (invalid OAuth redirects). And change the default passwords (minio, redis, clickhouse) before going to production.
On first startup, the worker applies the ClickHouse migrations — this can take one to two minutes. Follow docker compose logs -f web until you see the server listening on port 3000.
web listens internally on 3000 (mapped to 3005). We don't expose it to the world — the reverse proxy handles that in the next step.
Caddy handles HTTPS automatically (Let's Encrypt certificate, renewal included) — it's the simplest option. We add it to the same compose so it can reach web internally.
Then remove the ports: - "3005:3000" mapping from the web service (Caddy reaches it internally via web:3000), and restart: docker compose up -d.
Caddy fetches the certificate on its own at the first hit on https://langfuse.mondomaine.com. If you prefer Nginx + certbot, the principle is identical: proxy to web:3000.
Open your domain over HTTPS. The first account created is yours — then create an organization, a project, and grab the API keys.
To close signups once your account exists, add AUTH_DISABLE_SIGNUP=true to the .env and rerun docker compose up -d.
Almost always an unreachable ClickHouse. Check that the hostname is clickhouse (not localhost) and that CLICKHOUSE_MIGRATION_URL=clickhouse://clickhouse:9000. Containers reach each other by service name on the Docker network.
docker compose down -v deletes the volumes = total data loss. To just stop, use docker compose down without the -v.