概要、背景
Azureの仮想マシンのインスタンスを立てて、生成AIアプリの監視OSSとして有名なLangfuseをdockerコンテナ上にセルフホストしてみる
Langfuse公式ドキュメントでもAWSやAzureなど各パブクラ用のVMにdocker composeでLangfuseホストする手順は既に公開されています。これを読んで理解できる人は下記の記事は不要かと思います。
クラウド慣れしてない初心者の方にもわかるようAzureリソースの作り方も含めた丁寧な説明+Langfuse公式ドキュメントに書いてない、私が実際にハマったポイントを反映した手順をご紹介できればと思います。
今回はLangfuse立てるところまでで、実際にLangfuseと生成AIアプリを連携して監視するところまでは解説しません。
そちらについては他の方の記事をご参照ください。
LangfuseのVMホストって何がいいの?SaaS版とか公式提供のIaCコード使えばよくない?
使い分けについては、こちらの記事にて分かりやすく説明されているのでご参考に。
私の個人的見解としては、VMセルフホストは、PoC検証などの本番環境でないスモールな構築かつ、法人プロジェクトなどで閉域ネットワーク内でホスティングしたい、という場合に特に有効かなと思います。
ただし今回ご紹介する手順はパブリックサブネット前提で、閉域ネットワーク(プライベートサブネット)での構築ではないのでご了承ください。閉域ネットワークで構築したい場合は、サブネットの設定変えて、NATゲートウェイでOutbound通信できるようにしたりPrivateLinkでAzure内のAI推論リソースとバックボーン通信できるようにする感じかなと。詳しくは割愛します。
余談ですが、公式提供のIaC版(Terraform)はk8sで本格運用という感じでかなりコスト高そうでした。DDoSプロテクション有効だったりAKSノードも高性能だったりで、あれをそのままの設定で1か月起動してたら数十万円ぐらい行きそうな感じなので明らかに個人開発用ではなさそうです。気を付けてください。(ChatGPT見積もり)
アーキテクチャ、セキュリティ設定
(準備中。図ができたら書きます)
手順
最初にこれからやる内容をざっくりとリストアップ
リソースグループ作成
↓
ネットワーク系のリソース作成(仮想NW、セキュリティグループ)
↓
仮想マシン(VM)作成、ログイン
↓
VM上でDockerセットアップ、環境変数やConfigの修正、起動
1. Azure リソース作成
※既にリソースグループや仮想NWなど作成済の方は適宜読み飛ばしてください。
※リソースの名前やアドレス空間は一例です。任意のものに読み替えてもらってもかまいません。
1.1 リソースグループ
Azure Portalにログイン。上の検索窓に「リソースグループ」と入力、出てきたものをクリック → 「作成」ボタンをクリック
- 名前:
rg-langfuse-lab
- リージョン: 任意
困ったらAzure公式サイトでVMとかの料金表見て、一番安そうなところを選んでおくとよいと思います。私はCentral US
にしました。
1.2 仮想ネットワークとサブネット
VMを立てる前に、VMインスタンスを収容するネットワークの箱を作る必要がある。
ポータル上検索窓で「仮想ネットワーク」と検索 → 「作成」ボタンをクリック
下記設定を入力していく。記載のない箇所はデフォルト値のままでよい。
入力完了したら下部「レビューと作成」ボタンを押し、
「検証に成功しました」と表示されたら「作成」ボタンをクリック。デプロイ完了を待つ。
項目 | 値 |
---|---|
仮想ネットワーク名 | vnet-langfuse |
リージョン | Central US |
サブネット | subnet-langfuse |
サブネットのアドレスサイズ | 10.0.1.0/24 |
▼サブネット追加の画面。「IPアドレス」タブ>「サブネットの追加」ボタンから開く。
1.3 ネットワーク セキュリティ グループ (NSG)
先ほど作った仮想ネットワークのサブネットに対し、通信可能なIPアドレスやポートのルールを定める。ここを設定しないと攻撃者からも不正アクセス可能になってしまい危険。
ポータル上検索窓で「ネットワーク セキュリティ グループ」と検索 → 「作成」ボタンをクリック
-
名前:
nsg-langfuse
、リージョンは同じものを選んで作成 -
完成したら、NSGのトップ画面に戻り、作ったNSGの名前をクリック。続いて左のタブの「設定」>「受信セキュリティ規則」をクリック
-
ここで、外部インターネットから先ほど作ったサブネット内にアクセス可能な通信のルール(インバウンドルール)を追加していく(下図)
「追加」をクリックすると、ルールを追加できるので、下記4つのルールを追加。記載していない箇所はデフォルトのままでよい。
- ソース:
My IP address
, サービス: SSH (22/tcp
) - ソース:
My IP address
, サービス: HTTP (80/tcp
) - ソース:
My IP address
, サービス: HTTPS (443/tcp
) - ソース:
My IP address
, サービス: CUSTOM, 宛先ポート範囲:3000
(開発用 Langfuse ポート)
以上4つの設定を追加したら、左タブの「設定」>「サブネット」をクリックし、上部の「関連付け」ボタンをクリック。先ほど作った仮想ネットワークとサブネットがプルダウンで選択できるので、選んだらOKをクリック。これで、VMを収容するネットワークはあなたのPCのIPからしかアクセスできなくなりました。
複数のIPアドレスからアクセスを許可したい場合は、上記設定にてソース: IP address
を選択し、アドレスを個別で複数追加するかレンジ帯で指定しましょう。不要になった穴あけ設定は忘れず削除すること。
今回は個人の自宅開発での検証レベルを想定し、IP絞って侵入リスクを低減する程度の簡易な手順をご紹介しましたが、これで「外部からの攻撃に対し完璧に強い」とまでは言い切れないです。
例えば、自分のPCのIPからしか接続許可していないとはいえ、自分のPCがマルウェア感染したりしたら終わりです。法人で使う本番環境などでは、Bastionなど踏み台サーバを用意し閉域ネットワーク化する、などより厳格なセキュリティ設定をするようにしましょう。
本記事の手順通り設定したうえで攻撃による被害を受けても、投稿者は一切の責任を負いません。
1.4 仮想マシン
ポータル上検索窓で「仮想マシン」と検索 → 「作成」ボタンをクリック
項目 | 値 |
---|---|
仮想マシン名 | vm-langfuse |
リージョン |
Central US (前と同じ値) |
可用性オプション | インフラストラクチャ上長は必要ありません |
セキュリティの種類 | Standard |
イメージ |
Ubuntu Server 24.04 LTS (Linux OSであればなんでもよい) |
サイズ |
Standard_B2s 以上推奨(2 vCPU / 4 GB RAM) |
管理者アカウント 認証の種類 |
パスワード |
パブリック受信ポート | 選択したポートを許可する |
受信ポートを選択 |
SSH , HTTP , HTTPS
|
※サイズ(CPUとメモリのスペック)については何とも言えないです。
実運用してみて後からより高いスペックにも変更可能なのでそこは柔軟に変更してみてください。
※VMログイン時の認証はSSH公開キーをお勧めします。今回はめんどくさかったのでパスワードにしましたがおすすめはしません。
上記が入力し終わったら、続いて「次:ディスク」ボタンをクリック。
VMにつけるSSDとかのディスクストレージの設定をしていきます。
項目 | 値 |
---|---|
OS ディスクの種類 | Standard SSD |
下部に(VM名)のデータ ディスクの欄があるので、「新しいディスクを作成し接続する」をクリック。
OSとは別にSSDを用意し、Langfuse実行時に使えるストレージ容量を作っておく。「サイズの変更」をクリック。
上部「ストレージの種類」でStandard SSD
を選択。
容量は今回はとりあえず32GiBとしましたが、ご自身の使用量に合わせて適切な値を選んでください。
上記が入力し終わったら、続いて「次:ネットワーク」ボタンをクリック。
VMを格納するネットワークの設定をします。といっても前手順でNWは作成済なのでそれを選ぶだけ。
項目 | 値 |
---|---|
仮想ネットワーク | vnet-langfuse |
サブネット | subnet-langfuse |
パブリックIP | (新規) |
NIC ネットワーク セキュリティ グループ | なし |
※ネットワークセキュリティグループはサブネット側で設定済なので、サブネット内のVMにもそのルールが適用されます。よって今回、VMのNICには設定不要です。
ここまで入力したら「確認および作成」の青ボタンをクリック。
「作成」ボタンを押して、リソースが作成できたら成功。
VMは、リソース作成完了後は起動済の状態になっており、課金され続けている状態です。作業を中断する場合は「停止」ボタンを押して課金を止めましょう。
1.5 ストレージアカウント、Blobストレージ
Langfuseでは、非構造化データのストレージが必須となっています。AWSでいうS3バケットみたいなやつ
ストレージアカウントという大枠の箱を作った後、非構造化ストレージのBlobストレージを作成します。
BlobストレージのことをAzureでは「コンテナ」という名称で表記していますが、Dockerコンテナを想起させて紛らわしいので、本記事ではBlob表記多めになっています。
ポータル上検索窓で「ストレージアカウント」と検索 → 「作成」ボタンをクリック。以下の値を入力していきます。
項目 | 値 |
---|---|
ストレージ アカウント名 | storagelangfuse20250907 |
リージョン | Central US |
冗長性 | ローカル冗長ストレージ(LRS) |
パブリック ネットワーク アクセス | 無効にする |
※ストレージアカウント名は他人と被ってはいけないので適当な数でも付け加えましょう。
作成後、左のタブから「データストレージ」>「コンテナ」メニューを開きます。上記の「コンテナーの追加」ボタンを押して名前を入力し、新しいコンテナ(Blobストレージ)作成します。
- 名前:
blob-langfuse
2. VM 初期設定
あなたのローカルPCからSSH接続で作業していきます。
SSH ログイン:
$ ssh <ユーザ名>@<VMのパブリックIP>
ユーザ名、パスワードは手順1. 4で作成したものを使用してください。
VMのパブリックIPは、VMの概要ページに書いてあります。
パッケージ更新 & Docker セットアップ:
# 0) 前提パッケージ
$ sudo apt-get update
$ sudo apt-get install -y ca-certificates curl gnupg lsb-release
# 1) 公式GPG鍵&APTレポ登録
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo tee /etc/apt/keyrings/docker.asc >/dev/null
$ sudo chmod a+r /etc/apt/keyrings/docker.asc
$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
| sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
$ sudo apt-get update
# 2) Docker本体+Compose v2(plugin)をインストール
$ sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 3) 起動&docker自動起動ON、権限
$ sudo systemctl enable --now docker
$ sudo usermod -aG docker $USER
$ newgrp docker
# 4) 動作確認
# 下記二つはバージョン表示されればOK
$ docker --version
$ docker compose version
$ docker run --rm hello-world
# 中段に、下記メッセージが表示されればOK。
# Hello from Docker!
# This message shows that your installation appears to be working correctly.
3. Langfuse 用ディレクトリ作成
mkdir ~/langfuse && cd ~/langfuse
4. .env
設定
~/langfuse/.env
を作成し以下を記載。
# --- PostgreSQL ---
# username:langadmin, DBname:langfuseの場合。
POSTGRES_USER=langadmin
POSTGRES_PASSWORD=<任意のパスワード>
POSTGRES_DB=langfuse
DATABASE_URL=postgresql://langadmin:<任意のパスワード>@postgres:5432/langfuse
# --- Redis ---
REDIS_HOST=redis://redis:6379
# --- ClickHouse ---
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=<任意のパスワード>
CLICKHOUSE_DB=langfuse
CLICKHOUSE_URL=http://clickhouse:8123
CLICKHOUSE_MIGRATION_URL=clickhouse://default:<任意のパスワード>@clickhouse:9000/langfuse
CLICKHOUSE_CLUSTER=
# --- Langfuse secrets ---
NEXTAUTH_SECRET=<opensslコマンド実行して生成した値をコピペ>
ENCRYPTION_KEY=<opensslコマンド実行して生成した値をコピペ>
SALT=<opensslコマンド実行して生成した値をコピペ>
# --- Hostname ---
NEXTAUTH_URL=http://<VMのパブリックIP>:3000
AUTH_TRUST_HOST=true
# --- Azure Blob Storage (ネイティブ) ---
LANGFUSE_USE_AZURE_BLOB=true
LANGFUSE_S3_EVENT_UPLOAD_BUCKET=langfuse
LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID=<ストレージアカウントの名前を入れる>
LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY=<ストレージアカウントのアクセスキーを入れる>
LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT=https://<ストレージアカウントの名前>.blob.core.windows.net
編集箇所
- PostgreSQLの
POSTGRES_PASSWORD
,DATABASE_URL
にはユーザが決めた任意のパスワードを入力 -
CLICKHOUSE_PASSWORD
,と、CLICKHOUSE_MIGRATION_URL
の文字列中にはユーザが決めた任意のパスワードを入力 -
NEXTAUTH_SECRET
,ENCRYPTION_KEY
,SALT
: 「opensslコマンド実行して生成した値をコピペ」の箇所は、openssl rand -hex 32
をターミナルで3回実行し、生成した値3つをそれぞれ入れること -
LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID
,LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT
: Azureのストレージアカウントの名前を入力 -
LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY
: ストレージアカウントのアクセスキーを入力
▼ストレージアカウントの名前はページの上部に書いてあります。アクセスキーは、左側タブの「セキュリティとネットワーク」>「アクセス キー」から見られます。
アクセスキーは、key1またはkey2の「キー」の表示ボタンを押してコピペしましょう。
余談ですが私は、この.env
の設定で何回やっても上手くいかず、かなりハマりました。
5. docker-compose.yml
公式サンプルをベースに ~/langfuse/docker-compose.yml
を作成:
services:
postgres:
image: postgres:15
restart: always
env_file:
- .env
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: valkey/valkey:7
restart: always
clickhouse:
image: clickhouse/clickhouse-server:24.8
restart: always
volumes:
- chdata:/var/lib/clickhouse
langfuse-web:
image: langfuse/langfuse:3
depends_on: [postgres, redis, clickhouse]
ports: ["3000:3000"]
env_file:
- .env
langfuse-worker:
image: langfuse/langfuse-worker:3
depends_on: [postgres, redis, clickhouse]
env_file:
- .env
volumes:
pgdata:
chdata:
Dockerコンテナ立ち上げ画面。
[+] Running 6/6
✔ Network langfuse_default Created 0.1s
✔ Container langfuse-clickhouse-1 Started 1.0s
✔ Container langfuse-postgres-1 Started 1.0s
✔ Container langfuse-redis-1 Started 0.9s
✔ Container langfuse-langfuse-web-1 Started 1.4s
✔ Container langfuse-langfuse-worker-1 Started 1.5s
6. 起動
docker compose up -d
動作確認:
docker compose ps
curl -I http://localhost:3000
HTTP/1.1 200 OK
が返れば成功 🎉
7. ブラウザアクセス
ChromeなどWEBブラウザで開く。
- URL:
http://<VMのパブリックIP>:3000
- 初回アクセス時にユーザー登録。
8. Dockerコンテナ停止と再起動時は
-
停止:下記コマンド実行後VMログアウトし、ポータルでVM停止
docker compose down
-
再起動:ポータルでVM起動。VMログインし、
docker-compose.yml
を作ったディレクトリに移動して下記コマンド実行docker compose up -d
9. この後やること
※今回は構築準備メインなので、実際のLangfuseの使い方や連携設定については割愛します。
- Langfuseの初期設定
- 監視したい生成AIアプリとの接続設定