ローカル LLM 環境を構築するで作成した環境にノーコード AI ツールである Dify を追加する。
Dify とは
Dify とは Web ブラウザで視覚的に AI アプリケーションを開発できるノーコードツールである。
Dify をデプロイする
上記のページの Quick Start を参考にする。
以下のコマンドを実行する。
$ git clone https://github.com/langgenius/dify.git
$ cd dify/docker
$ cp .env.example .env
ポートを設定する
Dify が使用する HTTP ポートはデフォルトで 80 番になっているが、必要なら.envから変更することができる。
以下は 3001 番に変更する例である。
# ------------------------------
# Docker Compose Service Expose Host Port Configurations
# ------------------------------
EXPOSE_NGINX_PORT=3001
EXPOSE_NGINX_SSL_PORT=443
Ollama と連携するための設定を行う 1
dify/docker/docker-compose-template.yamlの各サービスに以下の行を追加する。
詳しい理由は後述するが、これを記載しないと Dify の Docker コンテナから Ollama の Docker コンテナへリクエストが到達しない。
extra_hosts:
- "host.docker.internal:host-gateway"
以下は設定の例である。非常に面倒くさいが、延々とやる。
x-shared-env: &shared-api-worker-env
services:
# API service
api:
image: langgenius/dify-api:1.8.1
restart: always
environment:
# Use the shared environment variables.
<<: *shared-api-worker-env
# Startup mode, 'api' starts the API server.
MODE: api
SENTRY_DSN: ${API_SENTRY_DSN:-}
SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
SENTRY_PROFILES_SAMPLE_RATE: ${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0}
PLUGIN_REMOTE_INSTALL_HOST: ${EXPOSE_PLUGIN_DEBUGGING_HOST:-localhost}
PLUGIN_REMOTE_INSTALL_PORT: ${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}
PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
volumes:
# Mount the storage directory to the container, for storing user files.
- ./volumes/app/storage:/app/api/storage
networks:
- ssrf_proxy_network
- default
+ extra_hosts:
+ - "host.docker.internal:host-gateway"
# worker service
# The Celery worker for processing the queue.
worker:
image: langgenius/dify-api:1.8.1
restart: always
environment:
# Use the shared environment variables.
<<: *shared-api-worker-env
# Startup mode, 'worker' starts the Celery worker for processing the queue.
MODE: worker
SENTRY_DSN: ${API_SENTRY_DSN:-}
SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
SENTRY_PROFILES_SAMPLE_RATE: ${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0}
PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
volumes:
# Mount the storage directory to the container, for storing user files.
- ./volumes/app/storage:/app/api/storage
networks:
- ssrf_proxy_network
- default
+ extra_hosts:
+ - "host.docker.internal:host-gateway"
# worker_beat service
# Celery beat for scheduling periodic tasks.
worker_beat:
image: langgenius/dify-api:1.8.1
restart: always
environment:
# Use the shared environment variables.
<<: *shared-api-worker-env
# Startup mode, 'worker_beat' starts the Celery beat for scheduling periodic tasks.
MODE: beat
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
networks:
- ssrf_proxy_network
- default
+ extra_hosts:
+ - "host.docker.internal:host-gateway"
# Frontend web application.
web:
image: langgenius/dify-web:1.8.1
restart: always
environment:
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
APP_API_URL: ${APP_API_URL:-}
SENTRY_DSN: ${WEB_SENTRY_DSN:-}
NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-0}
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
CSP_WHITELIST: ${CSP_WHITELIST:-}
ALLOW_EMBED: ${ALLOW_EMBED:-false}
ALLOW_UNSAFE_DATA_SCHEME: ${ALLOW_UNSAFE_DATA_SCHEME:-false}
MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai}
MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai}
TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-}
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-}
PM2_INSTANCES: ${PM2_INSTANCES:-2}
LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100}
MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10}
MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10}
MAX_ITERATIONS_NUM: ${MAX_ITERATIONS_NUM:-99}
MAX_TREE_DEPTH: ${MAX_TREE_DEPTH:-50}
ENABLE_WEBSITE_JINAREADER: ${ENABLE_WEBSITE_JINAREADER:-true}
ENABLE_WEBSITE_FIRECRAWL: ${ENABLE_WEBSITE_FIRECRAWL:-true}
ENABLE_WEBSITE_WATERCRAWL: ${ENABLE_WEBSITE_WATERCRAWL:-true}
+ extra_hosts:
+ - "host.docker.internal:host-gateway"
# 以下延々と続く
終わったら以下のコマンドを実行する。そうすると Dify のdocker-compose.ymlが生成される。
$ python generate_docker_compose
以下のコマンドを実行し、Dify のコンテナを起動する。
$ docker compose up -d
Ollama と連携するための設定を行う 2
http://localhost:3001/installにアクセスすると以下のような画面が表示されるので、アカウントを作成する。(ローカル環境なのでお試しなら別に適当に入力しても構わない)
以下のように画面右上のアカウントのアイコンから設定を選択する。
以下のように画面左にあるモデルプロバイダーを選択し、Ollama を探してインストールする。
以下のように Ollama について、モデルを追加を選択する。
以下のように Ollama に登録済みのモデルを設定する。
Model Nameには Ollama でモデルをインストールしたときの名前を指定する。(例: gpt-oss:20b)
忘れた場合、以下を参照する。
Model TypeにはLLMを指定する。
Base URLにはhttp://host.docker.internal:11434を指定する。
Base URLについて、http://localhost:11434を指定したくなるが、その場合 localhost は Dify のコンテナ内を意味するので、リクエストは以下のように Ollama へたどり着かないのだ。
前述のdify/docker/docker-compose-template.yamlの設定を済ませていれば、host.docker.internalで以下のようにホストのネットワークを経由して Ollama を参照できる。
Base URLにホストの IP アドレスを設定しても同じ経路で解決できるが、ホストの IP アドレスが DHCP で設定されている場合 IP アドレスが変わったときに繋がらなくなってしまう。
Dify で AI アプリケーションを作成する
動作確認としてチャットボットを作ってみる。
以下のようにホームの画面から最初から作成を選択する。
以下のようにチャットフローを選択し、名前をつける。
以下のように画面上でフローを作成する。今回は LLM を 2 つ並列にして異なる意見を聞けるようにしてみた。
以下のようにプレビューから動作確認を行うことができる。
Dify の環境を構築し、Dify を使って AI ツールを作成することができた。













