オープンソースのLLMアプリ開発プラットフォームのDifyをApple MシリーズのMacbook Proにインストールします。インストールにあたって、ベクトル・ストアとしてOracle Database 23ai Freeを使用します。ベクトル検索の確認にはエンべディングの生成が必要ですが、それにはローカルで実行しているOllamaを呼び出します。
2025年7月14日追記 - Dify 1.6.0を使用した手順に更新しました。
ベクトル・ストアとして、すでにAPEX向けに作成したワークスペース・スキーマを使用します。DifyのDocker Composeはデフォルトで、Oracle Database 23ai Freeのコンテナを新規作成します。docker-compose.yamlのoracleのprofilesの設定をoracleからoracle-skipへ変更することにより、すでに作成済みのスキーマへの接続に切り替えることができます。
謝辞:oracle-skipの設定については、以下の記事を参考にしています。
DifyでOracle Base Database Service(23ai)を利用する設定手順
以下より、Difyを動かすまでに行った作業を紹介します。作業を行ったマシンは、M4を積んだApple Macbook Pro、OSはmacOS Sequoia 15.5です。
概ね以下のDifyのドキュメントの記載に従って作業を行います。ただし、作業にはdockerの変わりにpodmanを使用します。podman composeを実行する際に外部のcompose providerとしてdocker-composeが呼び出されるように、docker-composeもインストールしておきます。
brewにてpodman、podman-composeおよびdocker-composeをインストールします。
brew install podman podman-compose docker-compose
私の環境ではすでにインストール済みだったので、そのように報告されました。
% brew install podman podman-compose docker-compose
==> Downloading https://formulae.brew.sh/api/formula.jws.json
==> Downloading https://formulae.brew.sh/api/cask.jws.json
Warning: podman 5.5.2 is already installed and up-to-date.
To reinstall 5.5.2, run:
brew reinstall podman
Warning: podman-compose 1.5.0 is already installed and up-to-date.
To reinstall 1.5.0, run:
brew reinstall podman-compose
Warning: docker-compose 2.38.2 is already installed and up-to-date.
To reinstall 2.38.2, run:
brew reinstall docker-compose
%
podmanの構成コマンドは以下になります。CPU数やメモリ量(ディスクサイズはデフォルトで100GB)は、環境に合わせて調整します。
podman machine init
podman machine set --cpus 8 --memory 16384
podman machine ls
podman machine start
Difyをクローンします。
git clone https://github.com/langgenius/dify.git
% git clone https://github.com/langgenius/dify.git
Cloning into 'dify'...
remote: Enumerating objects: 184984, done.
remote: Counting objects: 100% (1208/1208), done.
remote: Compressing objects: 100% (539/539), done.
remote: Total 184984 (delta 966), reused 683 (delta 669), pack-reused 183776 (from 4)
Receiving objects: 100% (184984/184984), 101.73 MiB | 7.09 MiB/s, done.
Resolving deltas: 100% (135319/135319), done.
%
Difyのリポジトリに含まれるdockerのディレクトリへ移動します。
cd dify/docker
% cd dify/docker
docker % ls
certbot elasticsearch ssrf_proxy
couchbase-server generate_docker_compose startupscripts
docker-compose-template.yaml middleware.env.example tidb
docker-compose.middleware.yaml nginx volumes
docker-compose.png pgvector
docker-compose.yaml README.md
docker %
構成ファイルとして.envを作成します。雛形の.env.exampleをコピーします。
cp .env.example .env
docker % cp .env.example .env
docker %
.envの設定を変更します。
私の環境ではpodmanをルートレス・モードで起動しているため、DifyのHTTPポートに80番を使用できません。以下のEXPOSE_NGINX_PORT、EXPORT_NGINX_SSL_PORTの番号を変更します。以下ではそれぞれ8084、8484に変更しています。
# ------------------------------
# Docker Compose Service Expose Host Port Configurations
# ------------------------------
EXPOSE_NGINX_PORT=8084
EXPOSE_NGINX_SSL_PORT=8484
謝辞:EXPOSE_NGINX_PORTについては、Aran NakayamaさんのQiitaの記事を参考にしています。
podmanを使ってDifyをローカルで動かしてみる(Macユーザー向け)
VECTOR_STOREの設定をoracleに変更します。
# ------------------------------
# Vector Database Configuration
# ------------------------------
# The type of vector store to use.
# Supported values are `weaviate`, `qdrant`, `milvus`, `myscale`, `relyt`, `pgvector`, `pgvecto-rs`, `chroma`, `opensearch`, `oracle`, `tencent`, `elasticsearch`, `elasticsearch-ja`, `analyticdb`, `couchbase`, `vikingdb`, `oceanbase`, `opengauss`, `tablestore`,`vastbase`,`tidb`,`tidb_on_qdrant`,`baidu`,`lindorm`,`huawei_cloud`,`upstash`, `matrixone`.
VECTOR_STORE=oracle
Oracle Databaseへの接続先を設定します。
ORACLE_USERに接続先となるデータベース・ユーザー名、ORACLE_PASSWORDに、その接続先ユーザーのパスワードを設定します。接続先となるOracle Databaseはホスト・ポートの1521で接続の待ち受けを行なっているので、ORACLE_DSNの設定はhost.containers.internal:1521/FREEPDB1になります。
ORACLE_IS_AUTONOMOUSはデフォルトでfalseになっています。ORACLE_CONFIG_DIR、ORACLE_WALLET_LOCATION、ORACLE_WALLET_PASSWORDは接続先データベースとしてAutonomous Databaseを選択したときに意味を持つ設定と思われるため、そのままの設定にしています。
# Oracle configuration, only available when VECTOR_STORE is `oracle`
ORACLE_USER=<接続するデータベース・ユーザー>
ORACLE_PASSWORD=<ORACLE_USERのパスワード>
ORACLE_DSN=host.containers.internal:1521/FREEPDB1
ORACLE_CONFIG_DIR=/app/api/storage/wallet
ORACLE_WALLET_LOCATION=/app/api/storage/wallet
ORACLE_WALLET_PASSWORD=dify
ORACLE_IS_AUTONOMOUS=false
docker-compose.yamlを開き、profilesの設定でoracleとなっている箇所をoracle-skipに変更します。
# Oracle vector database
oracle:
image: container-registry.oracle.com/database/free:latest
profiles:
- oracle-skip
restart: always
volumes:
- source: oradata
type: volume
target: /opt/oracle/oradata
- ./startupscripts:/opt/oracle/scripts/startup
environment:
ORACLE_PWD: ${ORACLE_PWD:-Dify123456}
ORACLE_CHARACTERSET: ${ORACLE_CHARACTERSET:-AL32UTF8}
接続先となるデータベース・ユーザーに、最低限必要な権限を与えます。
grant db_developer_role to <接続先データベース・ユーザー>;
grant execute on ctx_ddl to <接続先データベース・ユーザー>;
以下の例では、接続先データベース・ユーザーは
WKSP_APEXDEVになっています。
docker % sql sys/*********@localhost/freepdb1 as sysdba
SQLcl: 月 7月 14 12:36:11 2025のリリース25.2 Production
Copyright (c) 1982, 2025, Oracle. All rights reserved.
接続先:
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.8.0.25.04
SQL> grant db_developer_role to wksp_apexdev;
Grantが正常に実行されました。
SQL> grant execute on ctx_ddl to wksp_apexdev;
Grantが正常に実行されました。
SQL> exit
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.8.0.25.04から切断されました
docker %
接続先データベース・ユーザーで接続し、Oracle Textのレクサーをworld_lexerという名前で作成します。実際のレクサーは言語に応じて選択します。以下ではJAPANESE_LEXERを選択しています。
begin
ctx_ddl.create_preference(
preference_name => 'world_lexer',
object_name => 'JAPANESE_LEXER'
);
end;
/
docker % sql wksp_apexdev/********@localhost/freepdb1
SQLcl: 月 7月 14 12:46:02 2025のリリース25.2 Production
Copyright (c) 1982, 2025, Oracle. All rights reserved.
接続先:
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.8.0.25.04
SQL> begin
2 ctx_ddl.create_preference(
3 preference_name => 'world_lexer',
4 object_name => 'JAPANESE_LEXER'
5 );
6 end;
7* /
PL/SQLプロシージャが正常に完了しました。
SQL> exit
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.8.0.25.04から切断されました
docker %
以上で必要最小限の設定ができました。
Difyの環境の作成と起動を行います。
podman compose up -d
docker % podman compose up -d
>>>> Executing external compose provider "/opt/homebrew/bin/docker-compose". Please see podman-compose(1) for how to disable this message. <<<<
[+] Running 11/11
✔ Network docker_default Created 0.0s
✔ Network docker_ssrf_proxy_network Created 0.0s
✔ Container docker-web-1 Started 0.2s
✔ Container docker-redis-1 Started 0.2s
✔ Container docker-sandbox-1 Started 0.2s
✔ Container docker-db-1 Healthy 4.7s
✔ Container docker-ssrf_proxy-1 Started 0.1s
✔ Container docker-api-1 Started 4.7s
✔ Container docker-plugin_daemon-1 Started 4.7s
✔ Container docker-worker-1 Started 4.8s
✔ Container docker-nginx-1 Started 4.8s
docker %
以上でDifyが起動しました。手元のブラウザから接続します。
初回接続時は、管理者アカウントの作成を求められます。
メールアドレス、ユーザー名、パスワードを入力して、セットアップをクリックします。
直前に入力したメールアドレスとパスワードを入力し、サインインします。
サインインできました。
これからベクトル検索ができることを確認します。
今回の作業ではチャット・モデルとしてqwen3:8b、エンべディング・モデルとしてbge-m3:latestを使用します。
Ollamaでこれらのモデルをpullしておきます。
ollama pull bge-m3:latest
ollama pull qwen3:8b % ollama pull bge-m3:latest
pulling manifest
pulling daec91ffb5dd: 100% ▕██████████████████▏ 1.2 GB
pulling a406579cd136: 100% ▕██████████████████▏ 1.1 KB
pulling 0c4c9c2a325f: 100% ▕██████████████████▏ 337 B
verifying sha256 digest
writing manifest
success
% ollama pull qwen3:8b
pulling manifest
pulling a3de86cd1c13: 100% ▕██████████████████▏ 5.2 GB
pulling ae370d884f10: 100% ▕██████████████████▏ 1.7 KB
pulling d18a5cc71b84: 100% ▕██████████████████▏ 11 KB
pulling cff3f395ef37: 100% ▕██████████████████▏ 120 B
pulling 05a61d37b084: 100% ▕██████████████████▏ 487 B
verifying sha256 digest
writing manifest
success
%
ユーザー名のプルダウン・メニューに含まれる設定を開きます。
モデルプロバイダーを開き、Ollamaのインストールをクリックします。
Ollamaのプラグインを
インストールします。
プラグインとしてOllamaが追加されます。Ollamaにモデルを追加します。
Model TypeとしてText Embeddingを選択します。Model Nameはbge-m3:latest、Base URLは(DifyからみるとOllamaはコンテナ外のホストで動作しているため)、http://host.containers.internal:11434を指定します。
以上で保存します。
続けて、チャット・モデルを追加します。先ほどと同様にモデルを追加をクリックします。
Model TypeにLLMを選択し、Model Nameとしてqwen3:8bを設定します。Base URLはhttp://host.containers.internal:11434です。
Completion ModeにChatを選択します。
今回はベクトル検索の確認だけを行うので、このモデルは使用しません。
以上で保存します。
システムモデル設定をクリックします。
システム推論モデルとしてqwen3:8b、埋め込みモデルとしてbge-m3:latestを設定します。
以上を設定し、保存します。
モデルの設定は、以上で完了です。
ナレッジを開き、ナレッジベースを作成します。
データソースの選択として
テキストファイルからのインポートを選択し、とりあえず
空のナレッジベースを作成します。
ナレッジベースの名称は
testとします。
作成をクリックします。
ナレッジベースtestが作成されます。
ファイルを追加します。
ナレッジベースに登録するファイルを選択します。
次へ進みます。

Oracle Database 23ai Freeがベクトル・ストアとして使用されることを確認することが目的なので、パラメータの調整などは省きます。
チャンク設定は汎用にします。インデックス・モードは高品質を選択します。検索設定にベクトル検索を選択します。ベクトル・ストアやシステムモデルが設定されているため、これらはデフォルトで選択されています。
以上で保存して処理をクリックします。
ナレッジベースにドキュメントがアップロードされたことを確認し、ドキュメントに移動します。
検索テストを開きます。

ソーステキストに
ベクトル検索と表示されていることを確認します。
ソーステキストとして適当な文章を入力し、テスト中をクリックします。
取得したチャンクが表示されることを確認します。
精度の確認はさておき、検索結果パラグラフが表示されていれば、ベクトル検索自体は成功しています。ベクトル・ストアとしてOracle Database 23ai Freeは正しく構成されています。
Difyでの確認作業は以上になります。
Oracle Database 23ai Freeに接続し、 接続先スキーマに作成されたオブジェクトを確認します。SQLclを使います。
sql <接続先データベース・ユーザー>/<パスワード>@localhost/freepdb1
docker % sql wksp_apexdev/*******@localhost/freepdb1
SQLcl: 月 7月 14 13:33:03 2025のリリース25.2 Production
Copyright (c) 1982, 2025, Oracle. All rights reserved.
接続先:
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.8.0.25.04
SQL>
作成されている表を確認します。
select table_name from user_tables where table_name like '%EMBEDDING_VECTOR_INDEX%';SQL> select table_name from user_tables where table_name like '%EMBEDDING_VECTOR_INDEX%';
TABLE_NAME
_________________________________________________________________________________
DR$IDX_DOCS_EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE$I
DR$IDX_DOCS_EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE$K
DR$IDX_DOCS_EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE$U
DR$IDX_DOCS_EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE$Q
DR$IDX_DOCS_EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE$C
DR$IDX_DOCS_EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE$B
EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE
DR$IDX_DOCS_EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE$N
8行が選択されました。
SQL>
DR$で始まる表はOracle Textの全文索引を構成する表です。おそらくDifyではベクトル・ストアにオラクルを選択すると、ハイブリッド検索にOracle Text検索を使うように構成されているようです。
全文検索索引の構成を確認してみます。
select index_name, parameters from user_indexes where index_type = 'DOMAIN';
Oracle Text索引のレクサーとしてworld lexerが使用されていることが確認できます。
SQL> select index_name, parameters from user_indexes where index_type = 'DOMAIN';
INDEX_NAME PARAMETERS
____________________________________________________________________________ ______________________________________________________________________________________
IDX_DOCS_EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE FILTER CTXSYS.NULL_FILTER SECTION GROUP CTXSYS.HTML_SECTION_GROUP LEXER world_lexer
SQL>
それ以外の表は列TEXTにチャンク分割された文字列、列METAにJSON形式のメタデータ、列EMBEDDINGにベクトルが保存されています。
SQL> desc EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE
名前 Nullかどうか タイプ
____________ ___________ ____________________
ID VARCHAR2(100)
TEXT NOT NULL CLOB
META JSON
EMBEDDING NOT NULL VECTOR(*,*,DENSE)
SQL>
今回の記事は以上になります。
完