−25%

op Windows bij jaarbetaling, tot 31/10. Naar de pakketten

EQVPS
Aan de slag

VPS voor Langfuse: zie wat je AI-agents deden

Host Langfuse zelf en volg elke LLM-aanroep en elke toolstap van je agents die zonder toezicht draaien. Geteste Docker Compose, echte RAM-cijfers en een plan.

Een agent die om drie uur 's nachts zonder toezicht werkt, is precies zoveel waard als jouw vermogen om achteraf te reconstrueren wat hij deed. „Heeft vannacht $38 aan tokens verstookt” is een slechte ochtend. „Heeft $38 verstookt omdat een zoektool een lege pagina teruggaf en de planner het 400 keer opnieuw probeerde” is een bug die je voor de lunch oplost. Voor die tweede zin heb je traces nodig.

Langfuse legt elke LLM-aanroep vast, met prompt, toolstap, aantal tokens en latency, als een boom waar je doorheen kunt klikken. Host je het zelf, dan blijven die prompts en antwoorden — vaak met klantdata, API-output en af en toe een verdwaald geheim erin — op een server die jij beheert, niet in het dashboard van een ander.

Wat het kost om het te draaien

Langfuse v4 is geen klein binary maar zes containers: de webapp, een achtergrondworker, Postgres, ClickHouse voor events, Redis en MinIO voor bestanden. We installeerden het op een testserver en maten ongeveer 3,5 GB RAM in gebruik met een leeg project. Wat groeit is ClickHouse, want daar belandt elke span die je stuurt.

BelastingPlan
Een handvol agents, weken aan tracesMedium-IP: 6 vCPU, 6 GB, 45 GB ($20/mnd)
Een vloot agents, maanden historiePro-plannen, vanaf 32 GB RAM — op aanvraag

Op kleinere plannen installeert het wel, maar daarna gaat het piepen zodra ClickHouse en de worker tegelijk geheugen willen. Ik zou niet onder de 6 GB gaan.

Waar wonen de agents? Draaien ze op andere machines, kies dan een plan met een eigen IPv4: ze hebben een HTTPS-endpoint nodig, en op een NAT-plan is het uitgaande adres niet je eigen adres en is van buitenaf alleen de SSH-poort bereikbaar. Draaien de agents op deze server zelf, dan hoeft Langfuse nooit aan het internet te hangen: voor een test volstaat Medium met NAT ($12/mnd). Er zijn twee locaties, Duitsland en Finland; de beschikbaarheid zie je bij het bestellen. Kies de locatie die het dichtst bij de agents ligt, niet bij jou. Servers betaal je met crypto, zonder KYC.

Installatie

Op een verse Ubuntu 24.04- of Debian 12-server, als root. Eerst Docker:

curl -fsSL https://get.docker.com | sh

Dan Langfuse, met echte geheimen in plaats van de standaardwaarden uit het compose-bestand:

git clone --depth 1 https://github.com/langfuse/langfuse.git
cd langfuse

PG=$(openssl rand -hex 16); MINIO=$(openssl rand -hex 16)
cat > .env <<EOF
NEXTAUTH_URL=https://langfuse.example.com
NEXTAUTH_SECRET=$(openssl rand -hex 32)
SALT=$(openssl rand -hex 32)
ENCRYPTION_KEY=$(openssl rand -hex 32)
POSTGRES_PASSWORD=$PG
DATABASE_URL=postgresql://postgres:$PG@postgres:5432/postgres
CLICKHOUSE_PASSWORD=$(openssl rand -hex 16)
MINIO_ROOT_PASSWORD=$MINIO
LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY=$MINIO
LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY=$MINIO
LANGFUSE_S3_BATCH_EXPORT_SECRET_ACCESS_KEY=$MINIO
REDIS_AUTH=$(openssl rand -hex 16)
TELEMETRY_ENABLED=false
EOF
chmod 600 .env

Twee van die wachtwoorden horen bij elkaar: het Postgres-wachtwoord staat ook in DATABASE_URL, en het MinIO-wachtwoord moet overeenkomen met de drie regels S3_..._SECRET_ACCESS_KEY. Daarom komt elk uit één variabele.

Nu de valkuil. Het compose-bestand publiceert de webapp op poort 3000 en MinIO op 9090 op alle interfaces, en door Docker gepubliceerde poorten gaan langs ufw heen. Bind beide aan localhost, zodat de reverse proxy de enige ingang is:

sed -i 's/- 3000:3000/- 127.0.0.1:3000:3000/; s/- 9090:9000/- 127.0.0.1:9090:9000/' docker-compose.yml
docker compose up -d
curl -s http://127.0.0.1:3000/api/public/health

De laatste opdracht moet {"status":"OK", ...} tonen. Bij de eerste start draaien de databasemigraties; in onze test slaagde de health check ongeveer 15 seconden nadat de containers opkwamen.

HTTPS ervoor

Laat langfuse.example.com naar het IP van de server wijzen, en dan:

apt install -y caddy
cat > /etc/caddy/Caddyfile <<'EOF'
langfuse.example.com {
    reverse_proxy 127.0.0.1:3000
}
EOF
systemctl reload caddy
ufw allow 22/tcp && ufw allow 80/tcp && ufw allow 443/tcp && ufw enable

Caddy haalt het certificaat zelf op. Open de site, maak je account aan (dat wordt de eerste organisatie), voeg een project toe en kopieer de publieke en geheime sleutel ervan.

Doe daarna de deur achter je dicht. Langfuse begrijpt AUTH_DISABLE_SIGNUP, maar het standaard compose-bestand geeft het niet door aan de webcontainer, dus er moet één regel bij onder langfuse-web:

sed -i 's|^      NEXTAUTH_SECRET: \(.*\)$|      NEXTAUTH_SECRET: \1\n      AUTH_DISABLE_SIGNUP: ${AUTH_DISABLE_SIGNUP:-false}|' docker-compose.yml
echo "AUTH_DISABLE_SIGNUP=true" >> .env
docker compose up -d

Vanaf nu krijgt een registratiepoging «Sign up is disabled». Collega's voeg je toe vanuit het project.

Traces sturen vanuit een agent

De Python-SDK verpakt je functies, en geneste aanroepen worden geneste spans:

python3 -m venv venv && . venv/bin/activate
pip install langfuse
export LANGFUSE_PUBLIC_KEY=pk-lf-...
export LANGFUSE_SECRET_KEY=sk-lf-...
export LANGFUSE_BASE_URL=https://langfuse.example.com
from langfuse import get_client, observe

langfuse = get_client()  # leest de LANGFUSE_*-variabelen

@observe(name="fetch-prices")
def fetch_prices(pair: str) -> dict:
    return {"pair": pair, "bid": 64210.5}

@observe(name="nightly-agent-run")
def run() -> str:
    data = fetch_prices("BTC/USDT")
    return f"done: {data['pair']}"

print(run())
langfuse.flush()  # korte scripts stoppen voordat het verzenden op de achtergrond klaar is

Sla LANGFUSE_BASE_URL niet over. Zonder die variabele stuurt de SDK alles stilletjes naar de cloud van Langfuse, je sleutels bestaan daar niet en je zit naar een leeg dashboard te kijken.

Zo controleer je vanaf de shell dat de spans zijn aangekomen:

curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
  "$LANGFUSE_BASE_URL/api/public/v2/observations?limit=5"

In v4 geeft het oude endpoint /api/public/traces een fout over de events-only-modus. Dat is zo bedoeld, de installatie is niet kapot. In een echte agent verpak je de LLM-aanroep en elke tool op dezelfde manier; bovendien heeft Langfuse integraties voor de gangbare LLM-SDK's en agentframeworks, dus vaak volstaat het om een import te wijzigen in plaats van overal decorators neer te zetten.

Waar je op let

  • Schijf. ClickHouse en MinIO bewaren alles wat je stuurt. docker system df -v laat zien waar de ruimte gebleven is. Trace je lange prompts en antwoorden, dan zit de 45 GB van Medium-IP binnen weken vol, niet binnen jaren. Kijk één keer per maand; groei je eruit, dan is een Pro-plan met 400 GB of meer op aanvraag.
  • Updates. Het compose-bestand pint de hoofdversie (:4). docker compose pull && docker compose up -d haalt de fixes binnen die versie op. Lees de changelog voordat je een hoofdversie overslaat: juist in v4 verdween het traces-endpoint.
  • Back-ups. Wat ertoe doet zit in Docker-volumes: Postgres bewaart gebruikers, projecten en sleutels; ClickHouse en MinIO de traces. Kopieer ze volgens een schema naar een plek buiten de server.

Is het $20 per maand waard? Als je agents meer dan dat aan tokens uitgeven — en de meeste agents zonder toezicht doen dat — dan betaalt weten waar de tokens heen gingen zich terug de eerste keer dat een lus op hol slaat. Eén kleine agent die één keer per dag draait, heeft dit allemaal niet nodig: een logbestand en een tokenteller zijn genoeg.

Gerelateerd

Klaar om te implementeren? Betaal met crypto, geen KYC — live in ongeveer een minuut.

Nu implementeren →

FAQ

Hoeveel RAM heeft zelfgehoste Langfuse nodig?

Op onze testserver draaide Langfuse v4 als zes containers — web, worker, Postgres, ClickHouse, Redis en MinIO — en gebruikte het ongeveer 3,5 GB RAM met een leeg project. ClickHouse groeit met elke span die je stuurt. Medium-IP (6 GB RAM, 45 GB schijf) draait het met gemak voor een handvol agents; een hele vloot met maanden historie heeft een Pro-plan nodig, beschikbaar op aanvraag.

Heb ik een eigen IP-adres nodig voor Langfuse?

Alleen als je agents ergens anders draaien en traces via internet sturen: dan hebben ze een HTTPS-endpoint nodig, en een NAT-plan accepteert van buitenaf alleen je SSH-poort. Draaien de agents op dezelfde server, dan kan Langfuse op localhost blijven en open je het dashboard via een SSH-tunnel; daarvoor volstaat het Medium-plan met NAT.

Mijn code draait, maar het dashboard blijft leeg. Waarom?

Bijna altijd ontbreekt LANGFUSE_BASE_URL. Zonder die variabele stuurt de SDK alles naar de cloud van Langfuse zelf, je zelfgehoste sleutels bestaan daar niet en er komt niets aan op je server. Zet je eigen adres in de variabele.

Het endpoint /api/public/traces geeft een fout. Is de installatie kapot?

Nee. Langfuse v4 draait in een events-only-modus waarin dat endpoint uitgeschakeld is. Lees data via /api/public/v2/observations; met die aanroep hebben wij gecontroleerd dat onze testspans waren aangekomen.

Hoe voorkom ik dat vreemden zich op mijn instance registreren?

Langfuse leest AUTH_DISABLE_SIGNUP, maar de standaard docker-compose.yml geeft die variabele niet door aan de webcontainer, dus alleen een regel in .env doet niets. Voeg een regel toe aan de omgeving van langfuse-web (de opdracht staat hieronder), zet hem op true nadat je je eigen account hebt aangemaakt, en volgende aanmeldingen krijgen «Sign up is disabled».

Reacties

Nog geen reacties. Wees de eerste.

Laat een reactie achter

Reacties worden gemodereerd voordat ze verschijnen.