---
title: "Dify Qdrant切り替え手順：1.19.0の.env設定とvdb-migrateによる既存ナレッジ移行"
url: "https://www.issoh.co.jp/tech/details/19493/"
published: 2026-11-08
updated: 2026-11-08
categories: ["データベース"]
publisher: "株式会社一創"
---

# Dify Qdrant切り替え手順：1.19.0の.env設定とvdb-migrateによる既存ナレッジ移行

DifyのナレッジをQdrantに載せるには、`docker/.env`で`VECTOR_STORE=qdrant`を指定し、`COMPOSE_PROFILES`にqdrantを加えてから`docker compose up -d`を実行します。Dify 1.19.0（2026-11-04公開）からはプロファイルが自動で連動しなくなり、変数1つを替えるだけの古い手順ではQdrantのコンテナが起動しません。この記事では、1.19.0の設定ファイル、同梱Qdrantと外部Qdrantへの接続、`flask vdb-migrate`による移行、コレクションの構造までを公式リポジトリのソースに沿って説明します。版番号は2026年11月8日時点の確認値です。

## まとめ：DifyをQdrantへ切り替える前に決める接続先と移行の範囲

最初に決めるのは「どのQdrantにつなぐか」です。Dify同梱のQdrantはイメージが`langgenius/qdrant:v1.8.3`で、Difyが固定しているqdrant-client 1.9.0と1マイナー差に収まります。2026年11月時点のQdrant最新系であるv1.20系へつなぐと、Qdrant公式が検証していない版差になります。

新規環境なら、`.env`に`VECTOR_STORE`と`COMPOSE_PROFILES`の2行を書けば同梱Qdrantで動きます。既存環境では、旧ストアのプロファイルを残したまま切り替え、`flask vdb-migrate`で高品質インデックスのナレッジだけを移します。

- 新規構築：`VECTOR_STORE=qdrant`と`COMPOSE_PROFILES=qdrant,postgresql,collaboration`を書き、既定のAPIキーを替える
- 既存移行：バックアップ、旧ストアのプロファイル維持、`vdb-migrate`、件数確認の順に進める
- 外部接続：qdrantプロファイルを外し、`QDRANT_URL`とAPIキーをルートの`.env`に書く

## Dify 1.19.0でベクトルストアを決める設定ファイルと値の優先順位

1.19.0では、`docker/.env`に置く値が手動設定の必要なものだけに絞られました。サービスごとの既定値は`docker/envs/`配下の`.defaults`ファイルに分かれ、Composeが自動で読み込みます。Difyのナレッジ機能そのものの作り方は[Difyでチャットボットを作る手順と社内ナレッジの設定](https://www.issoh.co.jp/tech/details/2758/)で扱っているので、ここでは検索基盤の差し替えに絞ります。

### 1.19.0のVECTOR\_STOREとCOMPOSE\_PROFILES両方の変更

1.18.0の[.env.example](https://github.com/langgenius/dify/blob/1.18.0/docker/.env.example)では、`COMPOSE_PROFILES=${VECTOR_STORE:-weaviate},${DB_TYPE:-postgresql},collaboration`と書かれ、`VECTOR_STORE`を替えればQdrantのコンテナも起動していました。1.19.0の[.env.example](https://github.com/langgenius/dify/blob/1.19.0/docker/.env.example)は`COMPOSE_PROFILES=weaviate,postgresql,collaboration`と値を直接書く形です。

この差を知らずに`VECTOR_STORE`だけ替えると、Weaviateのコンテナが動いたままQdrantは立ち上がりません。新しいナレッジの索引作成が失敗する原因は、接続先が無いことです。[1.19.0のリリースノート](https://github.com/langgenius/dify/releases/tag/1.19.0)は、ルートの`.env`を優先させる仕組みのためにDocker Compose v2.35.0以上を必須にしています。上げる前に`docker compose version`で版を確かめます。

### qdrant.defaultsの接続変数と既定鍵difyai123456の変更理由

Qdrantの接続設定は[envs/vectorstores/qdrant.defaults](https://github.com/langgenius/dify/blob/1.19.0/docker/envs/vectorstores/qdrant.defaults)にまとまっています。`VECTOR_STORE=qdrant`のときだけ、Composeがこのファイルをapi・worker・worker\_beatへ読み込ませます。

| 変数                          | 既定値                | 役割              |
| --------------------------- | ------------------ | --------------- |
| QDRANT\_URL                 | http://qdrant:6333 | Difyが接続する先      |
| QDRANT\_API\_KEY            | difyai123456       | クライアントとサーバーの共通鍵 |
| QDRANT\_CLIENT\_TIMEOUT     | 20                 | クライアントの待ち秒数     |
| QDRANT\_GRPC\_ENABLED       | false              | gRPC接続の有無       |
| QDRANT\_REPLICATION\_FACTOR | 1                  | 新規コレクションの複製数    |

同じファイルの末尾で`QDRANT__SERVICE__API_KEY`に`QDRANT_API_KEY`の値を写しているため、ルートの`.env`で`QDRANT_API_KEY`を1か所替えれば、Dify側とQdrant側の鍵がそろって変わります。既定値は公開リポジトリに載っている文字列なので、社内LANでも替えておきます。

### 同梱Qdrant v1.8.3とqdrant-client 1.9.0固定の互換範囲

1.19.0の[docker-compose.yaml](https://github.com/langgenius/dify/blob/1.19.0/docker/docker-compose.yaml)では、qdrantサービスのイメージが`langgenius/qdrant:v1.8.3`、保存先が`./volumes/qdrant`、ファイル記述子の上限が524288です。`ports`の指定は無く、ホストの外からは直接つながりません。

Dify側のクライアントは、[vdb-qdrantのpyproject.toml](https://github.com/langgenius/dify/blob/1.19.0/api/providers/vdb/vdb-qdrant/pyproject.toml)で`qdrant-client==1.9.0`に固定された構成です。Qdrant公式の[Upgrading Qdrant](https://qdrant.tech/documentation/upgrades/)は、SDKをサーバーの1マイナー以内に保つよう求め、それより大きな差は「動く場合もあるが検証していない」としています。同梱の1.8.3と1.9.0の組み合わせは、この範囲に収まっています。

## 新規環境で同梱Qdrantを起動しナレッジを作るまでのdocker compose手順

まだナレッジが1件も無い環境なら、移行の手間はかかりません。ここではPostgreSQLと同梱Qdrantを組み合わせる構成を例にします。Qdrant単体の起動や永続化の考え方は[Qdrant Dockerの構築手順](https://www.issoh.co.jp/tech/details/19488/)と共通です。

### .envの3行とdocker compose up -dによる同梱Qdrant起動

[docker/README.md](https://github.com/langgenius/dify/blob/1.19.0/docker/README.md)の例に、APIキーの差し替えを加えた形です。`docker/`ディレクトリで実行します。

```
# docker/.env（既存の行は残し、次の3行を書き換える・追記する）
VECTOR_STORE=qdrant
COMPOSE_PROFILES=qdrant,postgresql,collaboration
QDRANT_API_KEY=ここにopenssl rand -hex 32の出力を貼る

# 反映と状態確認
docker compose up -d
docker compose ps --all
```

Weaviateを一度も使っていなければ、プロファイルからweaviateを外してかまいません。README.mdのとおり`docker compose restart`は環境変数を読み直さないので、反映は必ず`up -d`で行います。`COMPOSE_PROFILES`と`VECTOR_STORE`はComposeがサービス別の設定より先に読むため、`qdrant.env`ではなくルートの`.env`に置きます。

### apiコンテナからQdrantのコレクション一覧と件数を確かめるコード

同梱Qdrantはポートを公開していないため、ホストからcurlでは届きません。apiコンテナに入っているqdrant-clientを使えば、Difyと同じ経路で接続を確かめられます。

```
docker compose exec -T api python - <<'EOF'
import os
from qdrant_client import QdrantClient

client = QdrantClient(url=os.environ["QDRANT_URL"], api_key=os.environ.get("QDRANT_API_KEY"))
for col in client.get_collections().collections:
    print(col.name, client.count(col.name, exact=True).count)
EOF
```

ナレッジに文書を入れた後なら、`Vector_index_`で始まり`_Node`で終わる名前が並びます。命名は[models/dataset.py](https://github.com/langgenius/dify/blob/1.19.0/api/models/dataset.py)の`gen_collection_name_by_id`で、ナレッジIDのハイフンをアンダースコアに置き換えた文字列です。件数が0のままなら、apiとworkerが`VECTOR_STORE=qdrant`を受け取っているかを先に疑います。

## 外部Qdrant ServerやQdrant CloudへのDify接続設定と版の注意

Qdrantを別サーバーやマネージドサービスで運用し、Difyから接続だけする構成もとれます。マネージド版のクラスタ作成とAPIキー発行は[Qdrant Cloudの使い方](https://www.issoh.co.jp/tech/details/19490/)で手順を説明しています。

### qdrantプロファイルを外してQDRANT\_URLとAPIキーをルートに書く設定例

[DifyのEnvironment Variables](https://docs.dify.ai/en/self-host/deploy/configuration/environments)は、外部サーバーを使うときは同梱のプロファイルを外し、接続設定を渡すよう案内しています。

```
# docker/.env（外部Qdrantへ接続する例）
VECTOR_STORE=qdrant
COMPOSE_PROFILES=postgresql,collaboration
QDRANT_URL=https://qdrant.example.internal:6333
QDRANT_API_KEY=外部Qdrantで発行したキー
# 必要な場合のみ
# QDRANT_CLIENT_TIMEOUT=60
```

認証を設けていない外部サーバーなら、`QDRANT_API_KEY`を空にするのが、同ページに記載された設定方法です。Qdrant側は[Security & Access Control](https://qdrant.tech/documentation/security/)のとおり、`api-key`ヘッダーで鍵を受け取ります。社外のネットワークを通すなら、URLは`https`にして鍵を平文で流さない構成にします。

### v1.20系サーバーへqdrant-client 1.9.0でつなぐときの検証範囲

外部のQdrantをv1.20系で立てると、Difyのクライアント1.9.0とは11マイナーの差になります。Qdrant公式の互換方針では未検証の領域です。Dify側のコードは`create_collection`、`upsert`、`search`、ペイロード索引の作成という基本操作に限られますが、動くことは自分の環境で確かめるしかありません。

検証するなら、ナレッジの作成、文書追加、検索テスト、文書削除、ハイブリッド検索の5操作を通します。サーバーの版を上げるたびに同じ確認を繰り返す運用になる点も、構成を選ぶ時点で織り込んでおきます。

## WeaviateからQdrantへのナレッジ移行とflask vdb-migrate実行

運用中のDifyでは、`VECTOR_STORE`を替えても作成済みナレッジの索引は動きません。README.mdは、既存のナレッジが保存済みの接続先を使い続けると説明しています。索引をQdrantへ移すのが`flask vdb-migrate`です。

### 移行前のバックアップとWeaviateのプロファイルを残す理由

1.19.0のリリースノートは、データベース、ベクトルストアのデータ、アップロード済みファイル、環境設定ファイルを先に退避するよう求めています。Docker Composeの構成なら`docker/volumes/`配下と`.env`群が対象です。ファイルの保存先の扱いは[DifyのストレージをAmazon S3に切り替える設定手順](https://www.issoh.co.jp/tech/details/4131/)で詳しく触れています。

切り替えの間は、旧ストアのプロファイルを外しません。Difyのドキュメントは、旧ストアがWeaviate以外なら、その`.defaults`を`.env`へコピーしておかないと既存ナレッジの接続が切れると注意しています。Weaviateの接続既定値は[api-worker.defaults](https://github.com/langgenius/dify/blob/1.19.0/docker/envs/core-services/api-worker.defaults)に残してあるため、Weaviateからの移行ではコピーは要りません。

```
# docker/.env（移行期間中）
VECTOR_STORE=qdrant
COMPOSE_PROFILES=weaviate,qdrant,postgresql,collaboration
```

### flask vdb-migrateの–scope指定と移行対象になるナレッジの条件

[DifyのStorage & Migration](https://docs.dify.ai/en/self-host/deploy/troubleshooting/storage-and-migration)は、Dockerでの実行例として`docker exec -it docker-api-1 flask vdb-migrate`を示し、検証済みの移行先にQdrantを挙げています。Compose経由なら次のように書けます。

```
# ナレッジだけを移す（既定はall＝ナレッジと注釈返信の両方）
docker compose exec api flask vdb-migrate --scope knowledge

# 注釈返信の索引も移す
docker compose exec api flask vdb-migrate --scope annotation
```

[commands/vector.py](https://github.com/langgenius/dify/blob/1.19.0/api/commands/vector.py)を読むと、対象はインデックス方式が「高品質」のナレッジだけです。「経済的」はベクトルを持たないので移りません。すでに索引の種別が`qdrant`のナレッジは飛ばされます。文書は索引作成が完了し、有効で、アーカイブされていないものに限られます。

移行はナレッジ単位で、移行先の索引をいったん削除してから作り直す順です。途中で失敗したナレッジはロールバックされ、次のナレッジへ進みます。出力の`created`と`skipped`の件数を控えておくと、後の確認で役に立ちます。

### 埋め込みAPIが再び呼ばれるかはembeddingsテーブルの記録で決まる

移行は保存済みのベクトルをコピーするのではなく、セグメントの本文を埋め込みモデルに通して登録し直します。[vector\_factory.py](https://github.com/langgenius/dify/blob/1.19.0/api/core/rag/datasource/vdb/vector%5Ffactory.py)の`create`は、1,000件ずつ`embed_documents`を呼んでから書き込みます。

ここで効くのが[cached\_embedding.py](https://github.com/langgenius/dify/blob/1.19.0/api/core/rag/embedding/cached%5Fembedding.py)です。PostgreSQLの`embeddings`テーブルに同じモデル名と本文ハッシュの行があれば、それを使い回します。記録が無い本文の分だけ埋め込みAPIを呼ぶので、課金が発生するかどうかはこのテーブルの中身しだいです。移行前に行数と、ナレッジに設定したモデル名が一致しているかを見ておきます。

### ナレッジ移行後にWeaviateを止めてよいかを判断する確認手順

次の順で確かめ、すべて満たしてからプロファイルからweaviateを外します。

1. `vdb-migrate`の出力で、失敗を示す赤字の行が無いことを確かめる
2. 前述のコードで、ナレッジの数と同じ数の`Vector_index_`コレクションがあることを確かめる
3. 主要なナレッジで検索テストを実行し、移行前と同じ文書が上位に出るかを見る
4. `COMPOSE_PROFILES`からweaviateを外して`docker compose up -d`し、検索テストをもう一度通す

Weaviateの`volumes`はすぐに消さず、1〜2週間は残しておきます。戻すときは`VECTOR_STORE=weaviate`に替えて同じコマンドを流せば、種別が違うナレッジとして再び移せます。Weaviate自体の版上げを先に済ませる必要がある場合は、[EC2上のDifyで1.16系から上げるときのWeaviate段階移行](https://www.issoh.co.jp/tech/details/2725/)を参考にしてください。

## DifyがQdrantに作るコレクション構造とgroup\_idフィルタの読み方

DifyのQdrantは、Difyの画面から使う限り中身を意識する必要はありません。ただし、同じQdrantを他のアプリやMCPサーバーからも読む構成では、Difyの作り方を知らないと検索が遅くなります。

### ナレッジごとのコレクションとm=0・payload\_m=16のHNSW設定

[qdrant\_vector.py](https://github.com/langgenius/dify/blob/1.19.0/api/providers/vdb/vdb-qdrant/src/dify%5Fvdb%5Fqdrant/qdrant%5Fvector.py)は、コレクション作成時にHNSWを`m=0`、`payload_m=16`、`ef_construct=100`にする設定です。さらに`group_id`、`doc_id`、`document_id`のキーワード索引と、本文の全文索引（トークナイザーはmultilingual、2〜20文字）を張ります。各点の`group_id`にはナレッジIDが入ります。

Qdrant公式の[Configure Multitenancy](https://qdrant.tech/documentation/manage-data/multitenancy/)によると、`m=0`はコレクション全体のグラフを作らない指定です。`payload_m`を正の値にすると、作成されるのは、ペイロードの値ごとに分かれた個別のグラフです。DifyはテナントのIDを`group_id`に入れて分ける、公式どおりの構成をとっています。グラフの`m`や`ef_construct`の意味は[HNSWの仕組みとM・ef\_constructionの決め方](https://www.issoh.co.jp/tech/details/16468/)で説明しています。

### Difyの外からコレクションを検索するときにgroup\_idを外す落とし穴

同じMultitenancyのページには、`group_id`で絞らない全体検索は全グループをなめるため遅くなると書かれています。Difyのコレクションを別のPythonアプリから検索するなら、`group_id`が一致する条件をフィルタに必ず入れます。

Claude CodeなどからQdrantを記憶ストアとして使う[Qdrant MCPの設定](https://www.issoh.co.jp/tech/details/19491/)では、MCPサーバーが独自の名前付きベクトルを使います。Difyのコレクションとは形が違うため、同じコレクションを共用せず、コレクションを分けて置くほうが安全です。

## Qdrantへ切り替えるべきDify環境とWeaviateのままでよい場面の判断

切り替えは手段であって、目的ではありません。ここでは、移す価値がある条件と、やめておく条件を具体的に挙げます。

### DifyをQdrantへ移す価値がある条件と移行を見送るべき構成

移す価値があるのは、すでにQdrantを社内の別システムで運用していて、バックアップや監視の手順を一本化できる場合です。Qdrantの[スナップショット](https://qdrant.tech/documentation/snapshots/)でナレッジの索引も同じ手順で退避できるようになり、運用の窓口が1つ減ります。

見送るべきなのは、Weaviateで困っていない小規模な環境です。Dify 1.19.0の既定はWeaviateです。不満が具体的に無いまま移すと、移行と検証の工数だけが残ります。

もう1つ、同梱Qdrantで始めて後から最新系に上げる計画はおすすめしません。Upgrading Qdrantは、各中間マイナーの最新パッチを順に経由するよう求めており、1.8系から1.20系までは12回の段階更新になります。`vdb-migrate`は同じ`qdrant`種別のナレッジを飛ばすため、Qdrant同士の移し替えには使えません。最新系で運用したいなら、最初から外部Qdrantに決めて検証するほうが手戻りが少なく済みます。

PostgreSQLにまとめたいなら[DifyのベクトルストアをpgvectorにするDocker設定](https://www.issoh.co.jp/tech/details/6231/)、製品の違いから整理したいなら[ベクトルDBの仕組みと製品比較](https://www.issoh.co.jp/tech/details/7691/)と比べてください。

### RAG基盤の組み替えで外部に任せる作業と社内で決めておく判断範囲

ベクトルストアの切り替えは、設定ファイル2行の変更に見えて、バックアップ、埋め込みコスト、検索精度の比較、旧ストアの撤去判断までがひとまとまりです。社内で決めておくべきなのは、どのナレッジを移すか、検索結果の良し悪しを誰がどの質問で判断するか、の2点です。

手順の実行と検証の自動化、Weaviateとの検索結果の比較は外部に任せやすい作業です。ナレッジの分割方法や[ハイブリッド検索の組み合わせ方](https://www.issoh.co.jp/tech/details/8014/)まで含めて見直す場合は、[RAG構築支援](https://www.issoh.co.jp/service/ai/rag/)でDifyの構成診断から相談を受けています。

## よくある質問

DifyとQdrantの組み合わせで、実際によく調べられている疑問をまとめました。

### DifyでQdrantを使う設定は管理画面からできますか？

セルフホスト版のDifyでは、ベクトルストアは管理画面ではなく環境変数で決めます。`docker/.env`の`VECTOR_STORE`と`COMPOSE_PROFILES`を書き換え、`docker compose up -d`で反映します。画面で選べるのはナレッジごとのインデックス方式と検索方式で、Qdrantの接続先やAPIキーの項目はありません。

### Difyに同梱のQdrantを最新版のイメージへ差し替えられますか？

イメージのタグを書き換えれば起動自体は試せますが、二つの理由からおすすめしません。1つは、Qdrant公式の更新手順が中間のマイナー版を1つずつ経由するよう求めており、1.8系から一気に上げられないことです。もう1つは、Difyのクライアントが1.9.0に固定されていて、新しいサーバーとの組み合わせが未検証になることです。最新系を使いたいなら、外部Qdrantとして立てて検証します。

### QdrantからWeaviateやpgvectorへ戻すことはできますか？

できます。`VECTOR_STORE`を戻したい種別に替え、そのプロファイルを`COMPOSE_PROFILES`に入れてから`flask vdb-migrate`を実行します。移行コマンドは「現在の`VECTOR_STORE`と索引の種別が違うナレッジ」を対象にするため、向きは問いません。このときQdrantの接続が切れないよう、`qdrant.defaults`を`qdrant.env`へコピーしておきます。

### DifyのハイブリッドはQdrantでも使えますか？

Qdrantでもハイブリッド検索を利用できます。Difyの`qdrant_vector.py`はベクトル検索と全文検索の両方を実装しており、コレクション作成時に張る索引には本文の全文索引も含まれる仕様です。ナレッジの検索設定でハイブリッドを選べば、検索結果はベクトル検索と全文検索の両方を組み合わせたものです。全文索引のトークナイザーはmultilingualで、最短2文字・最長20文字のトークンだけを索引に入れます。社内用語や型番が狙いどおりに引けるかは、ナレッジの検索テストで確かめてから本番に使います。

### Qdrantのダッシュボードで、Difyが登録したデータを見られますか？

同梱Qdrantは`ports`を公開していないため、そのままではブラウザから開けません。本記事のPythonコードのようにapiコンテナ経由で件数を見るほうが安全です。ダッシュボードが必要なら、`docker-compose.override.yaml`で`127.0.0.1:6333`だけに公開し、外部から届かない形にとどめます。

## 関連記事

- [Qdrant Dockerの構築手順](https://www.issoh.co.jp/tech/details/19488/)：Difyの外にQdrantを立てるときの永続化とAPIキー設定
- [Qdrant Cloudの使い方](https://www.issoh.co.jp/tech/details/19490/)：外部接続先をマネージド版にする場合のクラスタ作成と料金の増え方
- [pgvectorとは？インストール手順と使い方](https://www.issoh.co.jp/tech/details/6231/)：Difyのベクトルストアをpgvectorにする選択肢
- [DifyをHelm chartでAWS EKSに構築する手順](https://www.issoh.co.jp/tech/details/7097/)：Kubernetes上のDifyで外部ベクトルストアを使う構成
- [RAG構築の手順](https://www.issoh.co.jp/column/details/12920/)：検索基盤を差し替えた後の精度改善と本番運用の進め方

---

出典: [Dify Qdrant切り替え手順：1.19.0の.env設定とvdb-migrateによる既存ナレッジ移行](<https://www.issoh.co.jp/tech/details/19493/>)（株式会社一創）
