Open23

WindowsでDifyを使いこなす!

shohei6117shohei6117

ゴール

  • 社内のWindows PCにDify環境を立てる
  • Difyで生成AIアプリを作る

このスクラップへのリンク

Dify公式リンク

Dify関連記事を探す

Dify関連の良かった記事

その他リンク

shohei6117shohei6117

Dify環境を作る #1

ゴール

  • DifyをWindows PCにインストールして起動する

まとめ

  • 公式ドキュメントとか巷にあふれるブログ記事のように簡単に起動できなかった
  • 情報がなく苦労したこと
    • Docker Desktop for Windows: バイパスproxy設定
    • docker-compose.yaml: エラー回避のためのコード修正

関連リンク

大まかな手順

  1. Docker Desktop for Windowsを導入する
  2. Docker環境でDifyを起動する

もう少し詳しい手順

  1. gitをインストールする(割愛)
  2. WSL2を有効化する
  • 「Windowsの機能の有効化または無効化」を開いて「Linux用Windowsサブシステム」と「仮想マシンプラットフォーム」にチェックを入れて保存、PCを再起動する
設定画面

  1. PowerShellを管理者モードで立ち上げてubuntuをインストールする
    以下のコマンドを順番に実行する。
PowerShell
wsl --status #バージョン2になっていることを確認
wsl --install -d ubuntu #ubuntuをインストール
wsl --update #wslの更新
wsl --status #ubuntuがインストールできたか確認

  1. Docker Desktop for Windowsをインストールする(割愛)
  2. Docker Desktop for Windowsの設定をする
Docker Desktop for WindowsのResources設定画面
  • wsl2との連携をONにする
  • Dockerのデフォルトネットワークサブネット。Dockerコンテナ同士の通信や、ホストマシンとDockerコンテナの間の通信用(いじらない)
  • プロキシ設定画面 大事!!
  • バイパスproxy設定の方法が分からない場合は、ipconfig /allの結果をChatGPTに貼り付けて、「Docker Desktop fow Windowsのバイパスproxy設定を教えて」と言って教えてもらう!
  • /22 とか /24の意味は「IPv4アドレス32ビット長のうち、ネットワーク部分が何ビットかを指すか」ということ。/22だとネットワークが22ビット、ホストが10ビット(=1024)なので、1024個のIPアドレス範囲を指すことになる。(、、、とChatGPTが教えてくれた)
  1. Difyのコードを公式リポジトリからダウンロードする
PowerShell
git clone https://github.com/langgenius/dify.git
  1. cloneしたdifyフォルダの中のdockerフォルダでPowerShellを起動して、DifyのDockerコンテナを起動する ⇒エラーが出る
PowerShell
docker compose up -d

⇒port80は別のアプリですでに使われているというエラーが出る

port80を使っているのはsystem

netstat -nanoコマンドでPID4のプロセスと分かる

⇒タスクマネージャーでSystemが使っていると分かる

⇒port80を使うのは諦める。

  1. port80でなく8080を使うように、docker-compose.yamlを修正する
docker-compose.yamlの修正部分
docker-compose.yaml
  nginx:
    image: nginx:latest
    restart: always
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/proxy.conf:/etc/nginx/proxy.conf
      - ./nginx/conf.d:/etc/nginx/conf.d
      #- ./nginx/ssl:/etc/ssl
    depends_on:
      - api
      - web
    ports:
      # - "80:80" #元の設定
      - "8080:80" #変更後の設定
      #- "443:443"

  1. あらためてdocker-compose up -dする ⇒まだ駄目
    langgenius/dify-web:0.6.9postgres:15-alpineのコンテナが停止、再起動を繰り返す。。
該当するコード
docker-compose.yaml
  web:
    image: langgenius/dify-web:0.6.9
    restart: always
    environment:
      CONSOLE_API_URL: ''
      APP_API_URL: ''
      SENTRY_DSN: ''

  db:
    image: postgres:15-alpine
    restart: always
    environment:
      PGUSER: postgres
      POSTGRES_PASSWORD: difyai123456
      POSTGRES_DB: dify
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      - ./volumes/db/data:/var/lib/postgresql/data
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 1s
      timeout: 3s
      retries: 30
  1. ChatGPTに助けてもらいながら、docker-compose.yamlをあちこち修正する。
    「エラーlogを渡す⇒yamlファイルの修正案をもらう⇒トライ」を繰り返した。。
    ⇒最終的にできたyamlファイルはこれ
ようやく完成したdocke-compose.yamlファイル
docker-compose.yaml
version: '3'

# ===========================================================
services:
# -----------------------------------------------------------
  api:
    image: langgenius/dify-api:0.6.9
    restart: always
    environment:
      MODE: api
      LOG_LEVEL: INFO
      SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
      CONSOLE_WEB_URL: ''
      INIT_PASSWORD: ''
      CONSOLE_API_URL: ''
      SERVICE_API_URL: ''
      APP_WEB_URL: ''
      FILES_URL: ''
      FILES_ACCESS_TIMEOUT: 300
      MIGRATION_ENABLED: 'true'
      DB_USERNAME: postgres
      DB_PASSWORD: difyai123456
      DB_HOST: db
      DB_PORT: 5432
      DB_DATABASE: dify
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_USERNAME: ''
      REDIS_PASSWORD: difyai123456
      REDIS_USE_SSL: 'false'
      REDIS_DB: 0
      CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
      WEB_API_CORS_ALLOW_ORIGINS: '*'
      CONSOLE_CORS_ALLOW_ORIGINS: '*'
      STORAGE_TYPE: local
      STORAGE_LOCAL_PATH: storage
      S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
      S3_BUCKET_NAME: 'difyai'
      S3_ACCESS_KEY: 'ak-difyai'
      S3_SECRET_KEY: 'sk-difyai'
      S3_REGION: 'us-east-1'
      AZURE_BLOB_ACCOUNT_NAME: 'difyai'
      AZURE_BLOB_ACCOUNT_KEY: 'difyai'
      AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
      AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
      GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
      GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
      VECTOR_STORE: weaviate
      WEAVIATE_ENDPOINT: http://weaviate:8080
      WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
      QDRANT_URL: http://qdrant:6333
      QDRANT_API_KEY: difyai123456
      QDRANT_CLIENT_TIMEOUT: 20
      QDRANT_GRPC_ENABLED: 'false'
      QDRANT_GRPC_PORT: 6334
      MILVUS_HOST: 127.0.0.1
      MILVUS_PORT: 19530
      MILVUS_USER: root
      MILVUS_PASSWORD: Milvus
      MILVUS_SECURE: 'false'
      RELYT_HOST: db
      RELYT_PORT: 5432
      RELYT_USER: postgres
      RELYT_PASSWORD: difyai123456
      RELYT_DATABASE: postgres
      PGVECTOR_HOST: pgvector
      PGVECTOR_PORT: 5432
      PGVECTOR_USER: postgres
      PGVECTOR_PASSWORD: difyai123456
      PGVECTOR_DATABASE: dify
      MAIL_TYPE: ''
      MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
      SMTP_SERVER: ''
      SMTP_PORT: 465
      SMTP_USERNAME: ''
      SMTP_PASSWORD: ''
      SMTP_USE_TLS: 'true'
      SMTP_OPPORTUNISTIC_TLS: 'false'
      RESEND_API_KEY: ''
      RESEND_API_URL: https://api.resend.com
      SENTRY_DSN: ''
      SENTRY_TRACES_SAMPLE_RATE: 1.0
      SENTRY_PROFILES_SAMPLE_RATE: 1.0
      NOTION_INTEGRATION_TYPE: public
      NOTION_CLIENT_SECRET: you-client-secret
      NOTION_CLIENT_ID: you-client-id
      NOTION_INTERNAL_SECRET: you-internal-secret
      CODE_EXECUTION_ENDPOINT: "http://sandbox:8194"
      CODE_EXECUTION_API_KEY: dify-sandbox
      CODE_MAX_NUMBER: 9223372036854775807
      CODE_MIN_NUMBER: -9223372036854775808
      CODE_MAX_STRING_LENGTH: 80000
      TEMPLATE_TRANSFORM_MAX_LENGTH: 80000
      CODE_MAX_STRING_ARRAY_LENGTH: 30
      CODE_MAX_OBJECT_ARRAY_LENGTH: 30
      CODE_MAX_NUMBER_ARRAY_LENGTH: 1000
      SSRF_PROXY_HTTP_URL: 'http://ssrf_proxy:3128'
      SSRF_PROXY_HTTPS_URL: 'http://ssrf_proxy:3128'
      INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
    depends_on:
      - db
      - redis
    volumes:
      - ./volumes/app/storage:/app/api/storage
    networks:
      - ssrf_proxy_network
      - default

# -----------------------------------------------------------
  worker:
    image: langgenius/dify-api:0.6.9
    restart: always
    environment:
      CONSOLE_WEB_URL: ''
      MODE: worker
      LOG_LEVEL: INFO
      SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
      DB_USERNAME: postgres
      DB_PASSWORD: difyai123456
      DB_HOST: db
      DB_PORT: 5432
      DB_DATABASE: dify
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_USERNAME: ''
      REDIS_PASSWORD: difyai123456
      REDIS_DB: 0
      REDIS_USE_SSL: 'false'
      CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
      STORAGE_TYPE: local
      STORAGE_LOCAL_PATH: storage
      S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
      S3_BUCKET_NAME: 'difyai'
      S3_ACCESS_KEY: 'ak-difyai'
      S3 SECRET_KEY: 'sk-difyai'
      S3_REGION: 'us-east-1'
      AZURE_BLOB_ACCOUNT_NAME: 'difyai'
      AZURE_BLOB_ACCOUNT_KEY: 'difyai'
      AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
      AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
      GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
      GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
      VECTOR_STORE: weaviate
      WEAVIATE_ENDPOINT: http://weaviate:8080
      WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
      QDRANT_URL: http://qdrant:6333
      QDRANT_API_KEY: difyai123456
      QDRANT_CLIENT_TIMEOUT: 20
      QDRANT_GRPC_ENABLED: 'false'
      QDRANT_GRPC_PORT: 6334
      MILVUS_HOST: 127.0.0.1
      MILVUS_PORT: 19530
      MILVUS_USER: root
      MILVUS_PASSWORD: Milvus
      MILVUS_SECURE: 'false'
      MAIL_TYPE: ''
      MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
      SMTP_SERVER: ''
      SMTP_PORT: 465
      SMTP_USERNAME: ''
      SMTP_PASSWORD: ''
      SMTP_USE_TLS: 'true'
      SMTP_OPPORTUNISTIC_TLS: 'false'
      RESEND_API_KEY: ''
      RESEND_API_URL: https://api.resend.com
      RELYT_HOST: db
      RELYT_PORT: 5432
      RELYT_USER: postgres
      RELYT_PASSWORD: difyai123456
      RELYT_DATABASE: postgres
      PGVECTOR_HOST: pgvector
      PGVECTOR_PORT: 5432
      PGVECTOR_USER: postgres
      PGVECTOR_PASSWORD: difyai123456
      PGVECTOR_DATABASE: dify
      NOTION_INTEGRATION_TYPE: public
      NOTION_CLIENT_SECRET: you-client-secret
      NOTION_CLIENT_ID: you-client-id
      NOTION_INTERNAL_SECRET: you-internal-secret
      INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
    depends_on:
      - db
      - redis
    volumes:
      - ./volumes/app/storage:/app/api/storage
    networks:
      - ssrf_proxy_network
      - default

# -----------------------------------------------------------
  web:
    image: langgenius/dify-web:0.6.9
    restart: always
    environment:
      CONSOLE_API_URL: ''
      APP_API_URL: ''
      SENTRY_DSN: ''
    networks:
      - ssrf_proxy_network # 修正: defaultネットワークにssrf_proxy_networkを追加
      - default

# -----------------------------------------------------------
  db:
    image: postgres:15-alpine
    restart: always
    environment:
      PGUSER: postgres
      POSTGRES_PASSWORD: difyai123456
      POSTGRES_DB: dify
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      - postgres_data:/var/lib/postgresql/data # 修正: ./volumes/db/dataからpostgres_dataに変更
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 1s
      timeout: 3s
      retries: 30
    networks:
      - default

# -----------------------------------------------------------
  redis:
    image: redis:6-alpine
    restart: always
    volumes:
      # - redis_data:/data # 修正: ./volumes/redis/dataからredis_dataに変更
      - ./volumes/redis/data:/data
    command: redis-server --requirepass difyai123456
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
    networks:
      - default

# -----------------------------------------------------------
  weaviate:
    image: semitechnologies/weaviate:1.19.0
    restart: always
    volumes:
      - ./volumes/weaviate:/var/lib/weaviate
    environment:
      QUERY_DEFAULTS_LIMIT: 25
      AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'false'
      PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
      DEFAULT_VECTORIZER_MODULE: 'none'
      CLUSTER_HOSTNAME: 'node1'
      AUTHENTICATION_APIKEY_ENABLED: 'true'
      AUTHENTICATION_APIKEY_ALLOWED_KEYS: 'WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih'
      AUTHENTICATION_APIKEY_USERS: 'hello@dify.ai'
      AUTHORIZATION_ADMINLIST_ENABLED: 'true'
      AUTHORIZATION_ADMINLIST_USERS: 'hello@dify.ai'
    networks:
      - default

# -----------------------------------------------------------
  sandbox:
    image: langgenius/dify-sandbox:0.2.0
    restart: always
    environment:
      API_KEY: dify-sandbox
      GIN_MODE: 'release'
      WORKER_TIMEOUT: 15
      ENABLE_NETWORK: 'true'
      HTTP_PROXY: 'http://ssrf_proxy:3128'
      HTTPS_PROXY: 'http://ssrf_proxy:3128'
    volumes:
      - ./volumes/sandbox/dependencies:/dependencies
    networks:
      - ssrf_proxy_network

# -----------------------------------------------------------
  ssrf_proxy:
    image: ubuntu/squid:latest
    restart: always
    volumes:
      - ./volumes/ssrf_proxy/squid.conf:/etc/squid/squid.conf
    networks:
      - ssrf_proxy_network
      - default

# -----------------------------------------------------------
  nginx:
    image: nginx:latest
    restart: always
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/proxy.conf:/etc/nginx/proxy.conf
      - ./nginx/conf.d:/etc/nginx/conf.d
    depends_on:
      - api
      - web
    ports:
      - "8080:80"
    networks:
      - default # 修正: defaultネットワークを追加

# ===========================================================
networks:
  ssrf_proxy_network:
    driver: bridge
    internal: true
  default: # 修正: defaultネットワークを追加
    driver: bridge

# ===========================================================
volumes:
  postgres_data: # 追加: 新しいボリュームを定義
  # redis_data: # 追加: 新しいボリュームを定義```
オリジナルと最終的なdocker-compose.yamlを可視化して比較

※graphvizで可視化してみた。
オリジナル

最終版

  1. ようやくDifyが起動!
shohei6117shohei6117

Dify環境を作る#2

ゴール

  • DIfyを別のWindows PCにインストールして起動する

まとめ

  • Docker Desktopでwsl2データを全削除したらエラーが解消した

関連リンク

手順

※ 同じ社内ネットワークにある別のPCなので、途中までは [前回](https://zenn.dev/link/comments/59a67f0070ba23) と同じで、手順6で出たエラーだけが違う

  1. gitをインストール(割愛)
  2. wsl2を有効化(割愛)
  3. Docker Desktop for Windowsを導入(割愛)
  4. Difyのコードを公式リポジトリからgit cloneする(割愛)
  5. cloneしたdifyフォルダの中のdocker-compose.yamlを書き替える
    ファイルのパスはE:\dify\docker\docker-compose.yaml
書き替えたあとのdocker-compose.yaml
docker-compose.yaml
version: '3'

# ===========================================================
services:
# -----------------------------------------------------------
  api:
    image: langgenius/dify-api:0.6.9
    restart: always
    environment:
      MODE: api
      LOG_LEVEL: INFO
      SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
      CONSOLE_WEB_URL: ''
      INIT_PASSWORD: ''
      CONSOLE_API_URL: ''
      SERVICE_API_URL: ''
      APP_WEB_URL: ''
      FILES_URL: ''
      FILES_ACCESS_TIMEOUT: 300
      MIGRATION_ENABLED: 'true'
      DB_USERNAME: postgres
      DB_PASSWORD: difyai123456
      DB_HOST: db
      DB_PORT: 5432
      DB_DATABASE: dify
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_USERNAME: ''
      REDIS_PASSWORD: difyai123456
      REDIS_USE_SSL: 'false'
      REDIS_DB: 0
      CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
      WEB_API_CORS_ALLOW_ORIGINS: '*'
      CONSOLE_CORS_ALLOW_ORIGINS: '*'
      STORAGE_TYPE: local
      STORAGE_LOCAL_PATH: storage
      S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
      S3_BUCKET_NAME: 'difyai'
      S3_ACCESS_KEY: 'ak-difyai'
      S3_SECRET_KEY: 'sk-difyai'
      S3_REGION: 'us-east-1'
      AZURE_BLOB_ACCOUNT_NAME: 'difyai'
      AZURE_BLOB_ACCOUNT_KEY: 'difyai'
      AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
      AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
      GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
      GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
      VECTOR_STORE: weaviate
      WEAVIATE_ENDPOINT: http://weaviate:8080
      WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
      QDRANT_URL: http://qdrant:6333
      QDRANT_API_KEY: difyai123456
      QDRANT_CLIENT_TIMEOUT: 20
      QDRANT_GRPC_ENABLED: 'false'
      QDRANT_GRPC_PORT: 6334
      MILVUS_HOST: 127.0.0.1
      MILVUS_PORT: 19530
      MILVUS_USER: root
      MILVUS_PASSWORD: Milvus
      MILVUS_SECURE: 'false'
      RELYT_HOST: db
      RELYT_PORT: 5432
      RELYT_USER: postgres
      RELYT_PASSWORD: difyai123456
      RELYT_DATABASE: postgres
      PGVECTOR_HOST: pgvector
      PGVECTOR_PORT: 5432
      PGVECTOR_USER: postgres
      PGVECTOR_PASSWORD: difyai123456
      PGVECTOR_DATABASE: dify
      MAIL_TYPE: ''
      MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
      SMTP_SERVER: ''
      SMTP_PORT: 465
      SMTP_USERNAME: ''
      SMTP_PASSWORD: ''
      SMTP_USE_TLS: 'true'
      SMTP_OPPORTUNISTIC_TLS: 'false'
      RESEND_API_KEY: ''
      RESEND_API_URL: https://api.resend.com
      SENTRY_DSN: ''
      SENTRY_TRACES_SAMPLE_RATE: 1.0
      SENTRY_PROFILES_SAMPLE_RATE: 1.0
      NOTION_INTEGRATION_TYPE: public
      NOTION_CLIENT_SECRET: you-client-secret
      NOTION_CLIENT_ID: you-client-id
      NOTION_INTERNAL_SECRET: you-internal-secret
      CODE_EXECUTION_ENDPOINT: "http://sandbox:8194"
      CODE_EXECUTION_API_KEY: dify-sandbox
      CODE_MAX_NUMBER: 9223372036854775807
      CODE_MIN_NUMBER: -9223372036854775808
      CODE_MAX_STRING_LENGTH: 80000
      TEMPLATE_TRANSFORM_MAX_LENGTH: 80000
      CODE_MAX_STRING_ARRAY_LENGTH: 30
      CODE_MAX_OBJECT_ARRAY_LENGTH: 30
      CODE_MAX_NUMBER_ARRAY_LENGTH: 1000
      SSRF_PROXY_HTTP_URL: 'http://ssrf_proxy:3128'
      SSRF_PROXY_HTTPS_URL: 'http://ssrf_proxy:3128'
      INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
    depends_on:
      - db
      - redis
    volumes:
      - ./volumes/app/storage:/app/api/storage
    networks:
      - ssrf_proxy_network
      - default

# -----------------------------------------------------------
  worker:
    image: langgenius/dify-api:0.6.9
    restart: always
    environment:
      CONSOLE_WEB_URL: ''
      MODE: worker
      LOG_LEVEL: INFO
      SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
      DB_USERNAME: postgres
      DB_PASSWORD: difyai123456
      DB_HOST: db
      DB_PORT: 5432
      DB_DATABASE: dify
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_USERNAME: ''
      REDIS_PASSWORD: difyai123456
      REDIS_DB: 0
      REDIS_USE_SSL: 'false'
      CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
      STORAGE_TYPE: local
      STORAGE_LOCAL_PATH: storage
      S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
      S3_BUCKET_NAME: 'difyai'
      S3_ACCESS_KEY: 'ak-difyai'
      S3 SECRET_KEY: 'sk-difyai'
      S3_REGION: 'us-east-1'
      AZURE_BLOB_ACCOUNT_NAME: 'difyai'
      AZURE_BLOB_ACCOUNT_KEY: 'difyai'
      AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
      AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
      GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
      GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
      VECTOR_STORE: weaviate
      WEAVIATE_ENDPOINT: http://weaviate:8080
      WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
      QDRANT_URL: http://qdrant:6333
      QDRANT_API_KEY: difyai123456
      QDRANT_CLIENT_TIMEOUT: 20
      QDRANT_GRPC_ENABLED: 'false'
      QDRANT_GRPC_PORT: 6334
      MILVUS_HOST: 127.0.0.1
      MILVUS_PORT: 19530
      MILVUS_USER: root
      MILVUS_PASSWORD: Milvus
      MILVUS_SECURE: 'false'
      MAIL_TYPE: ''
      MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
      SMTP_SERVER: ''
      SMTP_PORT: 465
      SMTP_USERNAME: ''
      SMTP_PASSWORD: ''
      SMTP_USE_TLS: 'true'
      SMTP_OPPORTUNISTIC_TLS: 'false'
      RESEND_API_KEY: ''
      RESEND_API_URL: https://api.resend.com
      RELYT_HOST: db
      RELYT_PORT: 5432
      RELYT_USER: postgres
      RELYT_PASSWORD: difyai123456
      RELYT_DATABASE: postgres
      PGVECTOR_HOST: pgvector
      PGVECTOR_PORT: 5432
      PGVECTOR_USER: postgres
      PGVECTOR_PASSWORD: difyai123456
      PGVECTOR_DATABASE: dify
      NOTION_INTEGRATION_TYPE: public
      NOTION_CLIENT_SECRET: you-client-secret
      NOTION_CLIENT_ID: you-client-id
      NOTION_INTERNAL_SECRET: you-internal-secret
      INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
    depends_on:
      - db
      - redis
    volumes:
      - ./volumes/app/storage:/app/api/storage
    networks:
      - ssrf_proxy_network
      - default

# -----------------------------------------------------------
  web:
    image: langgenius/dify-web:0.6.9
    restart: always
    environment:
      CONSOLE_API_URL: ''
      APP_API_URL: ''
      SENTRY_DSN: ''
    networks:
      - ssrf_proxy_network # 修正: defaultネットワークにssrf_proxy_networkを追加
      - default

# -----------------------------------------------------------
  db:
    image: postgres:15-alpine
    restart: always
    environment:
      PGUSER: postgres
      POSTGRES_PASSWORD: difyai123456
      POSTGRES_DB: dify
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      - postgres_data:/var/lib/postgresql/data # 修正: ./volumes/db/dataからpostgres_dataに変更
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 1s
      timeout: 3s
      retries: 30
    networks:
      - default

# -----------------------------------------------------------
  redis:
    image: redis:6-alpine
    restart: always
    volumes:
      # - redis_data:/data # 修正: ./volumes/redis/dataからredis_dataに変更
      - ./volumes/redis/data:/data
    command: redis-server --requirepass difyai123456
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
    networks:
      - default

# -----------------------------------------------------------
  weaviate:
    image: semitechnologies/weaviate:1.19.0
    restart: always
    volumes:
      - ./volumes/weaviate:/var/lib/weaviate
    environment:
      QUERY_DEFAULTS_LIMIT: 25
      AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'false'
      PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
      DEFAULT_VECTORIZER_MODULE: 'none'
      CLUSTER_HOSTNAME: 'node1'
      AUTHENTICATION_APIKEY_ENABLED: 'true'
      AUTHENTICATION_APIKEY_ALLOWED_KEYS: 'WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih'
      AUTHENTICATION_APIKEY_USERS: 'hello@dify.ai'
      AUTHORIZATION_ADMINLIST_ENABLED: 'true'
      AUTHORIZATION_ADMINLIST_USERS: 'hello@dify.ai'
    networks:
      - default

# -----------------------------------------------------------
  sandbox:
    image: langgenius/dify-sandbox:0.2.0
    restart: always
    environment:
      API_KEY: dify-sandbox
      GIN_MODE: 'release'
      WORKER_TIMEOUT: 15
      ENABLE_NETWORK: 'true'
      HTTP_PROXY: 'http://ssrf_proxy:3128'
      HTTPS_PROXY: 'http://ssrf_proxy:3128'
    volumes:
      - ./volumes/sandbox/dependencies:/dependencies
    networks:
      - ssrf_proxy_network

# -----------------------------------------------------------
  ssrf_proxy:
    image: ubuntu/squid:latest
    restart: always
    volumes:
      - ./volumes/ssrf_proxy/squid.conf:/etc/squid/squid.conf
    networks:
      - ssrf_proxy_network
      - default

# -----------------------------------------------------------
  nginx:
    image: nginx:latest
    restart: always
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/proxy.conf:/etc/nginx/proxy.conf
      - ./nginx/conf.d:/etc/nginx/conf.d
    depends_on:
      - api
      - web
    ports:
      - "8080:80"
    networks:
      - default # 修正: defaultネットワークを追加

# ===========================================================
networks:
  ssrf_proxy_network:
    driver: bridge
    internal: true
  default: # 修正: defaultネットワークを追加
    driver: bridge

# ===========================================================
volumes:
  postgres_data: # 追加: 新しいボリュームを定義
  # redis_data: # 追加: 新しいボリュームを定義  ```
オリジナルと最終的なdocker-compose.yamlを可視化して比較

※graphvizで可視化してみた。
オリジナル

最終版

  1. dockerフォルダでPoserShellを立ち上げて docker-compose up -dコマンドを打つ ⇒エラーが出る

Error response from daemon: error while creating mount source path '/run/desktop/mnt/host/e/dify/docker/volumes/sandbox/dependencies': mkdir /run/desktop/mnt/host/e: file exists

  1. データをいったん全削除する
    GhatGPTに聞きながら対応しても解決しない
    ⇒ググって、この記事を見つける!

⇒同じようにやってみる

Docker Desktop for Windows操作の画面キャプチャ

Troubleshootを開く

Clean / Purge data をクリック

WSL 2を選択して delete をクリック

images も containers も全部消えた。。

  1. あらためてdocker-compose up -dする
  2. ようやくDifyが起動!
shohei6117shohei6117

Difyを0.6.10にアップデートする

ゴール

  • Dify0.6.9 から Dify0.6.10 にアップデートする

まとめ

  • Dify0.6.9をインストールしたときに作ったdocker-compose.yamlファイルを流用した

関連リンク

手順

  1. いまのdockerフォルダにあるdocker-compose.yamlの名称をdocker-compose_069backup.yamlみたいな名前にしておいて、公式docどおりに進める。
PowerShell
# dockerフォルダに移動
cd dify/docker 
# リモートリポジトリのmainブランチから最新バージョンをダウンロード
git pull origin main
# 現在のdockerコンテナを停止
docker compose down
# docker-compose.ymlで定義された最新のイメージを取得
docker compose pull
# ------ ここから先はまだしない! --------------
# dockerコンテナを再構築して起動
# docker compose up -d 
  1. 0.6.10バージョンのdocker-compose.yamlを以下のように書き換える。
docker-compose.yamlの中身
version
services:
  api:
    image: langgenius/dify-api:0.6.10
    restart: always
    environment:
      MODE: api
      LOG_LEVEL: INFO
      SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
      CONSOLE_WEB_URL: 'http://161.93.***.***:8080' #追加(PCの静的IPを入れる)
      INIT_PASSWORD: ''
      CONSOLE_API_URL: 'http://161.93.***.***:8080' #追加(PCの静的IPを入れる)
      SERVICE_API_URL: 'http://161.93.***.***:8080' #追加(PCの静的IPを入れる)
      APP_WEB_URL: 'http://161.93.***.***:8080' #追加(PCの静的IPを入れる)
      FILES_URL: 'http://161.93.***.***:8080' #追加(PCの静的IPを入れる)
      FILES_ACCESS_TIMEOUT: 300
      MIGRATION_ENABLED: 'true'
      DB_USERNAME: postgres
      DB_PASSWORD: difyai123456
      DB_HOST: db
      DB_PORT: 5432
      DB_DATABASE: dify
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_USERNAME: ''
      REDIS_PASSWORD: difyai123456
      REDIS_USE_SSL: 'false'
      REDIS_DB: 0
      CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
      WEB_API_CORS_ALLOW_ORIGINS: '*'
      CONSOLE_CORS_ALLOW_ORIGINS: '*'
      STORAGE_TYPE: local
      STORAGE_LOCAL_PATH: storage
      S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
      S3_BUCKET_NAME: 'difyai'
      S3_ACCESS_KEY: 'ak-difyai'
      S3_SECRET_KEY: 'sk-difyai'
      S3_REGION: 'us-east-1'
      AZURE_BLOB_ACCOUNT_NAME: 'difyai'
      AZURE_BLOB_ACCOUNT_KEY: 'difyai'
      AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
      AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
      GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
      GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
      VECTOR_STORE: weaviate
      WEAVIATE_ENDPOINT: http://weaviate:8080
      WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
      QDRANT_URL: http://qdrant:6333
      QDRANT_API_KEY: difyai123456
      QDRANT_CLIENT_TIMEOUT: 20
      QDRANT_GRPC_ENABLED: 'false'
      QDRANT_GRPC_PORT: 6334
      MILVUS_HOST: 127.0.0.1
      MILVUS_PORT: 19530
      MILVUS_USER: root
      MILVUS_PASSWORD: Milvus
      MILVUS_SECURE: 'false'
      RELYT_HOST: db
      RELYT_PORT: 5432
      RELYT_USER: postgres
      RELYT_PASSWORD: difyai123456
      RELYT_DATABASE: postgres
      PGVECTOR_HOST: pgvector
      PGVECTOR_PORT: 5432
      PGVECTOR_USER: postgres
      PGVECTOR_PASSWORD: difyai123456
      PGVECTOR_DATABASE: dify
      MAIL_TYPE: ''
      MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
      SMTP_SERVER: ''
      SMTP_PORT: 465
      SMTP_USERNAME: ''
      SMTP_PASSWORD: ''
      SMTP_USE_TLS: 'true'
      SMTP_OPPORTUNISTIC_TLS: 'false'
      RESEND_API_KEY: ''
      RESEND_API_URL: https://api.resend.com
      SENTRY_DSN: ''
      SENTRY_TRACES_SAMPLE_RATE: 1.0
      SENTRY_PROFILES_SAMPLE_RATE: 1.0
      NOTION_INTEGRATION_TYPE: public
      NOTION_CLIENT_SECRET: you-client-secret
      NOTION_CLIENT_ID: you-client-id
      NOTION_INTERNAL_SECRET: you-internal-secret
      CODE_EXECUTION_ENDPOINT: "http://sandbox:8194"
      CODE_EXECUTION_API_KEY: dify-sandbox
      CODE_MAX_NUMBER: 9223372036854775807
      CODE_MIN_NUMBER: -9223372036854775808
      CODE_MAX_STRING_LENGTH: 80000
      TEMPLATE_TRANSFORM_MAX_LENGTH: 80000
      CODE_MAX_STRING_ARRAY_LENGTH: 30
      CODE_MAX_OBJECT_ARRAY_LENGTH: 30
      CODE_MAX_NUMBER_ARRAY_LENGTH: 1000
      SSRF_PROXY_HTTP_URL: 'http://ssrf_proxy:3128'
      SSRF_PROXY_HTTPS_URL: 'http://ssrf_proxy:3128'
      INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
    depends_on:
      - db
      - redis
    volumes:
      - ./volumes/app/storage:/app/api/storage
    networks:
      - ssrf_proxy_network
      - default

  worker:
    image: langgenius/dify-api:0.6.10
    restart: always
    environment:
      CONSOLE_WEB_URL: ''
      MODE: worker
      LOG_LEVEL: INFO
      SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
      DB_USERNAME: postgres
      DB_PASSWORD: difyai123456
      DB_HOST: db
      DB_PORT: 5432
      DB_DATABASE: dify
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_USERNAME: ''
      REDIS_PASSWORD: difyai123456
      REDIS_DB: 0
      REDIS_USE_SSL: 'false'
      CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
      STORAGE_TYPE: local
      STORAGE_LOCAL_PATH: storage
      S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
      S3_BUCKET_NAME: 'difyai'
      S3_ACCESS_KEY: 'ak-difyai'
      S3_SECRET_KEY: 'sk-difyai'
      S3_REGION: 'us-east-1'
      AZURE_BLOB_ACCOUNT_NAME: 'difyai'
      AZURE_BLOB_ACCOUNT_KEY: 'difyai'
      AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
      AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
      GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
      GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
      VECTOR_STORE: weaviate
      WEAVIATE_ENDPOINT: http://weaviate:8080
      WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
      QDRANT_URL: http://qdrant:6333
      QDRANT_API_KEY: difyai123456
      QDRANT_CLIENT_TIMEOUT: 20
      QDRANT_GRPC_ENABLED: 'false'
      QDRANT_GRPC_PORT: 6334
      MILVUS_HOST: 127.0.0.1
      MILVUS_PORT: 19530
      MILVUS_USER: root
      MILVUS_PASSWORD: Milvus
      MILVUS_SECURE: 'false'
      MAIL_TYPE: ''
      MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
      SMTP_SERVER: ''
      SMTP_PORT: 465
      SMTP_USERNAME: ''
      SMTP_PASSWORD: ''
      SMTP_USE_TLS: 'true'
      SMTP_OPPORTUNISTIC_TLS: 'false'
      RESEND_API_KEY: ''
      RESEND_API_URL: https://api.resend.com
      RELYT_HOST: db
      RELYT_PORT: 5432
      RELYT_USER: postgres
      RELYT_PASSWORD: difyai123456
      RELYT_DATABASE: postgres
      PGVECTOR_HOST: pgvector
      PGVECTOR_PORT: 5432
      PGVECTOR_USER: postgres
      PGVECTOR_PASSWORD: difyai123456
      PGVECTOR_DATABASE: dify
      NOTION_INTEGRATION_TYPE: public
      NOTION_CLIENT_SECRET: you-client-secret
      NOTION_CLIENT_ID: you-client-id
      NOTION_INTERNAL_SECRET: you-internal-secret
      INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
    depends_on:
      - db
      - redis
    volumes:
      - ./volumes/app/storage:/app/api/storage
    networks:
      - ssrf_proxy_network
      - default

  web:
    image: langgenius/dify-web:0.6.10
    restart: always
    environment:
      CONSOLE_API_URL: ''
      APP_API_URL: ''
      SENTRY_DSN: ''
    networks: #追加
      - ssrf_proxy_network #追加
      - default #追加


  db:
    image: postgres:15-alpine
    restart: always
    environment:
      PGUSER: postgres
      POSTGRES_PASSWORD: difyai123456
      POSTGRES_DB: dify
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      #- ./volumes/db/data:/var/lib/postgresql/data
      - postgres_data:/var/lib/postgresql/data #変更
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 1s
      timeout: 3s
      retries: 30
    networks: #追加
      - default #追加

  redis:
    image: redis:6-alpine
    restart: always
    volumes:
      - ./volumes/redis/data:/data
    command: redis-server --requirepass difyai123456
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
    networks: #追加
      - default #追加

  weaviate:
    image: semitechnologies/weaviate:1.19.0
    restart: always
    volumes:
      - ./volumes/weaviate:/var/lib/weaviate
    environment:
      QUERY_DEFAULTS_LIMIT: 25
      AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'false'
      PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
      DEFAULT_VECTORIZER_MODULE: 'none'
      CLUSTER_HOSTNAME: 'node1'
      AUTHENTICATION_APIKEY_ENABLED: 'true'
      AUTHENTICATION_APIKEY_ALLOWED_KEYS: 'WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih'
      AUTHENTICATION_APIKEY_USERS: 'hello@dify.ai'
      AUTHORIZATION_ADMINLIST_ENABLED: 'true'
      AUTHORIZATION_ADMINLIST_USERS: 'hello@dify.ai'
    networks: #追加
      - default #追加

  sandbox:
    image: langgenius/dify-sandbox:0.2.1
    restart: always
    environment:
      API_KEY: dify-sandbox
      GIN_MODE: 'release'
      WORKER_TIMEOUT: 15
      ENABLE_NETWORK: 'true'
      HTTP_PROXY: 'http://ssrf_proxy:3128'
      HTTPS_PROXY: 'http://ssrf_proxy:3128'
      SANDBOX_PORT: 8194
    volumes:
      - ./volumes/sandbox/dependencies:/dependencies
    networks:
      - ssrf_proxy_network

  ssrf_proxy:
    image: ubuntu/squid:latest
    restart: always
    volumes:
      - ./volumes/ssrf_proxy/squid.conf:/etc/squid/squid.conf
    networks:
      - ssrf_proxy_network
      - default

  nginx:
    image: nginx:latest
    restart: always
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/proxy.conf:/etc/nginx/proxy.conf
      - ./nginx/conf.d:/etc/nginx/conf.d
    depends_on:
      - api
      - web
    ports:
      - "8080:80" #80:80から変更
    networks: #追加
      - default #追加

networks:
  ssrf_proxy_network:
    driver: bridge
    internal: true
  default: #追加
    driver: bridge 

volumes: #追加
  postgres_data: #追加
docker-compose.yamlの中身を可視化

※streamlit+graphvizで可視化してみた。

  1. あたらめて起動
PowerShell
# dockerコンテナを再構築して起動
# docker compose up -d 
  1. 無事起動!
shohei6117shohei6117

Dify+Ollamaでチャットボットを作る

ゴール

  • Ollamaで動くLlama3と連携したチャットボットを作る

まとめ

  • Difyはすごい!
    • ノーコードでLLMアプリを作れる
    • 作ったアプリをホストしてくれる
    • デバッグがしやすい
    • ログ管理やセッション管理までできる
  • LLMブロックを3段階重ねて、なんとかLlama3で日本語チャットができるようになった

参考リンク

手順

まず、DifyにOllamaで動くLlama3を登録する

  1. Ollamaを以下のbatファイルから起動する
    ※ 前提:ollamaにllama3がインストールされている
    ※ OLLAM_HOSTをシステム環境変数として登録してもよい
ollama起動バッチファイル
@echo off
set OLLAMA_HOST=0.0.0.0:11434
ollama serve
  1. Difyを起動して、アクセスする。(私の場合はhttp://localhost:8080/apps
  2. LLMモデルを登録する

つぎに、Difyでチャットボットを作る

  1. 下図のようにはじめる
    スタジオ最初から作成チャットボットChatflow→アプリ名はLlama3チャットボット
  2. ブロックを追加、連結、編集していく。
完成したフロー

全体フロー

日→英翻訳:ユーザー入力を英語に変換する

  • システムプロンプト
# INSTRUCTIONS
- Translate only the Japanese parts of the "USER INPUT" sentences into English.
- Output only the translated text.
- Do not include "Here is the translation of the Japanese part: " at the beginning of the output text.
- Ensure the translation captures the full meaning of the Japanese text without adding unnecessary context. 


# GOOD SAMPLE
- USER INPUT: "moonshot meanってどういう意味?"
- YOUR OUTPUT: "What does moonshot mean?"
 

# BAD SAMPLE
- USER INPUT: "テニスのルールを教えて"
- YOUR OUTPUT: "Translation of Japanese text to English\nThe translation of the Japanese text is as follows:\n\n\"Teaching tennis rules\"
 

# USER INPUT
{{#context#}}

メインブロック:回答を生成する

英→日翻訳:LLM出力を日本語に翻訳する


システムプロンプト

以下の文章を、忠実に日本語に翻訳して出力してください。
(ただし以下は日本語に変換しないこと:固有名詞、技術用語、プログラミングコード、製品名やブランド名、特定の業界用語や略語(例えば、IT業界の「API」や「SQL」など)、ファイル名やディレクトリ名、設定や構成項目の名前、ログメッセージやエラーメッセージ、数値や特定の単位(例えば、「GB」や「Hz」など)、メールアドレスやURL )

# 翻訳する文章  
{{#context#}}

出力:出力するだけ

  1. デバッグしながら、プロンプトやLLM設定(tempretureなど)を調整する
デバッグの様子

  1. アプリとして「公開する」
アプリを公開

アプリを実行を選択すると、webアプリページが開く。

Chrome拡張機能を使って、ウェブサイトに埋め込むこともできる
※動かないサイトも多い

  1. アプリ管理機能もある
アプリ管理機能

ログ&アナウンス

概要

メッセージ数、アクティブユーザー数、セッション数、トークン出力速度、トークン使用量など

  1. (追加)最初のメッセージを設定する
最初のメッセージを設定




shohei6117shohei6117

Dify+OllamaでRAGチャットボットを作る#1

ゴール

  • OllamaのモデルだけでRAGチャットボットを作れるようになる

まとめ

  • Ollamaで使える埋め込みモデルの日本語処理性能が悪い!→使えないので中止

関連リンク

埋め込みモデルの設定方法

Ollamaで使える埋め込みモデル一覧(2024-6-9時点)

mxbai-embed-largeモデルについて

サンプルFAQデータセット

手順

Difyにmxbai-embe-largeを登録する

  1. ollamaにモデルをpullする。
PowerShell
ollama pull mxbai-embed-large
  1. ollamaを起動する
Ollama起動batファイル
@echo off
set OLLAMA_HOST=0.0.0.0:11434
ollama serve
  1. Difyでモデルを設定する
    画面右上のアカウント名をクリック → モデルプロバイダーOllamaAdd model
モデル設定画面

※ model context sizeは公式サイト(下図)を参考に、512に設定した。

埋め込むデータを準備する

  1. LINEヤフーが公開している「子育てAIチャットボット用FAQデータセット」を利用する
  2. このサイトからZIPファイルをダウンロードして展開する
解凍したデータ

エクセル(xlsx)ファイルで、レコード数は981。

質問項目は以下のとおり。

  • 母子手帳・妊婦健診
  • 子どもの健診
  • 予防接種
  • 引っ越し手続き
  • 児童手当
  • 療育医療・育成医療・養育医療
  • 保育園・延長保育・一時保育
  • 子育て支援・イベント
  • その他の手続き(住民票、婚姻届など)

データを埋め込む

  1. システムモデル設定で、埋め込みモデルをmxdbai-embed-largeに設定しておく。

  2. Difyに取り込む
    画面上部のナレッジ知識を作成テキストファイルからインポート→回答したエクセルファイルをアップロードと進む(詳細は下記)

ファイルアップロードから埋め込みまでの流れ

ファイルをアップロード

テキストの前処理とクリーニング

すべて自動でおまかせする。

埋め込みの実行

1分くらいで終わる。

  1. 検索テストをしてみる
    画面上部→ナレッジ→埋め込み完了したデータセットを選択→サイドバーの検索テストをクリック
検索テストの結果

※top-Kは10に再設定した

  • 「母子手帳」で検索 →ダメ
  • 「児童手当」で検索 →ダメ
  • 「保育園に入れたい」で検索 →ダメ

全然ダメだ。。

比較:azure-openai text-embedding-3-largeで埋め込んだときの検索テスト結果

検索テスト結果

※top-Kは6に再設定した

  • 「母子手帳」で検索 →合格
  • 「児童手当」で検索 →合格
  • 「保育園に入れたい」で検索 →合格

非常に優秀

別のモデル(nomic-embe-text、snowflake-arctic-embed)も導入する

  1. Ollamaを停止
  2. 二つのモデルをpull
PowerShell
ollama pull nomic-embed-text
ollama pull snowflake-arctic-embed
  1. Ollmaを再起動
  2. Difyと連携
  • Model context sizenomic-embed-text8192snowflake-arctic-embed4096に設定した。
  1. データを埋め込む
  2. 検証テストをする
検証テスト結果(nomic-embed-text)
  • 「母子手帳」で検索 →ダメ
  • 「児童手当」で検索 →ダメ
  • 「保育園に入れたい」で検索 →ギリギリ合格
  • 「金属ごみの出し方を知りたい」で検索 →ダメ
  • 「粗大ごみの出し方」で検索 →ダメ

→**nomic-embed-textもダメ**

検証テスト結果(snowflake-arctic-embed)
  • 「母子手帳」で検索 →ダメ
  • 「児童手当」で検索 →ダメ
  • 「保育園に入れたい」で検索 →ダメ
  • 「金属ごみの出し方を知りたい」で検索 →ダメ
  • 「粗大ごみの出し方」で検索 →ギリギリ合格

→**snowflake-arctic-embedもダメ**

shohei6117shohei6117

Difyと一緒にOllamaもDockerで動かしてみる

ゴール

  • Difyのdocker-compose.yamlにOllamaも追記して、Docker上でOllamaを稼働させる
     ※現状はwindowsアプリとして起動させている

まとめ

  • 問題なく動いたが、現状CPUしか使えていない
    • GPUで動くようにするのはまた今度

関連リンク

手順

コンテナの再構築

  1. dify/dockerフォルダでPowerShellを起動して、Difyを停止する。
PowerShell
docker-compose down

※Docker Desktopの停止ボタンを押しても良い。
2. docker-compose.yamlを次のように書き替える

修正したdocker-compose.yaml
docker-compose.yaml
version: '3'
services:
  api:
    image: langgenius/dify-api:0.6.10
    restart: always
    environment:
      MODE: api
      LOG_LEVEL: INFO
      SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
      CONSOLE_WEB_URL: 'http://(DifyをホストするPCの静的IPを記載):8080' #追加
      INIT_PASSWORD: ''
      CONSOLE_API_URL: 'http://(DifyをホストするPCの静的IPを記載):8080' #追加
      SERVICE_API_URL: 'http://(DifyをホストするPCの静的IPを記載):8080' #追加
      APP_WEB_URL: 'http://(DifyをホストするPCの静的IPを記載):8080' #追加
      FILES_URL: 'http://(DifyをホストするPCの静的IPを記載):8080' #追加
      FILES_ACCESS_TIMEOUT: 300
      MIGRATION_ENABLED: 'true'
      DB_USERNAME: postgres
      DB_PASSWORD: difyai123456
      DB_HOST: db
      DB_PORT: 5432
      DB_DATABASE: dify
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_USERNAME: ''
      REDIS_PASSWORD: difyai123456
      REDIS_USE_SSL: 'false'
      REDIS_DB: 0
      CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
      WEB_API_CORS_ALLOW_ORIGINS: '*'
      CONSOLE_CORS_ALLOW_ORIGINS: '*'
      STORAGE_TYPE: local
      STORAGE_LOCAL_PATH: storage
      S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
      S3_BUCKET_NAME: 'difyai'
      S3_ACCESS_KEY: 'ak-difyai'
      S3_SECRET_KEY: 'sk-difyai'
      S3_REGION: 'us-east-1'
      AZURE_BLOB_ACCOUNT_NAME: 'difyai'
      AZURE_BLOB_ACCOUNT_KEY: 'difyai'
      AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
      AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
      GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
      GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
      VECTOR_STORE: weaviate
      WEAVIATE_ENDPOINT: http://weaviate:8080
      WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
      QDRANT_URL: http://qdrant:6333
      QDRANT_API_KEY: difyai123456
      QDRANT_CLIENT_TIMEOUT: 20
      QDRANT_GRPC_ENABLED: 'false'
      QDRANT_GRPC_PORT: 6334
      MILVUS_HOST: 127.0.0.1
      MILVUS_PORT: 19530
      MILVUS_USER: root
      MILVUS_PASSWORD: Milvus
      MILVUS_SECURE: 'false'
      RELYT_HOST: db
      RELYT_PORT: 5432
      RELYT_USER: postgres
      RELYT_PASSWORD: difyai123456
      RELYT_DATABASE: postgres
      PGVECTOR_HOST: pgvector
      PGVECTOR_PORT: 5432
      PGVECTOR_USER: postgres
      PGVECTOR_PASSWORD: difyai123456
      PGVECTOR_DATABASE: dify
      MAIL_TYPE: ''
      MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
      SMTP_SERVER: ''
      SMTP_PORT: 465
      SMTP_USERNAME: ''
      SMTP_PASSWORD: ''
      SMTP_USE_TLS: 'true'
      SMTP_OPPORTUNISTIC_TLS: 'false'
      RESEND_API_KEY: ''
      RESEND_API_URL: https://api.resend.com
      SENTRY_DSN: ''
      SENTRY_TRACES_SAMPLE_RATE: 1.0
      SENTRY_PROFILES_SAMPLE_RATE: 1.0
      NOTION_INTEGRATION_TYPE: public
      NOTION_CLIENT_SECRET: you-client-secret
      NOTION_CLIENT_ID: you-client-id
      NOTION_INTERNAL_SECRET: you-internal-secret
      CODE_EXECUTION_ENDPOINT: "http://sandbox:8194"
      CODE_EXECUTION_API_KEY: dify-sandbox
      CODE_MAX_NUMBER: 9223372036854775807
      CODE_MIN_NUMBER: -9223372036854775808
      CODE_MAX_STRING_LENGTH: 80000
      TEMPLATE_TRANSFORM_MAX_LENGTH: 80000
      CODE_MAX_STRING_ARRAY_LENGTH: 30
      CODE_MAX_OBJECT_ARRAY_LENGTH: 30
      CODE_MAX_NUMBER_ARRAY_LENGTH: 1000
      SSRF_PROXY_HTTP_URL: 'http://ssrf_proxy:3128'
      SSRF_PROXY_HTTPS_URL: 'http://ssrf_proxy:3128'
      INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
    depends_on:
      - db
      - redis
    volumes:
      - ./volumes/app/storage:/app/api/storage
    networks:
      - ssrf_proxy_network
      - default

  worker:
    image: langgenius/dify-api:0.6.10
    restart: always
    environment:
      CONSOLE_WEB_URL: ''
      MODE: worker
      LOG_LEVEL: INFO
      SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
      DB_USERNAME: postgres
      DB_PASSWORD: difyai123456
      DB_HOST: db
      DB_PORT: 5432
      DB_DATABASE: dify
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_USERNAME: ''
      REDIS_PASSWORD: difyai123456
      REDIS_DB: 0
      REDIS_USE_SSL: 'false'
      CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
      STORAGE_TYPE: local
      STORAGE_LOCAL_PATH: storage
      S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
      S3_BUCKET_NAME: 'difyai'
      S3_ACCESS_KEY: 'ak-difyai'
      S3_SECRET_KEY: 'sk-difyai'
      S3_REGION: 'us-east-1'
      AZURE_BLOB_ACCOUNT_NAME: 'difyai'
      AZURE_BLOB_ACCOUNT_KEY: 'difyai'
      AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
      AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
      GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
      GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
      VECTOR_STORE: weaviate
      WEAVIATE_ENDPOINT: http://weaviate:8080
      WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
      QDRANT_URL: http://qdrant:6333
      QDRANT_API_KEY: difyai123456
      QDRANT_CLIENT_TIMEOUT: 20
      QDRANT_GRPC_ENABLED: 'false'
      QDRANT_GRPC_PORT: 6334
      MILVUS_HOST: 127.0.0.1
      MILVUS_PORT: 19530
      MILVUS_USER: root
      MILVUS_PASSWORD: Milvus
      MILVUS_SECURE: 'false'
      MAIL_TYPE: ''
      MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
      SMTP_SERVER: ''
      SMTP_PORT: 465
      SMTP_USERNAME: ''
      SMTP_PASSWORD: ''
      SMTP_USE_TLS: 'true'
      SMTP_OPPORTUNISTIC_TLS: 'false'
      RESEND_API_KEY: ''
      RESEND_API_URL: https://api.resend.com
      RELYT_HOST: db
      RELYT_PORT: 5432
      RELYT_USER: postgres
      RELYT_PASSWORD: difyai123456
      RELYT_DATABASE: postgres
      PGVECTOR_HOST: pgvector
      PGVECTOR_PORT: 5432
      PGVECTOR_USER: postgres
      PGVECTOR_PASSWORD: difyai123456
      PGVECTOR_DATABASE: dify
      NOTION_INTEGRATION_TYPE: public
      NOTION_CLIENT_SECRET: you-client-secret
      NOTION_CLIENT_ID: you-client-id
      NOTION_INTERNAL_SECRET: you-internal-secret
      INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
    depends_on:
      - db
      - redis
    volumes:
      - ./volumes/app/storage:/app/api/storage
    networks:
      - ssrf_proxy_network
      - default

  web:
    image: langgenius/dify-web:0.6.10
    restart: always
    environment:
      CONSOLE_API_URL: ''
      APP_API_URL: ''
      SENTRY_DSN: ''
    networks: #追加
      - ssrf_proxy_network #追加
      - default #追加


  db:
    image: postgres:15-alpine
    restart: always
    environment:
      PGUSER: postgres
      POSTGRES_PASSWORD: difyai123456
      POSTGRES_DB: dify
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      #- ./volumes/db/data:/var/lib/postgresql/data
      - postgres_data:/var/lib/postgresql/data #変更
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 1s
      timeout: 3s
      retries: 30
    networks: #追加
      - default #追加

  redis:
    image: redis:6-alpine
    restart: always
    volumes:
      - ./volumes/redis/data:/data
    command: redis-server --requirepass difyai123456
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
    networks: #追加
      - default #追加

  weaviate:
    image: semitechnologies/weaviate:1.19.0
    restart: always
    volumes:
      - ./volumes/weaviate:/var/lib/weaviate
    environment:
      QUERY_DEFAULTS_LIMIT: 25
      AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'false'
      PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
      DEFAULT_VECTORIZER_MODULE: 'none'
      CLUSTER_HOSTNAME: 'node1'
      AUTHENTICATION_APIKEY_ENABLED: 'true'
      AUTHENTICATION_APIKEY_ALLOWED_KEYS: 'WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih'
      AUTHENTICATION_APIKEY_USERS: 'hello@dify.ai'
      AUTHORIZATION_ADMINLIST_ENABLED: 'true'
      AUTHORIZATION_ADMINLIST_USERS: 'hello@dify.ai'
    networks: #追加
      - default #追加

  sandbox:
    image: langgenius/dify-sandbox:0.2.1
    restart: always
    environment:
      API_KEY: dify-sandbox
      GIN_MODE: 'release'
      WORKER_TIMEOUT: 15
      ENABLE_NETWORK: 'true'
      HTTP_PROXY: 'http://ssrf_proxy:3128'
      HTTPS_PROXY: 'http://ssrf_proxy:3128'
      SANDBOX_PORT: 8194
    volumes:
      - ./volumes/sandbox/dependencies:/dependencies
    networks:
      - ssrf_proxy_network

  ssrf_proxy:
    image: ubuntu/squid:latest
    restart: always
    volumes:
      - ./volumes/ssrf_proxy/squid.conf:/etc/squid/squid.conf
    networks:
      - ssrf_proxy_network
      - default

  nginx:
    image: nginx:latest
    restart: always
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/proxy.conf:/etc/nginx/proxy.conf
      - ./nginx/conf.d:/etc/nginx/conf.d
    depends_on:
      - api
      - web
    ports:
      - "8080:80" #80:80から変更
    networks: #追加
      - default #追加

# ----------------------------------------
# 240609: Ollamaを追加
# ----------------------------------------
  ollama: #追加
    image: ollama/ollama
    restart: always
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama:/root/.ollama

networks:
  ssrf_proxy_network:
    driver: bridge
    internal: true
  default: #追加
    driver: bridge 

volumes: #追加
  postgres_data: #追加
  ollama: #追加
コンテナの関係を可視化

  1. Difyを再起動
PowerShell
# ollamaイメージをダウンロード
docker-compose pull ollama
# difyを再起動。
docker-compose up -d

OllamaにLlama3導入

  1. Docker上のollamaにllama3を導入
    ollamaコンテナに入る
PowerShell
docker exec -it ollama /bin/sh

ollamaコンテナでコマンドを実行

ollama pull llama3

Docker Desktopから簡単にアクセスできる

  1. Chrome拡張機能のollama-uiでLlama3が稼働していることを確認する
確認方法
  • ollama-uiを導入
  • 問題なければllama3モデルが選択できる
  • チャットもできた

DifyとOllama(Llama3)を連携

  1. Diryにアクセス
  2. 画面右上のアカウントをクリック⇒モデルプロバイダーOllamaAdd Model⇒下図のように設定

Difyで動作検証

  1. 既存チャットボットのモデルをOllmaのLlama3に切り替えて動かしてみた(割愛)
  2. やはりCPUしか使っていないのでレスポンスが遅い。。
    タスクマネージャーの画面
shohei6117shohei6117

DifyアプリにAPIアクセスする

ゴール

  • Dify APIエンドポイントにAPIリクエストを送信する

まとめ

  • Chrome拡張機能のTalend API TesterからのPOSTリクエストが成功した

関連リンク

手順

DifyチャットアプリのAPIキーを取得する

  1. Difyでチャットアプリを作る
  2. 概要からAPIキーを取得する
  3. ChromeブラウザにTalend API Tester拡張機能を導入する
  4. Dify公式docなどを参考に、下図のように設定する
参考にしたもの

Dify公式doc

Pythonでのリクエスト方法(公式doc)
import requests
import json

url = 'https://api.dify.ai/v1/chat-messages'
headers = {
    'Authorization': 'Bearer ENTER-YOUR-SECRET-KEY',
    'Content-Type': 'application/json',
}
data = {
    "inputs": {},
    "query": "eh",
    "response_mode": "streaming",
    "conversation_id": "1c7e55fb-1ba2-4e10-81b5-30addcea2276",
    "user": "abc-123"
}

response = requests.post(url, headers=headers, data=json.dumps(data))

print(response.json())

アプリのAPIアクセスページ

curl -X POST 'http://161.93.110.41:8080/v1/chat-messages' \
--header 'Authorization: Bearer {api_key}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "inputs": {},
    "query": "What are the specs of the iPhone 13 Pro Max?",
    "response_mode": "streaming",
    "conversation_id": "",
    "user": "abc-123",
    "files": [
      {
        "type": "image",
        "transfer_method": "remote_url",
        "url": "https://cloud.dify.ai/logo/logo-site.png"
      }
    ]
}'

BODYは次のとおり 
※会話IDは空欄
※テキストチャットなら"files"は不要

{
  "query": "こんにちは",
  "response_mode": "streaming",
  "conversation_id": "",
  "user": "abc-123",
  "inputs": {},
  "files": [
    {
      "type": "image",
      "transfer_method": "remote_url",
      "url": "https://cloud.dify.ai/logo/logo-site.png"
    }
  ]
}

  1. SENDを押す⇒成功!
shohei6117shohei6117

Dify+OllamaでRAGチャットボットを作る#2

ゴール

  • ローカルだけで完結するRAG検索チャットボットを作る

まとめ

  • ollama pullできる多言語対応埋め込みモデルがあったので作れたが、精度は悪く、実用には堪えない。

関連リンク

手順

  1. Ollamaトップページの検索窓でembedding multiみたいなキーワードを入力して検索する
  2. ヒットしたモデルのなかで、多言語対応の埋め込みモデルのparaphrase-multilingual-minilmと日本語LLMのFugaku-llmをollama pullする
PowerShell
ollama pull nextfire/paraphrase-multilingual-minilm
ollama run nebel/fugaku-llm:13b-instruct
  1. ollamaを起動する
  2. Difyに2つのモデルを登録する
Dify登録画面

paraphrase-multilingual-minilmを登録

Fugaku-llmの登録

  1. Difyでまずナレッジを埋め込む
  1. 埋め込みが完了したら、検索テストをしてみる
    頑張ってはいるが精度はいまいち。。
検索テストの結果



  1. RAGアプリを作る
    下図のようにつくった
アプリ作成画面

アプリ全体のアーキテクチャ

Fugaku-llmの詳細設定

  1. デバッグとプレビュー機能を使って検索してみる
検索結果


うーむ、使えたものじゃない。。

shohei6117shohei6117

Difyを0.6.10から0.6.12fix1にアップデートする

ゴール

  • Dify0.6.12fix1にバージョンアップする
  • 0.6.10環境のデータを引き継ぐ

まとめ

  • 0.6.12fix1は起動できたが、0.6.10環境のデータの引継ぎはできず。。
  • これまでのようにdocker-compose.yamlの内容をあれこれ触らなくても起動した。
    • ただしPostgresDBのデータ保管場所だけは従来と同じく変えた(後述)

関連リンク

手順

(背景)

  • 別のPCのDify0.6.10環境にDify0.6.12fixを上書きするインストールしたが、データ継承されなかった。
  • このPCのDify0.6.10環境は絶対壊したくないので、既存のDify0.6.10環境を残して、新たにDify0.6.12fix1環境を作った。以下はその手順。

PowerShellで実行するコマンド

powershell
# difyフォルダをコピー
cp dify dify_latest

# コピー先のdockerディレクトリに移動
cd dify_latest\docker\

# 手元のフォルダのタグを確認
git tag
# ⇒0.6.10までだった

# リモートのタグ情報を取得
git fetch --tags

# 再度タグを確認
git tag
# ⇒0.6.12fix1までになった

# mainブランチに切り替え
git checkout main

# リモートのmainブランチの最新内容を取得(=fetch+merge)
git pull origin main
# ⇒手元のdocker-compose.yamlをコミットしていないのでダメとエラーが出た

# docker-compose.yamlの変更を破棄
git checkout -- docker-compose.yaml
# ⇒docker-compose.yamlが上書きされるので、
#  docker-compose_0.6.10stable.yamlという名前にして、別のフォルダに保存する

# 改めてmainブランチの最新内容を取得
git pull origin main
# →今度はできた

# 手動でdocker-compose.yamlの中身を書き換える(後述)
# .env.sampleファイルを.envという名前に変えて、中身を書き換える(後述)

# コンテナをdify0_6_12という名前で起動
docker-compose -p dify0_6_12 up -d
# ⇒無事起動!
docker-compose.yaml
  db:
    volumes:
      # 変更後
      - postgres_data:/var/lib/postgresql/data #追加
      # 変更前
      # - ./volumes/db/data:/var/lib/postgresql/data

volumes:
  oradata:
  postgres_data: #追加
.env
# ------------------------------
# Common Variables
# ------------------------------
# ホストマシンのIPに変更
CONSOLE_API_URL=http://161.93.***.**:8880 #追加
CONSOLE_WEB_URL=http://161.93.***.**:8880 #追加
SERVICE_API_URL=http://161.93.***.**:8880 #追加
APP_API_URL=http://161.93.***.**:8880 #追加
APP_WEB_URL=http://161.93.***.**:8880 #追加
FILES_URL=http://161.93.***.**:8880 #追加

# ------------------------------
# Docker Compose Service Expose Host Port Configurations
# ------------------------------
EXPOSE_NGINX_PORT=8880 #80から変更
EXPOSE_NGINX_SSL_PORT=8443 #443から変更
shohei6117shohei6117

Firecrawlをセルフホストして、Difyで使う

ゴール

  • Firecrawlをセルフホストして、Difyと連携する
    • Firecrawlはサイトをクロールしてマークダウンに変換するツール
    • FirecrawlをDifyと連携させると、サイトデータをナレッジとして簡単に埋め込めるようになる

まとめ

  • Firecrawlをセルフホストできた
  • Difyと連携して、外部サイトデータ(githubリポジトリ)をナレッジにできた
  • しかし、社内サイト(SharePointOnlineサイト、OneDriveなど)はできなかった

関連リンク

手順

  1. FirecrawlをDockerから起動するまで
powershell
# リポジトリをクローン
git clone https://github.com/mendableai/firecrawl.git

# ディレクトリに移動
cd firecrawl

# 深い階層にある.env.sampleを現在のディレクトリに.envとしてコピー
cp ./apps/api/.env.example .env

# .envの中身を書き換える(後述)

# dockerコンテナを立てる
docker-compose build
#⇒かなり時間かかるが、待てば処理が終わる。

docker-compose up -d
#⇒かなり時間かかるが、無事起動!
  • GitHubリポジトリへのリンク
.env
.env
# ===== Required ENVS ======
NUM_WORKERS_PER_QUEUE=8 
PORT=3002
HOST=0.0.0.0

# 変更前
# REDIS_URL=redis://localhost:6379
# 変更後
REDIS_URL=redis://redis:6379

PLAYWRIGHT_MICROSERVICE_URL=http://playwright-service:3000/html

## To turn on DB authentication, you need to set up supabase.
# trueから変更
USE_DB_AUTHENTICATION=false

# ===== Optional ENVS ======

# Supabase Setup (used to support DB authentication, advanced logging, etc.)
# 変更後
SUPABASE_ANON_TOKEN=dummy_token 
SUPABASE_URL=http://dummy_url
SUPABASE_SERVICE_TOKEN=dummy_service_token


# Other Optionals
# 変更前
# TEST_API_KEY= # use if you've set up authentication and want to test with a real API key
# 変更後
TEST_API_KEY=fc-test

RATE_LIMIT_TEST_API_KEY_SCRAPE= # set if you'd like to test the scraping rate limit
RATE_LIMIT_TEST_API_KEY_CRAWL= # set if you'd like to test the crawling rate limit
SCRAPING_BEE_API_KEY= #Set if you'd like to use scraping Be to handle JS blocking
OPENAI_API_KEY= # add for LLM dependednt features (image alt generation, etc.)
BULL_AUTH_KEY= @
LOGTAIL_KEY= # Use if you're configuring basic logging with logtail
LLAMAPARSE_API_KEY= #Set if you have a llamaparse key you'd like to use to parse pdfs
SERPER_API_KEY= #Set if you have a serper key you'd like to use as a search api
SLACK_WEBHOOK_URL= # set if you'd like to send slack server health status messages
POSTHOG_API_KEY= # set if you'd like to send posthog events like job logs
POSTHOG_HOST= # set if you'd like to send posthog events like job logs

STRIPE_PRICE_ID_STANDARD=
STRIPE_PRICE_ID_SCALE=
STRIPE_PRICE_ID_STARTER=
STRIPE_PRICE_ID_HOBBY=
STRIPE_PRICE_ID_HOBBY_YEARLY=
STRIPE_PRICE_ID_STANDARD_NEW=
STRIPE_PRICE_ID_STANDARD_NEW_YEARLY=
STRIPE_PRICE_ID_GROWTH=
STRIPE_PRICE_ID_GROWTH_YEARLY=

HYPERDX_API_KEY=
HDX_NODE_BETA_MODE=1

FIRE_ENGINE_BETA_URL= # set if you'd like to use the fire engine closed beta

# Proxy Settings for Playwright (Alternative you can can use a proxy service like oxylabs, which rotates IPs for you on every request)
PROXY_SERVER=
PROXY_USERNAME=
PROXY_PASSWORD=
# set if you'd like to block media requests to save proxy bandwidth
BLOCK_MEDIA=

# Set this to the URL of your webhook when using the self-hosted version of FireCrawl
SELF_HOSTED_WEBHOOK_URL=

# Resend API Key for transactional emails
RESEND_API_KEY=
  • ブラウザから起動を確認する
    • http://localhost:3002/ ⇒SCRAPERS-JS: Hello, world! Fly.ioと表示される
    • http://host.docker.internal:3002/ ⇒SCRAPERS-JS: Hello, world! Fly.ioと表示される
    • http://localhost:3002/test ⇒Hello, world!が表示される
    • http://host.docker.internal:3002/test ⇒Hello, world!が表示される
  1. Difyと連携する
  • 設定項目
    • API Key: fc-test
    • Base URL: http://host.docker.internal:3002
画面キャプチャ
  • Difyトップ画面 ⇒ナレッジ ⇒ウェブサイトから同期 ⇒設定:データベース ⇒ FireCrawlのConfigureを選択
  • 以下のように設定
  • 成功!
  1. ウェブサイトをナレッジにしてみる
  • GitHubリポジトリはできた
  • 社内サイト(SharePointOnlineサイト、OneNoteなど)はクロールできず。。
画面キャプチャ
  • Difyリポジトリをナレッジにしてみる


    ※以下割愛
shohei6117shohei6117

Langfuseをセルフホストして、Difyで使う #1

ゴール

  • Langfuseをセルフホストする
  • LangfuseとDifyを連携して、DifyアプリをLangfuseでトレースする

まとめ

  • セルフホストは簡単にできた(http://localhost:3000
  • ただしDifyはhttps通信でないと連携できない!⇒ 次回に続く

関連リンク

手順

  1. Langfuseを起動する
PowerShell
# Langfuseリポジトリをcloneする
git clone https://github.com/langfuse/langfuse.git

# langufuseフォルダに移動
cd langfuse

# docker-compose.yamlをすこし書き換える(後述)

# langfuseを起動
docker-compose up -d
# ⇒特に問題なく起動!
docker-compose.yml
docker-compose.yml
services:
  langfuse-server:
    image: langfuse/langfuse:2
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://postgres:postgres@db:5432/postgres
      - NEXTAUTH_SECRET=mysecret
      - SALT=mysalt
      # 変更前
      # - NEXTAUTH_URL=http://localhost:3000
      # 変更後(ホストするPCのIPアドレスに書き換える)
      - NEXTAUTH_URL=http://161.93.***.**:3000
      - TELEMETRY_ENABLED=${TELEMETRY_ENABLED:-true}
      - LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES=${LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES:-false}

  db:
    image: postgres
    restart: always
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 3s
      timeout: 3s
      retries: 10
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=postgres
    ports:
      - 5432:5432
    volumes:
      - database_data:/var/lib/postgresql/data

volumes:
  database_data:
    driver: local
  1. Langfuseにサインアップする
画面キャプチャ
  • ブラウザでlocalhost:3000にアクセスすると、サインイン画面になる。
  • まずはサインアップする
  • あらためてサインインすると、初期画面になった。
  1. Difyと連携する
  • セルフホストしているhttpサーバを指定するとエラーになる。。(今回はここまで)
shohei6117shohei6117

API経由でナレッジを操作する

ゴール

  • APIを使ってナレッジを操作できるようになる。

まとめ

  • 簡単にできた。これを使えば、ファイルの更新や追加があるたびに埋め込み処理を実行したり、自作のwebアプリ経由でナレッジを追加したりできる。
  • ただし、ナレッジ削除も簡単にできてしまうので注意が必要。

参考リンク

手順

  • 公式docはcURLコマンドのサンプルがあるので、これをPythonコードに書き換えて実行してみる。
  • いずれも問題なく実行できた。
ナレッジ一覧の取得
import requests
import json

# -------------------------------
# ユーザー設定
api_key = "dataset-**********" # APIキー
endpoint = "http://161.93.***:**:8880/v1/datasets?page=1&limit=20" # エンドポイント
# -------------------------------

headers = {"Authorization": f"Bearer {api_key}"}

# GETリクエストを送信
response = requests.get(endpoint, headers=headers)
response = response.json() # JSON形式に変換

# dataから、ナレッジのnameとidだけを取得して表示
for knowledge in response["data"]:
    print("="*100)
    print(f"Name: {knowledge['name']}")
    print(f"ID: {knowledge['id']}")
新規ナレッジの作成
import requests
import json

# -------------------------------
# ユーザー設定
api_key = "dataset-**********"
endpoint = "http://161.93.***:**:8880/v1/datasets"
new_knowledge_name = "API-Knowledge 5" # 新しいナレッジの名前
# -------------------------------

headers = {
    "Authorization": f"Bearer {api_key}",
    "Content-Type": "application/json"
}
payload = {"name": new_knowledge_name} 

# POSTリクエストを送信して新しいナレッジを作成
response = requests.post(endpoint, headers=headers, data=json.dumps(payload))
response = response.json()

# dataにstatusコードが含まれていないときだけ実行する
if "status" not in response:
    # dataから、ナレッジのnameとidだけを取得して表示
    print("="*100)
    print(f"Name: {response['name']}")
    print(f"ID: {response['id']}")
else:
    # data全体を見やすく表示
    print(json.dumps(response, indent=4))
既存ナレッジの削除
import requests
import json

# -------------------------------
# ユーザー設定
api_key = "dataset-**********" # APIキー
dataset_id = "******************" # 削除するナレッジのID
# -------------------------------

endpoint = f"http://161.93.***:**:8880/v1/datasets/{dataset_id}"
headers = {"Authorization": f"Bearer {api_key}"}

# DELETEリクエストを送信してナレッジを削除
response = requests.delete(endpoint, headers=headers)

# レスポンスを表示
if response.status_code == 204:
    print("Knowledge deleted successfully.")
else:
    print(f"Failed to delete knowledge. Status code: {response.status_code}")
ファイルからドキュメントを作成
import requests
import json

# -------------------------------
# ユーザー設定
api_key = "dataset-**********" # APIキー
dataset_id = "******************" # ドキュメントを追加するナレッジのID
file_path =  r"ファイルパス" # ドキュメントとして追加するファイルのパス
# -------------------------------


endpoint = f"http://161.93.***:**:8880/v1/datasets/{dataset_id}/document/create_by_file"
headers = {"Authorization": f"Bearer {api_key}"}

# 処理方法
# 自動埋め込みならこれだけ
process_rule = {"mode": "automatic"}
# カスタム埋め込みならこちらを使う
# process_rule = {
#     "mode": "custom"
#     "rules": {
#         "pre_processing_rules": [
#             {"id": "remove_extra_spaces", "enabled": True}, # 余分なスペースを削除
#             {"id": "remove_urls_emails", "enabled": False} # URLとメールアドレスを削除
#         ],
#         "segmentation": {"separator": "###", "max_tokens": 1000} # セグメントの設定
#     }
# }
data = {
    "indexing_technique": "high_quality", # インデックス技術
    "process_rule": process_rule # プロセスルール
}
files = {
    'file': open(file_path, 'rb'),
    'data': (None, json.dumps(data), 'application/json')
}

# POSTリクエストを送信して新しいドキュメントを作成
response = requests.post(endpoint, headers=headers, files=files)
response = response.json()

# 結果を見やすく表示
print(json.dumps(response, indent=4))
テキストからドキュメントを作成
import requests
import json

# -------------------------------
# ユーザー設定
api_key = "dataset-**********"
dataset_id = "******************" # ドキュメントを追加するナレッジのID
document_name = "Sample Document"
document_text = """生成AIの業務利用には以下の点に注意が必要です。
まず、生成AIが提供する情報の正確性や信頼性を常に確認してください。
生成AIは誤った情報を生成する可能性があるため、重要な決定に使用する前に専門家によるレビューが必要です。
次に、データのプライバシーとセキュリティを確保するため、適切なアクセス制御とデータ保護対策を講じてください。
また、生成AIの利用が法令や規制に準拠していることを確認することも重要です。
最後に、生成AIが生成するコンテンツの著作権や倫理的側面についても注意し、適切な利用範囲を守るようにしてください。
これらのポイントを遵守することで、生成AIの業務利用が効果的かつ安全になります。
"""
# -------------------------------

# APIエンドポイントURL
endpoint = f"http://161.93.***:**:8880/v1/datasets/{dataset_id}/document/create_by_text"
headers = {
    "Authorization": f"Bearer {api_key}",
    "Content-Type": "application/json"
}

# POSTデータを作成
payload = {
    "name": document_name,
    "text": document_text,
    "indexing_technique": "high_quality",
    "process_rule": {"mode": "automatic"}
}

# POSTリクエストを送信して新しいドキュメントを作成
response = requests.post(endpoint, headers=headers, data=json.dumps(payload))
response = response.json()

# 結果を見やすく表示
print(json.dumps(response, indent=4))

ナレッジのドキュメント一覧を取得
import requests
import json

# APIキーとdataset_idを設定
api_key = "dataset-ydCFZztP4M**************"
dataset_id = "9d93bf86-0354-4211-af2**********"

headers = {"Authorization": f"Bearer {api_key}"}
url_get_documents = f"http://161.93.+++.+++:8880/v1/datasets/{dataset_id}/documents"

response_get_documents = requests.get(url_get_documents, headers=headers)

if response_get_documents.status_code == 200:
    documents = response_get_documents.json()
    # print("Documents:", documents) # そのまま出力
    # print(json.dumps(documents, indent=4)) # 見やすく表示
    # "id"と"name"だけ出力
    print("Document ID and Name")
    for d in documents["data"]:
        print(d["id"], d["name"])
else:
    print(f"Failed to retrieve documents. Status code: {response_get_documents.status_code}")

ナレッジのドキュメントを削除
import requests

api_key = "dataset-ydCFZztP4MSgwa**********"
dataset_id = "9d93bf86-0354-4211-af20-89**********"
document_id = "****************"  # 削除するドキュメントのID

url_delete_document = f"http://161.93.+++.+++:8880/v1/datasets/{dataset_id}/documents/{document_id}"

headers = {"Authorization": f"Bearer {api_key}"}
response_delete_document = requests.delete(url_delete_document, headers=headers)

if response_delete_document.status_code == 204:
    print("Document deleted successfully.")
else:
    print(f"Failed to delete document. Status code: {response_delete_document.status_code}")

shohei6117shohei6117

Dify0.6.12fix1から0.6.14にアップデートする

ゴール

  • Dify0.6.14にアップデートする
  • Dify0.6.12fix1のデータを引き継ぐ

まとめ

  • スムーズにアップデートできた。データ引き継ぎも問題なし。

関連リンク

手順

PowerShellで実行するコマンド

powershell
# difyのdockerフォルダに移動して
docker-compose down

# ダウンロード済みのタグを確認
git tag
# ⇒0.6.13までだった

# リモートのタグ情報を取得
git fetch --tags

# 再度タグ確認
git tag
# ⇒0.6.14までになった

# mainブランチに切り替え
git checkout main

# リモートのmainブランチの最新内容をpull(=fetch+merge)
# ※git checkput main しているので git pull でもよい
git pull origin main
# ⇒手元のdocker-compose.yamlなどの更新がコミットされていないというエラーが出る
# ⇒docker-compose.yamlと.envファイルだけ「バックアップ」フォルダを作ってコピーしておく

# スタッシュする
git stash

# あらためてpull
# ※これもgit pullでよい
git pull origin main

# docker-compose.yamlと.envファイルを書き替える(後述)

# コンテナを起動
docker-compose up -d
# ※docker-compose -p dify0_6_14 up -dのようにコンテナ名を変えるとデータ継承されない
# ⇒無事起動!データも継承されている。
  • docker-compose.yamlと.envファイルの変更点:
docker-compose.yaml
###############
# 変更1箇所目
###############
  db:
    image: postgres:15-alpine
    restart: always
    environment:
      PGUSER: ${PGUSER:-postgres}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-difyai123456}
      POSTGRES_DB: ${POSTGRES_DB:-dify}
      PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
    volumes:
      # - ./volumes/db/data:/var/lib/postgresql/data #オリジナル
      - postgres_data:/var/lib/postgresql/data #追加

    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 1s
      timeout: 3s
      retries: 30
    ports: #追加(SQLツールからアクセスできるように)
      - "5432:5432" #追加

###############
# 変更2箇所目
###############
volumes:
  oradata: 
  postgres_data: #追加
.env
# ホストマシンのIPに変更
# ------------------------------
# Common Variables
# ------------------------------
CONSOLE_API_URL=http://161.93.+++.+++:8080
CONSOLE_WEB_URL=http://161.93.+++.+++:8080
SERVICE_API_URL=http://161.93.+++.+++:8080
APP_API_URL=http://161.93.+++.+++:8080
APP_WEB_URL=http://161.93.+++.+++:8080
FILES_URL=http://161.93.+++.+++:8080

# ------------------------------
# Docker Compose Service Expose Host Port Configurations
# ------------------------------
EXPOSE_NGINX_PORT=8080 #80から変更
EXPOSE_NGINX_SSL_PORT=8443 #443から変更
shohei6117shohei6117

DifyコンテナのPostgresデータベースにSQLツールから接続する

ゴール

  • DifyのPostgresデータベースにSQLツールのA5:SQL Mk2から接続する

まとめ

  • 簡単にできた。
  • DBに格納されているデータに簡単にアクセスできるようになった。

参考リンク

Difyが動かしている3つのデータベースについて
  1. Postgresデータベース(dbサービス)

Postgresデータベースには、Difyアプリケーションに関連する多くの永続的なデータが格納されます。
具体的には以下のような情報が含まれます。

  • ユーザーデータ: ユーザーアカウント、プロフィール情報、認証情報など。
  • アプリケーションデータ: アプリケーション設定、構成情報、使用状況ログなど。
  • メッセージデータ: チャットや会話のログ、メッセージの履歴など。
  • APIトークン: 外部サービスとの連携に使用されるAPIトークン。
  • アノテーションデータ: アノテーションに関連する設定や履歴。
  • ワークフローデータ: ワークフローの定義や実行履歴。

  1. Redis(redisサービス)

Redisはインメモリデータベースで、高速アクセスが必要なデータのキャッシュやセッション情報の格納に使用されます。具体的には以下のような情報が含まれます。

  • セッションデータ: ユーザーのセッション情報、ログイン状態など。
  • キャッシュデータ: 頻繁にアクセスされるデータのキャッシュ(例: ユーザー設定やアプリケーション設定)。
  • キュー: ジョブキューやタスクキュー(Celeryなどのバックエンドタスク処理で使用)。

  1. Weaviate(weaviateサービス)

Weaviateはベクトル検索エンジンで、ベクトルデータや意味的検索に関連する情報を格納します。具体的には以下のような情報が含まれます。

  • ベクトルデータ: テキストやその他のデータのベクトル表現。
  • メタデータ: 各ベクトルに関連するメタデータ(例: ドキュメントIDやその他の関連情報)。
  • 検索インデックス: 効率的なベクトル検索をサポートするためのインデックス。

手順

  1. docker-compose.yamlに外部ポート開放設定を追加
docker-compose.yaml
  # The postgres database.
  db:
    image: postgres:15-alpine
    restart: always
    environment:
      PGUSER: ${PGUSER:-postgres}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-difyai123456}
      POSTGRES_DB: ${POSTGRES_DB:-dify}
      PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
    volumes:
      # 変更後
      # 名前付きボリューム postgres_data をコンテナ内のディレクトリ /var/lib/postgresql/data にマウントします。
      - postgres_data:/var/lib/postgresql/data #追加
      # オリジナルは下記
      # ./volumes/db/data をコンテナ内のディレクトリ /var/lib/postgresql/data にマウントします。
      # - ./volumes/db/data:/var/lib/postgresql/data
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 1s
      timeout: 3s
      retries: 30
    ports: #追加
      - "5433:5432" #追加 5432でなく5433を使います!
  1. コンテナをdocker-compose up -dなどで起動。
  2. A5:SQL Mk2を起動して、以下のように設定する。


.env設定を変えていないならば、

  • データベース名:dify
  • ユーザーID:postgres
  • パスワード:difyai123456

⇒設定が正しいかは、「テスト接続」ですぐ確認できる。

  1. 接続すると、publicスキーマにあるテーブルに各種データが格納されていることがわかる。
  • accountsテーブル
    • Difyアカウント情報(id、登録名、メールアドレス、登録日など)
  • appsテーブル
    • アプリ情報(アプリid、アプリ名、テナントid、作成日など)
  • datasetsテーブル
    • ナレッジのデータセット情報(id、ファイル名、埋め込み方法など)
  • documentsテーブル
    • ナレッジに格納しているドキュメント情報
  • end_usersテーブル
    • Difyアプリを使ったユーザー情報(利用したアプリid、登録日など)
  • messagesテーブル
    • チャット履歴(id、アプリid、会話id、クエリ、トークン数、ユーザーid(from_end_user_id、from_account_idのいずれか)、作成日など)

shohei6117shohei6117

ベクトルデータベースとの接続トラブル対処記録

ゴール

  • ベクトルデータベース(weaviate)とDify本体(sandbox)が通信できない不具合を解消する。

まとめ

  • middlewareコンテナを停止、再起動したら解消した。
    • ⇒ middlewareの何が悪かったのかは未解明。

手順

  • 前日まで問題なく動いていたが、朝から次の症状が出た
    • ナレッジの埋め込みはできるが、データベースに登録できない
    • RAGアプリでナレッジ検索ブロックでデータベースに接続できない
  • 確認したこと
    • ログ ⇒問題ない
    • ストレージ ⇒十分余裕がある
    • ファイル ⇒壊れていない
    • Dify本体コンテナの停止、再起動 ⇒症状改善しない
    • Dify本体をバージョンアップ(0.6.14⇒0.6.15)⇒症状改善しない
    • Dify-middlewareを停止、再起動 ⇒ 症状改善した
shohei6117shohei6117

Dify0.6.15から0.7.0にアップデートする

ゴール

  • Dify0.7.0にアップデートする

まとめ

  • スムーズにアップデートできた。データ引き継ぎも問題なし。
  • middlewareは変化なしだったのでそのまま稼働中。

関連リンク

手順

powershell
# difyのdockerフォルダに移動して、起動中の環境を落とす
docker-compose down

# いまのdocker-compose.yamlとか.envファイルを別フォルダにコピー(バックアップ)する
# データバックアップはしない

# 最新バージョンをpullするために、現在のフォルダ状態をスタッシュ
git stash

# mainブランチに切り替え
git checkout main

# リモートのタグ情報を取得
git fetch --tags

# タグ確認
git tag
# ⇒0.7.0まであることを確認

# 最新バージョンをpull
git pull origin main

# docker-compose.yamlと.envファイルを書き換える(後述)

# コンテナを起動
docker-compose up -d
  • docker-compose.yamlと.envファイルの変更点:
docker-compose.yaml

### 変更1箇所目 #################################
  # The postgres database.
  db:
    image: postgres:15-alpine
    restart: always
    environment:
      PGUSER: ${PGUSER:-postgres}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-difyai123456}
      POSTGRES_DB: ${POSTGRES_DB:-dify}
      PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
    command: >
      postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}'
               -c 'shared_buffers=${POSTGRES_SHARED_BUFFERS:-128MB}'
               -c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
               -c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
               -c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}'
    volumes:
      # - ./volumes/db/data:/var/lib/postgresql/data #オリジナル
      - postgres_data:/var/lib/postgresql/data #追加
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 1s
      timeout: 3s
      retries: 30

### 変更2箇所目 #################################
volumes:
  oradata:
  dify_es01_data:
  postgres_data: #追加

.env
# ホストマシンのIPに変更
# ------------------------------
# Common Variables
# ------------------------------
CONSOLE_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
CONSOLE_WEB_URL=http://161.93.+++.++:8880 #オリジナルは空欄
SERVICE_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
APP_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
APP_WEB_URL=http://161.93.+++.++:8880 #オリジナルは空欄
FILES_URL=http://161.93.+++.++:8880 #オリジナルは空欄

# ------------------------------
# Docker Compose Service Expose Host Port Configurations
# ------------------------------
EXPOSE_NGINX_PORT=8880 #オリジナルは80
EXPOSE_NGINX_SSL_PORT=8443 #オリジナルは443
shohei6117shohei6117

Firecrawlをセルフホストして、Difyで使う #2

ゴール

  • Dify0.7.0にバージョンアップしたら動かなくなったFirecrawlを使ったチャットボットを再び動かす

まとめ

  • 次のブロックに渡すFirecrawlの出力をtextからjsonに変更して復活させた
    • textだと空データが出力されてしまう

関連リンク

手順

  1. CRAWLブロックの次のブロックに渡す変数を textからjsonに変更した。
  2. また次のテンプレートブロックで、最大1万文字でカットオフする。
{{ json[0].data|map(attribute='content')|join(' ')|truncate(10000, true, '') }}
  1. 無事復活した。
shohei6117shohei6117

Difyを0.8.3にアップデートする

ゴール

  • APIキーのロードバランシングもできるようにする 参考記事

まとめ

  • スムーズにアップデートできた。データ引き継ぎも問題なし。
  • ロードバランシング機能も有効化できた。(まだ有効にはしていない)

関連リンク

手順

powershell
# difyのdockerフォルダに移動して、起動中の環境を落とす
docker-compose down

# いまのdocker-compose.yamlとか.envファイルを別フォルダにコピー(バックアップ)する
# データバックアップはしない

# 最新バージョンをpullするために、現在のフォルダ状態をスタッシュ
git stash

# mainブランチに切り替え
git checkout main

# リモートのタグ情報を取得
git fetch --tags

# タグ確認
git tag
# ⇒0.8.3まであることを確認

# 最新バージョンをpull
git pull origin main

# docker-compose.yamlと.envファイルを書き換える(後述)

# コンテナを起動
docker-compose up -d
  • docker-compose.yamlと.envファイルの変更点:
docker-compose.yaml

### 変更1箇所目 #################################
# ロードバランシングを有効化するため

x-shared-env: &shared-api-worker-env
  LOG_LEVEL: ${LOG_LEVEL:-INFO}
  LOG_FILE: ${LOG_FILE:-}
 ## 途中省略 ##
  SSRF_PROXY_HTTP_URL: ${SSRF_PROXY_HTTP_URL:-http://ssrf_proxy:3128}
  SSRF_PROXY_HTTPS_URL: ${SSRF_PROXY_HTTPS_URL:-http://ssrf_proxy:3128}
  MODEL_LB_ENABLED: "true"  # 追加(ロードバランシングを有効化)

### 変更2,3箇所目 #################################
  # The postgres database.
  db:
    image: postgres:15-alpine
    restart: always
    environment:
      PGUSER: ${PGUSER:-postgres}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-difyai123456}
      POSTGRES_DB: ${POSTGRES_DB:-dify}
      PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
    command: >
      postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}'
               -c 'shared_buffers=${POSTGRES_SHARED_BUFFERS:-128MB}'
               -c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
               -c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
               -c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}'
    volumes:
      # - ./volumes/db/data:/var/lib/postgresql/data #オリジナル
      - postgres_data:/var/lib/postgresql/data #追加(こうしないとエラーになるから)
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 1s
      timeout: 3s
      retries: 30
    ports: #追加
      - "5432:5432" #追加(SQLツールからの接続用)

### 変更4箇所目 #################################
volumes:
  oradata:
  dify_es01_data:
  postgres_data: #追加

.env
# ホストマシンのIPに変更
# ------------------------------
# Common Variables
# ------------------------------
CONSOLE_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
CONSOLE_WEB_URL=http://161.93.+++.++:8880 #オリジナルは空欄
SERVICE_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
APP_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
APP_WEB_URL=http://161.93.+++.++:8880 #オリジナルは空欄
FILES_URL=http://161.93.+++.++:8880 #オリジナルは空欄

# ------------------------------
# Docker Compose Service Expose Host Port Configurations
# ------------------------------
EXPOSE_NGINX_PORT=8880 #オリジナルは80
EXPOSE_NGINX_SSL_PORT=8443 #オリジナルは443
shohei6117shohei6117

セルフホストしているFirecrawlをv0からv1にアップデートする#1

ゴール

  • ローカルPCでセルフホストしているFirecrawlをv0からv1にアップグレードする
  • Difyを0.8.3にアップデートしたらFirecrawlツールが使えなくなったため、とりあえずやってみる。

まとめ

  • v0のときと症状は変わらず。Difyでナレッジ作成はできるが、ツールが使えない。
  • (11/9追記)再構築したら治った
ナレッジ作成画面(問題なし)

改善前の症状

ツール(4種類)でエラーが出るのは解消せず。

認証はされているようだが、、

⇒認証を再設定しようとするとエラーが出る

関連リンク

手順

  • 最新バージョンをgithubからpull
  • .envファイルを書き換えて、コンテナをbuild&up
powershell
# firecrawlフォルダに移動して、起動中の環境を落とす
docker-compose down

# いまのdocker-compose.yamlと.envファイルを別フォルダにコピー(バックアップ)する
# データバックアップはしない

# 最新バージョンをpullするために、現在のフォルダ状態をスタッシュ
git stash

# mainブランチに切り替え
git checkout main

# リモートのタグ情報を取得
git fetch --tags

# タグ確認
git tag
# ⇒v1まであることを確認

# 最新バージョンをpull
git pull origin main

# .envファイルを書き換える(後述)
# docker-compose.yamlは書き換えるところなし

# buildする
docker-compose build
# ⇒時間かかる。待つ。

# コンテナを起動する
docker-compose up -d

無事起動

.envファイル(変更あり)

.env
.env
# ===== Required ENVS ======
NUM_WORKERS_PER_QUEUE=8
PORT=3002
HOST=0.0.0.0
REDIS_URL=redis://redis:6379 #for self-hosting using docker, use redis://redis:6379. For running locally, use redis://localhost:6379
REDIS_RATE_LIMIT_URL=redis://redis:6379 #for self-hosting using docker, use redis://redis:6379. For running locally, use redis://localhost:6379
PLAYWRIGHT_MICROSERVICE_URL=http://playwright-service:3000/html

## To turn on DB authentication, you need to set up supabase.
# USE_DB_AUTHENTICATION=true #オリジナル
USE_DB_AUTHENTICATION=false #変更後

# ===== Optional ENVS ======

# SearchApi key. Head to https://searchapi.com/ to get your API key
SEARCHAPI_API_KEY=
# SearchApi engine, defaults to google. Available options: google, bing, baidu, google_news, etc. Head to https://searchapi.com/ to explore more engines
SEARCHAPI_ENGINE=

# Supabase Setup (used to support DB authentication, advanced logging, etc.)
SUPABASE_ANON_TOKEN=
SUPABASE_URL=
SUPABASE_SERVICE_TOKEN=

# Other Optionals
# use if you've set up authentication and want to test with a real API key
TEST_API_KEY=fc-test #追加
# set if you'd like to test the scraping rate limit
RATE_LIMIT_TEST_API_KEY_SCRAPE=
# set if you'd like to test the crawling rate limit
RATE_LIMIT_TEST_API_KEY_CRAWL=
# set if you'd like to use scraping Be to handle JS blocking
SCRAPING_BEE_API_KEY=
# add for LLM dependednt features (image alt generation, etc.)
OPENAI_API_KEY=
BULL_AUTH_KEY=@
# set if you have a llamaparse key you'd like to use to parse pdfs
LLAMAPARSE_API_KEY=
# set if you'd like to send slack server health status messages
SLACK_WEBHOOK_URL=
# set if you'd like to send posthog events like job logs
POSTHOG_API_KEY=
# set if you'd like to send posthog events like job logs
POSTHOG_HOST=

STRIPE_PRICE_ID_STANDARD=
STRIPE_PRICE_ID_SCALE=
STRIPE_PRICE_ID_STARTER=
STRIPE_PRICE_ID_HOBBY=
STRIPE_PRICE_ID_HOBBY_YEARLY=
STRIPE_PRICE_ID_STANDARD_NEW=
STRIPE_PRICE_ID_STANDARD_NEW_YEARLY=
STRIPE_PRICE_ID_GROWTH=
STRIPE_PRICE_ID_GROWTH_YEARLY=

# set if you'd like to use the fire engine closed beta
FIRE_ENGINE_BETA_URL=

# Proxy Settings for Playwright (Alternative you can can use a proxy service like oxylabs, which rotates IPs for you on every request)
PROXY_SERVER=
PROXY_USERNAME=
PROXY_PASSWORD=
# set if you'd like to block media requests to save proxy bandwidth
BLOCK_MEDIA=

# Set this to the URL of your webhook when using the self-hosted version of FireCrawl
SELF_HOSTED_WEBHOOK_URL=

# Resend API Key for transactional emails
RESEND_API_KEY=

# LOGGING_LEVEL determines the verbosity of logs that the system will output.
# Available levels are:
# NONE - No logs will be output.
# ERROR - For logging error messages that indicate a failure in a specific operation.
# WARN - For logging potentially harmful situations that are not necessarily errors.
# INFO - For logging informational messages that highlight the progress of the application.
# DEBUG - For logging detailed information on the flow through the system, primarily used for debugging.
# TRACE - For logging more detailed information than the DEBUG level.
# Set LOGGING_LEVEL to one of the above options to control logging output.
LOGGING_LEVEL=INFO

docker-compose.yamlファイル(変更していません)

docker-compose.yaml
docker-compose.yaml
name: firecrawl

x-common-service: &common-service
  build: apps/api
  networks:
    - backend
  extra_hosts:
    - "host.docker.internal:host-gateway"

services:
  playwright-service:
    build: apps/playwright-service
    environment:
      - PORT=3000
      - PROXY_SERVER=${PROXY_SERVER}
      - PROXY_USERNAME=${PROXY_USERNAME}
      - PROXY_PASSWORD=${PROXY_PASSWORD}
      - BLOCK_MEDIA=${BLOCK_MEDIA}
    networks:
      - backend

  api:
    <<: *common-service
    environment:
      REDIS_URL: ${REDIS_URL:-redis://redis:6379}
      REDIS_RATE_LIMIT_URL: ${REDIS_URL:-redis://redis:6379}
      PLAYWRIGHT_MICROSERVICE_URL: ${PLAYWRIGHT_MICROSERVICE_URL:-http://playwright-service:3000}
      USE_DB_AUTHENTICATION: ${USE_DB_AUTHENTICATION}
      PORT: ${PORT:-3002}
      NUM_WORKERS_PER_QUEUE: ${NUM_WORKERS_PER_QUEUE}
      OPENAI_API_KEY: ${OPENAI_API_KEY}
      OPENAI_BASE_URL: ${OPENAI_BASE_URL}
      MODEL_NAME: ${MODEL_NAME:-gpt-4o}
      SLACK_WEBHOOK_URL: ${SLACK_WEBHOOK_URL}
      LLAMAPARSE_API_KEY: ${LLAMAPARSE_API_KEY}
      LOGTAIL_KEY: ${LOGTAIL_KEY}
      BULL_AUTH_KEY: ${BULL_AUTH_KEY}
      TEST_API_KEY: ${TEST_API_KEY}
      POSTHOG_API_KEY: ${POSTHOG_API_KEY}
      POSTHOG_HOST: ${POSTHOG_HOST}
      SUPABASE_ANON_TOKEN: ${SUPABASE_ANON_TOKEN}
      SUPABASE_URL: ${SUPABASE_URL}
      SUPABASE_SERVICE_TOKEN: ${SUPABASE_SERVICE_TOKEN}
      SCRAPING_BEE_API_KEY: ${SCRAPING_BEE_API_KEY}
      HOST: ${HOST:-0.0.0.0}
      SELF_HOSTED_WEBHOOK_URL: ${SELF_HOSTED_WEBHOOK_URL}
      LOGGING_LEVEL: ${LOGGING_LEVEL}
      FLY_PROCESS_GROUP: app
    depends_on:
      - redis
      - playwright-service
    ports:
      - "3002:3002"
    command: [ "pnpm", "run", "start:production" ]

  worker:
    <<: *common-service
    environment:
      REDIS_URL: ${REDIS_URL:-redis://redis:6379}
      REDIS_RATE_LIMIT_URL: ${REDIS_URL:-redis://redis:6379}
      PLAYWRIGHT_MICROSERVICE_URL: ${PLAYWRIGHT_MICROSERVICE_URL:-http://playwright-service:3000}
      USE_DB_AUTHENTICATION: ${USE_DB_AUTHENTICATION}
      PORT: ${PORT:-3002}
      NUM_WORKERS_PER_QUEUE: ${NUM_WORKERS_PER_QUEUE}
      OPENAI_API_KEY: ${OPENAI_API_KEY}
      OPENAI_BASE_URL: ${OPENAI_BASE_URL}
      MODEL_NAME: ${MODEL_NAME:-gpt-4o}
      SLACK_WEBHOOK_URL: ${SLACK_WEBHOOK_URL}
      LLAMAPARSE_API_KEY: ${LLAMAPARSE_API_KEY}
      LOGTAIL_KEY: ${LOGTAIL_KEY}
      BULL_AUTH_KEY: ${BULL_AUTH_KEY}
      TEST_API_KEY: ${TEST_API_KEY}
      POSTHOG_API_KEY: ${POSTHOG_API_KEY}
      POSTHOG_HOST: ${POSTHOG_HOST}
      SUPABASE_ANON_TOKEN: ${SUPABASE_ANON_TOKEN}
      SUPABASE_URL: ${SUPABASE_URL}
      SUPABASE_SERVICE_TOKEN: ${SUPABASE_SERVICE_TOKEN}
      SCRAPING_BEE_API_KEY: ${SCRAPING_BEE_API_KEY}
      HOST: ${HOST:-0.0.0.0}
      SELF_HOSTED_WEBHOOK_URL: ${SELF_HOSTED_WEBHOOK_URL}
      LOGGING_LEVEL: ${LOGGING_LEVEL}
      FLY_PROCESS_GROUP: worker
    depends_on:
      - redis
      - playwright-service
      - api
    command: [ "pnpm", "run", "workers" ]

  redis:
    image: redis:alpine
    networks:
      - backend
    command: redis-server --bind 0.0.0.0

networks:
  backend:
    driver: bridge
shohei6117shohei6117

Dify0.9.0でRAG検索できないエラー発生

ゴール

  • 0.8.3から0.9.0にアップデートしたら知識獲得ツールでエラーが出るようになったのを対処する。

    Run failed: '<' not supported between instances of 'NoneType' and 'NoneType'

まとめ

  • 0.9.0から0.9.1にアップデートしたら治った。

参考リンク

手順

shohei6117shohei6117

Dify0.10.0にアップデートする

ゴール

  • 0.10.0にアップデートする

まとめ

  • スムーズにアップデートできた。データ引き継ぎも問題なし。

参考リンク

手順

  • いつもは単なる最新版へのupdateだが、今回は0.10.0bata2から0.10.0にする
powershell
# firecrawlフォルダに移動して、起動中の環境を落とす
docker-compose down

# いまのdocker-compose.yamlと.envファイルを別フォルダにコピー(バックアップ)する
# データバックアップはしない

# 最新バージョンをpullするために、現在のフォルダ状態をスタッシュ
git stash

# mainブランチに切り替え
git checkout main

# リモートのタグ情報を取得
git fetch --tags

# タグ確認
git tag
# ⇒0.10.0まであることを確認

# 最新バージョンまでpull
git pull origin main

# ===最新版にするだけなら不要(ここから)===
# 0.10.0タグに切り替え
git checkout tags/0.10.0
# ===最新版にするだけなら不要(ここまで)===

# docker-compose.yamlと.envファイルを書き換える(後述)

# コンテナを起動する
docker-compose up -d

⇒無事起動。

  • docker-compose.yamlと.envファイルの変更点:
docker-compose.yaml
### 変更1箇所目 #################################
# ロードバランシングを有効化するため

x-shared-env: &shared-api-worker-env
  LOG_LEVEL: ${LOG_LEVEL:-INFO}
  LOG_FILE: ${LOG_FILE:-}
 ## 途中省略 ##
  SSRF_PROXY_HTTP_URL: ${SSRF_PROXY_HTTP_URL:-http://ssrf_proxy:3128}
  SSRF_PROXY_HTTPS_URL: ${SSRF_PROXY_HTTPS_URL:-http://ssrf_proxy:3128}
  MODEL_LB_ENABLED: "true"  # 追加(ロードバランシングを有効化)

### 変更2,3箇所目 #################################
  # The postgres database.
  db:
    image: postgres:15-alpine
    restart: always
    environment:
      PGUSER: ${PGUSER:-postgres}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-difyai123456}
      POSTGRES_DB: ${POSTGRES_DB:-dify}
      PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
    command: >
      postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}'
               -c 'shared_buffers=${POSTGRES_SHARED_BUFFERS:-128MB}'
               -c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
               -c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
               -c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}'
    volumes:
      # - ./volumes/db/data:/var/lib/postgresql/data #オリジナル
      - postgres_data:/var/lib/postgresql/data #追加(こうしないとエラーになるから)
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 1s
      timeout: 3s
      retries: 30
    ports: #追加
      - "5432:5432" #追加(SQLツールからの接続用)

### 変更4箇所目 #################################
volumes:
  oradata:
  dify_es01_data:
  postgres_data: #追加

.env
# ホストマシンのIPに変更
# ------------------------------
# Common Variables
# ------------------------------
CONSOLE_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
CONSOLE_WEB_URL=http://161.93.+++.++:8880 #オリジナルは空欄
SERVICE_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
APP_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
APP_WEB_URL=http://161.93.+++.++:8880 #オリジナルは空欄
FILES_URL=http://161.93.+++.++:8880 #オリジナルは空欄

# ------------------------------
# Docker Compose Service Expose Host Port Configurations
# ------------------------------
EXPOSE_NGINX_PORT=8880 #オリジナルは80
EXPOSE_NGINX_SSL_PORT=8443 #オリジナルは443
shohei6117shohei6117

Dify0.11.0にアップデートする

ゴール

  • 0.11.0にアップデートする

まとめ

  • middlewareを稼働させたままアップデートしたら、ナレッジのドキュメント取り込みができなくなった。(過去にもあった現象)
    • middlewareを停止して、Difyを再起動したら治った。
  • 並列イテレーションが実装されて、アプリが高速化した!

参考リンク

手順