はじめに
GAOの遠矢です。普段はLLMアプリケーションの開発を主にしております。
このガイドでは、LangfuseというLLMOpsの基盤となるツールをGoogle Cloud上でセルフホスティングする手順を紹介します。Google Cloud上のKubernetes (GKE) でLangfuse v3を安全かつ推奨される構成でデプロイする手順を解説します。
V3では以下のような重要な改善が行われています
アーキテクチャの最適化
キューに入れられたトレースの取り込み
トレースはバッチ処理され、S3に直接保存
APIキーのキャッシュング
Redisを活用した高速なAPI認証
プロンプトのキャッシュ(SDK・API)
リードスルーキャッシュによる応答時間の改善
OLAPデータベース(ClickHouse)の採用
分析処理の高速化
信頼性の向上
S3/Blobストレージを活用したイベントの回復可能性
バックグラウンド移行のサポート
マルチモーダルトレースのサポート
コンポーネント構成
アプリケーションコンテナ(Web・Worker)
ストレージコンポーネント(Postgres, ClickHouse, Redis/Valkey, S3/Blob)
オプショナルなLLM API/ゲートウェイ
注記: この手順はLangfuse v3のデプロイに焦点を当てています。v2のデプロイについては、v2のドキュメントを参照してください。
注意事項: 本番環境で使用する前に、セキュリティとパフォーマンスを考慮して構成を見直すことを強く推奨します。
システム要件と構成
アーキテクチャ図
推奨構成
GKE(コンテナアプリケーション)
2つのCPUと4 GB の RAM
高可用性を実現するには、Langfuse Web コンテナのインスタンスを少なくとも 2 つ
Cloud SQL(PostgreSQL)
特に指定なし
Redis
1GB以上
ClickHouse:
3レプリカ構成
Cloud Storage(S3)
特に指定なし
注意事項: 今回はClickhouseをGKE上に構築する場合の手順のため、GKEノード(GCE)のマシンスペックが低いとClickhouseを構築できない可能性があるためご注意ください。
構築手順
本手順では、主にターミナルを利用して構築を行います。
構築準備
まず、Google Cloudプロジェクトの設定から始めます。
以下のコマンドでプロジェクトを設定します。
gcloud config set project [YOUR_PROJECT_ID]
ネットワークインフラの構築
セキュアな環境を構築するため、専用のVPCネットワークとサブネットを作成します。
これにより、リソース間の安全な通信が可能になります。
# VPCネットワークの作成
gcloud compute networks create langfuse-network --subnet-mode=custom
# サブネットの作成
gcloud compute networks subnets create langfuse-subnet \
--network=langfuse-network \
--region=asia-northeast1 \
--range=10.0.0.0/20
# VPCピアリングの設定
gcloud compute addresses create google-managed-services-range \
--global \
--purpose=VPC_PEERING \
--prefix-length=16 \
--network=langfuse-network
gcloud services vpc-peerings connect \
--service=servicenetworking.googleapis.com \
--ranges=google-managed-services-range \
--network=langfuse-network
# 内部通信用のファイアウォールルール
gcloud compute firewall-rules create langfuse-allow-internal \
--network=langfuse-network \
--allow=tcp,udp,icmp \
--source-ranges=10.0.0.0/20
Kubernetesクラスターの構築
GKEクラスターを作成します。
本番環境では可用性を考慮して、複数のノードを配置することを推奨します。
gcloud container clusters create langfuse-cluster \
--network=langfuse-network \
--subnetwork=langfuse-subnet \
--region=asia-northeast1 \
--num-nodes=1~2 \
--machine-type=e2-standard-2 \
--enable-ip-alias
# 認証設定
gcloud container clusters get-credentials langfuse-cluster --region=asia-northeast1
PostgreSQLデータベースをCloud SQLで構築します。本番環境では十分なリソースと冗長性を確保することが重要です。
パスワード等は本来であれば、シークレット等で管理してください。
# PostgreSQL作成
gcloud sql instances create langfuse-postgres \
--database-version=POSTGRES_15 \
--tier=db-g1-small \
--region=asia-northeast1 \
--root-password=[YOUR_ROOT_PASSWORD] \ # 今回設定する箇所は特にないので任意で
--database-flags=max_connections=100 \
--network=langfuse-network \
--no-assign-ip
# データベース作成
gcloud sql databases create langfuse --instance=langfuse-postgres
# ユーザの作成
gcloud sql users create langfuse --instance=langfuse-postgres --password=langfuse1234
また、プライベートIPはこの後Langfuse側で設定する必要があるのでメモしておいてください。
# プライベートIPの取得
gcloud sql instances describe langfuse-postgres \
--format="get(ipAddresses[0].ipAddress)
Redisをマネージドサービスである、Memorystore for Redisを利用して構築を行います。
しかし、コスト等の兼ね合いがある場合マネージドサービスを利用せずコンテナ上で構築することも可能です。
# Redisインスタンスの作成
gcloud redis instances create langfuse-redis \
--size=1 \
--region=asia-northeast1 \
--redis-version=redis_7_0 \
--network=langfuse-network \
--enable-auth \
--redis-config maxmemory-policy=noeviction
Redisでは、認証用の文字列(REDIS_AUTH)、ホスト(REDIS_HOST)、ポート(REDIS_PORT)をこの後Langfuse側で設定する必要があるので、メモしておいてください
# Redis認証文字列の取得
gcloud redis instances get-auth-string langfuse-redis --region=asia-northeast1
# Redisホストの取得
gcloud redis instances describe langfuse-redis \
--region=asia-northeast1 \
--format="get(host)"
# Redisポートの取得
gcloud redis instances describe langfuse-redis \
--region=asia-northeast1 \
--format="get(port)"
# バケットの作成
gcloud storage buckets create gs://$BUCKET_NAME \
--location=asia-northeast1
HMAC キーの作成手順
Cloud Storage > 設定 > 相互運用性タブに移動
サービスアカウント or ユーザーアカウントを選択しHMACキーを作成します。
アクセスキーとシークレットを安全に保存(これらは後でLangfuseの設定で使用)
今回はGKE上にClickHouseをデプロイする手法で行います。
# Helmのインストール
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Helmリポジトリの追加
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
次に以下のclickhouse-values.yamlを作成します。
shards: 1
replicaCount: 3
auth:
username: default
password: changeme
resourcesPreset: large
persistence:
size: 100Gi
shards: シャード数(この場合は1)
replicaCount: レプリカ数(本番では3以上推奨)
YAML作成後、Clickhouseのデプロイを行います。
helm install clickhouse bitnami/clickhouse \
-f clickhouse-values.yaml \
--namespace default
その後以下のコマンドで、正常に起動することを確認します。
# Podの状態確認
kubectl get pods | grep clickhouse
# サービスの確認
kubectl get svc -l app.kubernetes.io/name=clickhouse
# ログの確認
kubectl logs clickhouse-0
# デプロイされたリソース一覧の確認
kubectl get all -l app.kubernetes.io/name=clickhouse
# Langfuseリポジトリのクローン
git clone https://github.com/langfuse/langfuse-k8s.git
cd langfuse-k8s/charts/langfuse
git checkout lfe-1348-v3-chart
リポジトリをクローン後、以下の内容でlangfuse-values.yamlを作成してください。
また、その際に変数等は適宜変更してください。
langfuse-values.yaml
replicaCount: 1
image:
repository: langfuse/langfuse
pullPolicy: Always
tag: 3
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
langfuse:
port: 3000
nodeEnv: development
next:
healthcheckBasePath: ""
nextauth:
url: "http://localhost:3000"
secret: "openssl rand -base64 32で作成"
salt: "openssl rand -base64 32で作成"
telemetryEnabled: true
nextPublicSignUpDisabled: false
enableExperimentalFeatures: true
extraContainers: []
extraVolumes: []
extraInitContainers: []
extraVolumeMounts: []
web:
replicas: 1
worker:
replicas: 1
additionalEnv:
- name: "LANGFUSE_LOG_FORMAT"
value: "json"
# Experimental v3 feature flags
- name: "LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES"
value: "true"
- name: "ENCRYPTION_KEY"
value: "openssl rand -hex 32で作成"
- name: "LANGFUSE_ASYNC_INGESTION_PROCESSING"
value: "true"
- name: "LANGFUSE_ASYNC_CLICKHOUSE_INGESTION_PROCESSING"
value: "true"
- name: "LANGFUSE_READ_DASHBOARDS_FROM_CLICKHOUSE"
value: "true"
- name: "LANGFUSE_READ_FROM_POSTGRES_ONLY"
value: "false"
- name: "LANGFUSE_RETURN_FROM_CLICKHOUSE"
value: "true"
# Database connections
- name: DATABASE_URL
value: "postgresql://langfuse:langfuse1234@[DB_IP]:5432/langfuse"
- name: "REDIS_HOST"
value: "[REDIS_HOST]"
- name: "REDIS_PORT"
value: "[REDIS_PORT]"
- name: "REDIS_AUTH"
value: "[REDIS_AUTH]"
- name: "CLICKHOUSE_URL"
value: "http://clickhouse:8123"
- name: "CLICKHOUSE_MIGRATION_URL"
value: "clickhouse://clickhouse:9000"
- name: "CLICKHOUSE_USER"
value: "default"
- name: "CLICKHOUSE_PASSWORD"
value: "changeme"
- name: CLICKHOUSE_CLUSTER_ENABLED
value: "false"
# Cloud Storage settings
- name: "LANGFUSE_S3_EVENT_UPLOAD_ENABLED"
value: "true"
- name: "LANGFUSE_S3_EVENT_UPLOAD_BUCKET"
value: "[BUCKET_NAME]"
- name: "LANGFUSE_S3_EVENT_UPLOAD_REGION"
value: "auto"
- name: "LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID"
value: "[HMAC_ACCESS_KEY]"
- name: "LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY"
value: "[HMAC_SECRET_ACCESS_KEY]"
- name: "LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT"
value: "https://storage.googleapis.com"
- name: "LANGFUSE_S3_EVENT_UPLOAD_FORCE_PATH_STYLE"
value: "true"
- name: "LANGFUSE_S3_EVENT_UPLOAD_PREFIX"
value: "events/"
serviceAccount:
create: true
annotations: {}
name: ""
podAnnotations: {}
podSecurityContext: {}
securityContext: {}
service:
enabled: true
type: NodePort
port: 3000
targetPort: 3000
ingress:
enabled: false # ローカル環境では無効化
resources: {}
autoscaling:
enabled: false
nodeSelector: {}
tolerations: []
affinity: {}
postgresql:
deploy: false # 外部PostgreSQLを使用
auth:
username: "langfuse"
password: "langfuse1234"
database: "langfuse"
clickhouse:
deploy: false # 外部Clickhouseを使用
valkey:
deploy: false
minio:
deploy: false # 外部ストレージを使用
extraManifests: []
主に変更する箇所は以下です。
パラメータ | 作成方法/説明 |
nextauth.secret | openssl rand -base64 32で作成 |
salt | openssl rand -base64 32で作成 |
ENCRYPTION_KEY | openssl rand -hex 32で作成 |
[DB_IP] | PostgreSQLデータベースのIPアドレス |
[REDIS_HOST] | Redisサーバーのホスト名 |
[REDIS_PORT] | Redisサーバーのポート番号 |
[REDIS_AUTH] | Redisの認証パスワード |
[BUCKET_NAME] | Cloud Storageのバケット名 |
[HMAC_ACCESS_KEY] | Cloud StorageアクセスのHMACアクセスキー |
[HMAC_SECRET_ACCESS_KEY] | Cloud StorageアクセスのHMACシークレットキー |
LANGFUSE_EE_LICENSE_KEY | Langfuse Enterprise プランのライセンスキー(オプション) ない場合は特に追加の必要なし |
以下のコマンドでhelmでLangfuseをlangfuse-values.yamlに沿って作成します。
# Langfuseのデプロイ
helm dependency update
helm install langfuse . -f langfuse-values.yaml
デプロイができたら、以下のコマンドでログとポッドの状態を確認します。
# podの状態確認
kubectl get pods -l app.kubernetes.io/instance=langfuse
# ログの確認
kubectl logs -f deployment/langfuse-web
kubectl logs -f deployment/langfuse-worker
どちらとも起動することを確認したら、ポートフォワーディングをして、localhost:3000でLangfuseのログイン画面が出力されることを確認します。
ポートフォワーディングのコマンド
# ポートフォワーディングの設定
kubectl port-forward svc/langfuse-web 3000:3000
その後、トレースなどを行い動作に問題がないか確認したらデプロイ完了です。
応用編 (外部IP付与 GCLB)
GoogleのGlobal Load Balancerを利用して、HTTPS通信を可能にします。 まずは、Google マネージドのSSL証明書を作成します。
以下のmanaged-cert.yamlを作成します。
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: langfuse-cert
spec:
domains:
- YOUR_DOMAIN # 実際のドメインに変更
その後マネージド証明書の適用を行います。
# マネージド証明書の適用
kubectl apply -f managed-cert.yaml
次に外部IPアドレスを予約しておきます
# 静的外部IPアドレスの予約
gcloud compute addresses create langfuse-ip --global
ここで予約したIPアドレスを DNS の A レコードとして設定してください。
次に、langfuse-values.yamlを更新します。 主な変更点としては環境変数の更新・追加とIngressの追加を行います。
# 主な更新箇所のみ抜粋
langfuse:
nextauth:
url: "https://YOUR_DOMAIN" # 外部アクセス用のドメインに更新
additionalEnv:
- name: "LANGFUSE_CSP_ENFORCE_HTTPS"
value: "true" # HTTPSを強制的に使用
# 新規追加のIngress設定
ingress:
enabled: true
annotations:
kubernetes.io/ingress.global-static-ip-name: langfuse-ip
networking.gke.io/managed-certificates: langfuse-cert
kubernetes.io/ingress.class: "gce"
kubernetes.io/ingress.allow-http: "false"
hosts:
- host: YOUR_DOMAIN
paths:
- path: /
pathType: Prefix
Langfuseの更新
# Langfuseの更新
helm upgrade langfuse . -f langfuse-values.yaml
確認コマンド
# 証明書の状態確認
kubectl describe managedcertificate
# AtiveになったらOK
# ロードバランサーの確認
kubectl get ingress
# HOST名が設定したドメイン名、アドレスが langfuse-ipの値になってたらOK
# GUIでGCLBが作成できるかどうかも確認
以上の設定が完了したら、https://YOUR_DOMAINにアクセスして、LangfuseUIにログインできたら成功です。 トレースなどができるか確認してみてください。
できない場合は helm unistallなどをしてください また、以下の画面はenterpriseEditionのライセンスキーの有効化を行なっているため、左上がv3.2.0 EEとなっています。
EEとなっており、Playground等の機能も画面に出力されている状態になっております。
クリーンアップ
必要に応じて、以下の手順でリソースを削除します
# Langfuseの削除
helm uninstall langfuse
helm uninstall clickhouse
# GKEクラスターの削除
gcloud container clusters delete langfuse-cluster \
--region=asia-northeast1 \
--async
# Cloud SQLインスタンスの削除
gcloud sql instances delete langfuse-postgres
# Redisインスタンスの削除
gcloud redis instances delete langfuse-redis \
--region=asia-northeast1
# Cloud Storageバケットの削除
gsutil rm -r gs://$BUCKET_NAME
# ファイアウォールルールの削除
gcloud compute firewall-rules delete langfuse-allow-internal
# VPCピアリング接続の削除
gcloud services vpc-peerings disconnect \
--service=servicenetworking.googleapis.com \
--network=langfuse-network
# 予約したIPレンジの削除
gcloud compute addresses delete google-managed-services-range \
--global
# サブネットの削除
gcloud compute networks subnets delete langfuse-subnet \
--region=asia-northeast1
# VPCネットワークの削除
gcloud compute networks delete langfuse-network
トラブルシューティング
Redis接続エラーについて
"Redis connection error: ERR unknown command 'client'"という警告は、Google CloudのMemoryStoreの制限によるものです。
この警告は表示されても、Redisとの接続自体は正常に行われています。
証明書のプロビジョニング
マネージド証明書のプロビジョニングには数分から数十分かかる場合があります。
kubectl describe managedcertificate で状態を確認できます。
注意事項
すべてのパスワードとシークレットは適切に管理してください。
本番環境ではより強力なセキュリティ設定と、より多くのリソースを割り当てることを検討してください。
環境変数の値は実際の値に置き換えてください。
Langfuseの公式ドキュメントも参照し、最新の情報を確認してください。
最後に
このガイドが、Google Cloud上でのLangfuse v3の安全なデプロイに役立つことを願っています。
また企業向けサポートとして、ガオ株式会社を通じてLangfuse ProおよびEnterpriseプランを日本円で購入し、日本語でサポートを受けることが可能です。
ご興味ある方は、contact@gao-ai.comまでご連絡ください。
Comments