How to install Langfuse on a VPS
Langfuse provides tracing, prompt management and evaluation data for LLM applications. Its self-hosted deployment uses several persistent services, so this guide prepares a Docker host, follows the maintained Compose deployment and protects the keys needed by the web and ingestion layers.
Prerequisites
Use Ubuntu 22.04 or 24.04 with SSH, a public IP, Docker and a domain such as langfuse.example.com. Official minimums are 4 CPU cores, 16 GB RAM, 100 GB disk. Langfuse runs PostgreSQL, ClickHouse, Redis, MinIO and two application containers (about 6 containers total). Keep extra disk for traces, analytical indexes and object storage.
Time zone warning: Both PostgreSQL and ClickHouse must run in the UTC timezone. Non-UTC configurations cause incorrect query results, which is a silent and confusing failure. Verify your server's timezone with
timedatectlbefore deploying.
You also need a backup target, a password generator and an understanding that observability data can contain prompts and user input. Define a retention policy before sending real traffic.
Step 1, Connecting to your server
Prepare the host and an administrator-only directory:
ssh root@SERVER_IP
apt update && apt upgrade -y
apt install -y ca-certificates curl git
mkdir -p /opt/langfuse
cd /opt/langfuse
chmod 750 /opt/langfuseLeave ports 80 and 443 for the reverse proxy. Do not publish database, cache or object-storage ports to the internet.
Step 2, Installing Docker and Docker Compose
Install Docker Engine and the Compose plugin from Docker's official Ubuntu instructions:
docker --version
docker compose version
systemctl enable --now dockerConfirm that the server has enough free space before downloading the maintained stack. Pin image tags after testing a release.
Step 3, Running the maintained Langfuse stack
Langfuse publishes a self-hosted Compose deployment through its official documentation and source repository. Use the current deployment files rather than constructing a three-line compose file that omits analytical storage or migrations. Place the files in /opt/langfuse and follow the release's directory layout.
Create the environment file with newly generated values. All required variables are listed below:
Required environment variables
DATABASE_URL=REPLACE_WITH_THE_DOCUMENTED_DATABASE_URL
NEXTAUTH_SECRET=REPLACE_WITH_A_LONG_RANDOM_VALUE
SALT=REPLACE_WITH_A_RANDOM_VALUE
ENCRYPTION_KEY=REPLACE_WITH_64_HEX_CHARS
CLICKHOUSE_URL=http://clickhouse:8123
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=REPLACE_WITH_A_RANDOM_VALUE
CLICKHOUSE_MIGRATION_URL=http://clickhouse:8123
CLICKHOUSE_CLUSTER_ENABLED=false
REDIS_CONNECTION_STRING=redis://default:REPLACE_WITH_A_RANDOM_VALUE@redis:6379
LANGFUSE_S3_EVENT_UPLOAD_BUCKET=langfuse-events| Variable | Description | How to generate |
|---|---|---|
NEXTAUTH_SECRET |
Required, used for NextAuth session encryption | openssl rand -base64 32 |
SALT |
Required, salts hashed API keys | openssl rand -hex 16 |
ENCRYPTION_KEY |
Required, exactly 64 hex characters (256 bits) | openssl rand -hex 32 |
CLICKHOUSE_URL |
ClickHouse HTTP endpoint (internal Docker network) | http://clickhouse:8123 |
CLICKHOUSE_MIGRATION_URL |
ClickHouse URL for migrations (can be same as above) | http://clickhouse:8123 |
CLICKHOUSE_CLUSTER_ENABLED |
Set to false for single-node deployments |
false |
REDIS_CONNECTION_STRING |
Redis connection for queues and caching | redis://default:...@redis:6379 |
Use the exact names and formats from the official release. Do not use the sample values from documentation in production, and never commit .env.
Disclaimer: The Docker Compose deployment is intended for testing and low-scale use. Production deployments should use the Kubernetes Helm chart or Terraform modules from the official Langfuse repository.
Validate and start the supplied project:
docker compose config
docker compose pull
docker compose up -d
docker compose psIf the release includes a separate migration command, run it exactly as documented before accepting traffic. Inspect the web, worker and database logs separately.
Step 4, Configuring the reverse proxy
Route langfuse.example.com to the langfuse-web service's private localhost port (port 3000) from the supplied Compose file. If you need direct access to MinIO for object management, route a subdomain to MinIO's port (9090). Let Caddy, Nginx or your platform proxy terminate HTTPS and preserve forwarded host and protocol headers.
Set NEXTAUTH_URL to the public HTTPS URL of your instance (https://langfuse.example.com). This is required for authentication callbacks to work correctly.
Keep ingestion, database and storage services on private networks. Open 80 and 443 in the firewall and test the certificate. Confirm that large trace payloads and long-running requests are not rejected by an overly small proxy body or timeout limit.
Step 5, First access and initial setup
Open the HTTPS hostname, create the first organization and generate a project key pair. Use the public key where the SDK expects it, but keep the secret key in server-side configuration. Send one test trace, add a prompt version and check that the trace and metadata appear in the dashboard.
Decide which fields can contain personal or confidential information. Mask or omit sensitive values at the instrumentation boundary rather than relying only on dashboard permissions.
Maintenance
Back up every persistent component listed by the current deployment, including analytical storage and encryption secrets. Set retention limits and monitor disk growth. Upgrade during a maintenance window, read migration notes and keep a tested rollback plan.
When ingestion fails, inspect proxy access logs, the web service, workers and the persistence layer in that order. Do not delete analytical data to solve an authentication or DNS problem.
Tools mentioned
Langfuse
โOpen-source tracing, prompt management and evaluation for LLM products.
Hobby: 50k usage units/month with 30-day retention; self-hosting the open-source edition is also free.