30
37

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プロキシ環境下のローカルPCに "Dify" を導入して、Bedrockする

Posted at

はじめに

お疲れ様です。yuki_inkです。

今年のGWあたりからにわかに「Difyがすごいらしい」と話題になりましたが、今まで触れられていませんでした。

それから約1か月が経ち、ネット上の情報がかなり厚くなってきた今日この頃(界隈の皆さん強すぎですね)
ちょっと調べてみると、どうやらDifyはローカル環境でも動くらしいとのこと。
え、自社端末で使いたい!!
というモチベーションで色々やってみたという記事です。

やったこと

  1. WSL 導入
  2. Docker 導入
  3. Git 導入
  4. Dify 導入
  5. Dify で「ワイのかわりに検索くん」を作る
  6. 「ワイのかわりに検索くん」をBedrockする

前提条件

  • Windows10のPCで作業しています。
  • Docker Desktopは利用しません。
  • この記事ではプロキシの IP アドレスを 192.168.11.9、プロキシのポートを 3128 として説明します。
    この記事を参考にされる際は、実際のプロキシの情報に置き換えて設定してください。

(1) WSL 導入

以下の手順を参照して、PCにWSLを導入します。

私は Ubuntu 22.04.3 LTS を入れました。
image.png

取得したインストーラを実行するとこのような画面が開きます。
ここでユーザ名とパスワードを設定します。
image.png

私の環境では「Ubuntuインストール時に0.0%でスタック」する事象が発生してしまったので、記事に記述されている通りの対応を行い、無事WSLを導入できました。

管理者権限でpowershellに
wsl --update --web-download
↓実行
wsl --install --web-download
↓実行
とインストールが完了しユーザー名とパスワード入力後Ubuntuが起動しました。

PowerShellで wsl --list --verbose コマンドを実行し、導入したディストリビューションのステータスが Running となっていることを確認します。

> wsl --list --verbose
  NAME      STATE           VERSION
* Ubuntu    Running         2

【参考にした記事】

(2) Docker 導入

Ubuntu(WSL)へのプロキシ設定

スタート画面から先ほど取得した Ubuntu 22.04.3 LTS をクリックし、起動します。
image.png

とりあえず、Linux環境でよくあるプロキシ設定を入れておきます。
sudo -i コマンドでrootになって、/etc/profile の末尾に以下の記述を追記。

# http://<id>:<password>@X.X.X.X:<port番号>
PROXY='http://192.168.11.9:3128'

# httpおよびhttpsを使う際に参照するプロキシのURLを指定する
export http_proxy=$PROXY
export HTTP_PROXY=$PROXY
export https_proxy=$PROXY
export HTTPS_PROXY=$PROXY

# localhostやプロキシ内(社内イントラなど)に存在し、プロキシを経由させるべきでないものを指定する
export no_proxy=localhost,127.0.0.1
export NO_PROXY=${no_proxy}

source /etc/profile コマンドで設定を反映し、printenv | grep -i proxy コマンドで確認します。

# source /etc/profile

# printenv | grep -i proxy
http_proxy=http://192.168.11.9:3128
HTTP_PROXY=http://192.168.11.9:3128
https_proxy=http://192.168.11.9:3128
HTTPS_PROXY=http://192.168.11.9:3128
no_proxy=localhost,127.0.0.1
NO_PROXY=localhost,127.0.0.1

各環境変数にプロキシの値が入っていたらOK!

あわせて、後続手順で利用する apt コマンドがプロキシを通るように設定していきます。
/etc/apt/apt.conf を作成し、以下の通り記述します。

/etc/apt/apt.conf
Acquire::http::Proxy "http://192.168.11.9:3128";
Acquire::https::Proxy "http://192.168.11.9:3128";

ここで exit して、rootから抜けておきましょう。
一般ユーザに戻ったら、念のため、再度 source /etc/profile コマンドで設定を反映し、printenv | grep -i proxy コマンドで確認。

【参考にした記事】

Docker インストール

以下の手順を参照して、Dockerをインストールします。

  • 事前準備
  • Docker リポジトリの追加
  • Docker CE のインストール

インストールが完了しました~(3分クッキング感)

$ docker -v
Docker version 26.1.4, build 5650f9b

Docker 関連の設定

以下の手順を参考に、Dockerのプロキシの設定をします。

まず、mkdir コマンドでディレクトリを作っておきます。

$ sudo mkdir /etc/systemd/system/docker.service.d/
$ mkdir ~/.docker

続いて以下2つのファイルを作成します。

/etc/systemd/system/docker.service.d/override.conf
[Service]
Environment="HTTP_PROXY=http://192.168.11.9:3128"
Environment="HTTPS_PROXY=http://192.168.11.9:3128"
Environment="NO_PROXY=localhost,127.0.0.1"
~/.docker/config.json
{
  "proxies": {
    "default": {
      "httpProxy": "http://192.168.11.9:3128",
      "httpsProxy": "http://192.168.11.9:3128",
      "noProxy": "localhost,127.0.0.1"
    }
  }
}

以下のコマンドで設定反映 & Docker を再起動し、設定が適切に反映されていることを確認します。
ついでに、「sudoなしでdockerコマンドを実行できるようにする」ために sudo usermod -a -G docker (ユーザ名) コマンドを実行しておきます。

$ sudo systemctl daemon-reload

$ sudo systemctl restart docker

$ sudo systemctl show --property=Environment docker
Environment=HTTP_PROXY=http://192.168.11.9:3128 HTTPS_PROXY=http://192.168.11.9:3128 NO_PROXY=localhost,127.0.0.1

$ sudo usermod -a -G docker `whoami`

$ exit

最後に exit して、プロンプトを閉じたので、再度プロンプトを立ち上げます。

【参考にした記事】

Dockerの動作確認

以前やった手順をそのまま実施し、Nginxを動かしてみました。

$ docker image pull nginx

$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
nginx        latest    4f67c83422ec   8 days ago   188MB

$ docker container run -d -p 8080:80 --name webserver nginx
285f67e5b734fe0fb6b985193257e3d7d6fd005471f4cb450e3f957251d5afe7

ブラウザを立ち上げ、http://localhost:8080/ にアクセス。
動いた!
image.png

問題なく動作していることが確認できたので、コンテナを止めておきます。
docker container ps コマンドでプロセスが何も表示されなければOK。

$ docker container stop webserver
webserver

$ docker container ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

(3) Git 導入

sudo apt-get install git コマンドでGitをインストール。
dpkg -l git コマンドでGitがインストールされたか確認します。

$ sudo apt-get install git

$ dpkg -l git
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version              Architecture Description
+++-==============-====================-============-===================================================
ii  git            1:2.34.1-1ubuntu1.11 amd64        fast, scalable, distributed revision control system

以下のコマンドを実行して、Gitのプロキシを設定し、設定が反映されているか確認します。

$ git config --global http.proxy http://192.168.11.9:3128

$ git config --global -l
http.proxy=http://192.168.11.9:3128

Gitのプロキシ設定はOSユーザごとに必要になります。
※設定は ~/.gitconfig ファイルに記述されます。

【参考にした記事】

(4) Dify 導入

まずは git clone コマンドで資材をダウンロードします。

$ cd (資材を置きたいディレクトリ)
$ git clone https://github.com/langgenius/dify.git

次に、コンテナからプロキシ経由でインターネットに出ていけるように、./dify/docker/docker-compose.yaml を修正します。
具体的には、environment キーのところに HTTP_PROXYHTTPS_PROXY の設定を書いていきます。

docker-compose.yaml の修正を行わないと、Dify上でLLMのAPIキーの検証などができません。
※ローカルLLMの利用に限定するなど、あえてインターネットとの通信を行いたくない場合には、この修正いらないかも。。

以下、修正の差分のところに色を付けておきます。

修正後の docker-compose.yaml

とりあえず各サービスのenvironment キーのところに HTTP_PROXYHTTPS_PROXY の設定を追記しましたが、全部やる必要あったかの確認(取捨選択の検証)は行っていません。
本来プロキシ設定がいらないところにも書いてしまっている気がします。。
そのような箇所がありましたら、ご指摘いただけますと幸いです。

docker-compose.yaml
version: '3'
services:
  # API service
  api:
    image: langgenius/dify-api:0.6.10
    restart: always
    environment:
      # Startup mode, 'api' starts the API server.
      MODE: api
      # The log level for the application. Supported values are `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
      LOG_LEVEL: INFO
      # enable DEBUG mode to output more logs
      # DEBUG : true
      # A secret key that is used for securely signing the session cookie and encrypting sensitive information on the database. You can generate a strong key using `openssl rand -base64 42`.
      SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
      # The base URL of console application web frontend, refers to the Console base URL of WEB service if console domain is
      # different from api or web app domain.
      # example: http://cloud.dify.ai
      CONSOLE_WEB_URL: ''
      # Password for admin user initialization.
      # If left unset, admin user will not be prompted for a password when creating the initial admin account.
      INIT_PASSWORD: ''
      # The base URL of console application api server, refers to the Console base URL of WEB service if console domain is
      # different from api or web app domain.
      # example: http://cloud.dify.ai
      CONSOLE_API_URL: ''
      # The URL prefix for Service API endpoints, refers to the base URL of the current API service if api domain is
      # different from console domain.
      # example: http://api.dify.ai
      SERVICE_API_URL: ''
      # The URL prefix for Web APP frontend, refers to the Web App base URL of WEB service if web app domain is different from
      # console or api domain.
      # example: http://udify.app
      APP_WEB_URL: ''
      # File preview or download Url prefix.
      # used to display File preview or download Url to the front-end or as Multi-model inputs;
      # Url is signed and has expiration time.
      FILES_URL: ''
      # File Access Time specifies a time interval in seconds for the file to be accessed.
      # The default value is 300 seconds.
      FILES_ACCESS_TIMEOUT: 300
      # When enabled, migrations will be executed prior to application startup and the application will start after the migrations have completed.
      MIGRATION_ENABLED: 'true'
      # The configurations of postgres database connection.
      # It is consistent with the configuration in the 'db' service below.
      DB_USERNAME: postgres
      DB_PASSWORD: difyai123456
      DB_HOST: db
      DB_PORT: 5432
      DB_DATABASE: dify
      # The configurations of redis connection.
      # It is consistent with the configuration in the 'redis' service below.
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_USERNAME: ''
      REDIS_PASSWORD: difyai123456
      REDIS_USE_SSL: 'false'
      # use redis db 0 for redis cache
      REDIS_DB: 0
      # The configurations of celery broker.
      # Use redis as the broker, and redis db 1 for celery broker.
      CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
      # Specifies the allowed origins for cross-origin requests to the Web API, e.g. https://dify.app or * for all origins.
      WEB_API_CORS_ALLOW_ORIGINS: '*'
      # Specifies the allowed origins for cross-origin requests to the console API, e.g. https://cloud.dify.ai or * for all origins.
      CONSOLE_CORS_ALLOW_ORIGINS: '*'
      # CSRF Cookie settings
      # Controls whether a cookie is sent with cross-site requests,
      # providing some protection against cross-site request forgery attacks
      #
      # Default: `SameSite=Lax, Secure=false, HttpOnly=true`
      # This default configuration supports same-origin requests using either HTTP or HTTPS,
      # but does not support cross-origin requests. It is suitable for local debugging purposes.
      #
      # If you want to enable cross-origin support,
      # you must use the HTTPS protocol and set the configuration to `SameSite=None, Secure=true, HttpOnly=true`.
      #
      # The type of storage to use for storing user files. Supported values are `local` and `s3` and `azure-blob` and `google-storage`, Default: `local`
      STORAGE_TYPE: local
      # The path to the local storage directory, the directory relative the root path of API service codes or absolute path. Default: `storage` or `/home/john/storage`.
      # only available when STORAGE_TYPE is `local`.
      STORAGE_LOCAL_PATH: storage
      # The S3 storage configurations, only available when STORAGE_TYPE is `s3`.
      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'
      # The Azure Blob storage configurations, only available when STORAGE_TYPE is `azure-blob`.
      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'
      # The Google storage configurations, only available when STORAGE_TYPE is `google-storage`.
      GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
      # if you want to use Application Default Credentials, you can leave GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64 empty.
      GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
      # The type of vector store to use. Supported values are `weaviate`, `qdrant`, `milvus`, `relyt`.
      VECTOR_STORE: weaviate
      # The Weaviate endpoint URL. Only available when VECTOR_STORE is `weaviate`.
      WEAVIATE_ENDPOINT: http://weaviate:8080
      # The Weaviate API key.
      WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
      # The Qdrant endpoint URL. Only available when VECTOR_STORE is `qdrant`.
      QDRANT_URL: http://qdrant:6333
      # The Qdrant API key.
      QDRANT_API_KEY: difyai123456
      # The Qdrant client timeout setting.
      QDRANT_CLIENT_TIMEOUT: 20
      # The Qdrant client enable gRPC mode.
      QDRANT_GRPC_ENABLED: 'false'
      # The Qdrant server gRPC mode PORT.
      QDRANT_GRPC_PORT: 6334
      # Milvus configuration Only available when VECTOR_STORE is `milvus`.
      # The milvus host.
      MILVUS_HOST: 127.0.0.1
      # The milvus host.
      MILVUS_PORT: 19530
      # The milvus username.
      MILVUS_USER: root
      # The milvus password.
      MILVUS_PASSWORD: Milvus
      # The milvus tls switch.
      MILVUS_SECURE: 'false'
      # relyt configurations
      RELYT_HOST: db
      RELYT_PORT: 5432
      RELYT_USER: postgres
      RELYT_PASSWORD: difyai123456
      RELYT_DATABASE: postgres
      # pgvector configurations
      PGVECTOR_HOST: pgvector
      PGVECTOR_PORT: 5432
      PGVECTOR_USER: postgres
      PGVECTOR_PASSWORD: difyai123456
      PGVECTOR_DATABASE: dify
      # tidb vector configurations
      TIDB_VECTOR_HOST: tidb
      TIDB_VECTOR_PORT: 4000
      TIDB_VECTOR_USER: xxx.root
      TIDB_VECTOR_PASSWORD: xxxxxx
      TIDB_VECTOR_DATABASE: dify
      # Mail configuration, support: resend, smtp
      MAIL_TYPE: ''
      # default send from email address, if not specified
      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'
      # the api-key for resend (https://resend.com)
      RESEND_API_KEY: ''
      RESEND_API_URL: https://api.resend.com
      # The DSN for Sentry error reporting. If not set, Sentry error reporting will be disabled.
      SENTRY_DSN: ''
      # The sample rate for Sentry events. Default: `1.0`
      SENTRY_TRACES_SAMPLE_RATE: 1.0
      # The sample rate for Sentry profiles. Default: `1.0`
      SENTRY_PROFILES_SAMPLE_RATE: 1.0
      # Notion import configuration, support public and internal
      NOTION_INTEGRATION_TYPE: public
      NOTION_CLIENT_SECRET: you-client-secret
      NOTION_CLIENT_ID: you-client-id
      NOTION_INTERNAL_SECRET: you-internal-secret
      # The sandbox service endpoint.
      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 server
      SSRF_PROXY_HTTP_URL: 'http://ssrf_proxy:3128'
      SSRF_PROXY_HTTPS_URL: 'http://ssrf_proxy:3128'
      # Indexing configuration
      INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
+     # Add proxy settings
+     HTTP_PROXY: 'http://192.168.11.9:3128'
+     HTTPS_PROXY: 'http://192.168.11.9:3128'
    depends_on:
      - db
      - redis
    volumes:
      # Mount the storage directory to the container, for storing user files.
      - ./volumes/app/storage:/app/api/storage
    # uncomment to expose dify-api port to host
    # ports:
    #   - "5001:5001"
    networks:
      - ssrf_proxy_network
      - default

  # worker service
  # The Celery worker for processing the queue.
  worker:
    image: langgenius/dify-api:0.6.10
    restart: always
    environment:
      CONSOLE_WEB_URL: ''
      # Startup mode, 'worker' starts the Celery worker for processing the queue.
      MODE: worker

      # --- All the configurations below are the same as those in the 'api' service. ---

      # The log level for the application. Supported values are `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
      LOG_LEVEL: INFO
      # A secret key that is used for securely signing the session cookie and encrypting sensitive information on the database. You can generate a strong key using `openssl rand -base64 42`.
      # same as the API service
      SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
      # The configurations of postgres database connection.
      # It is consistent with the configuration in the 'db' service below.
      DB_USERNAME: postgres
      DB_PASSWORD: difyai123456
      DB_HOST: db
      DB_PORT: 5432
      DB_DATABASE: dify
      # The configurations of redis cache connection.
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_USERNAME: ''
      REDIS_PASSWORD: difyai123456
      REDIS_DB: 0
      REDIS_USE_SSL: 'false'
      # The configurations of celery broker.
      CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
      # The type of storage to use for storing user files. Supported values are `local` and `s3` and `azure-blob` and `google-storage`, Default: `local`
      STORAGE_TYPE: local
      STORAGE_LOCAL_PATH: storage
      # The S3 storage configurations, only available when STORAGE_TYPE is `s3`.
      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'
      # The Azure Blob storage configurations, only available when STORAGE_TYPE is `azure-blob`.
      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'
      # The Google storage configurations, only available when STORAGE_TYPE is `google-storage`.
      GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
      # if you want to use Application Default Credentials, you can leave GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64 empty.
      GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
      # The type of vector store to use. Supported values are `weaviate`, `qdrant`, `milvus`, `relyt`, `pgvector`.
      VECTOR_STORE: weaviate
      # The Weaviate endpoint URL. Only available when VECTOR_STORE is `weaviate`.
      WEAVIATE_ENDPOINT: http://weaviate:8080
      # The Weaviate API key.
      WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
      # The Qdrant endpoint URL. Only available when VECTOR_STORE is `qdrant`.
      QDRANT_URL: http://qdrant:6333
      # The Qdrant API key.
      QDRANT_API_KEY: difyai123456
      # The Qdrant client timeout setting.
      QDRANT_CLIENT_TIMEOUT: 20
      # The Qdrant client enable gRPC mode.
      QDRANT_GRPC_ENABLED: 'false'
      # The Qdrant server gRPC mode PORT.
      QDRANT_GRPC_PORT: 6334
      # Milvus configuration Only available when VECTOR_STORE is `milvus`.
      # The milvus host.
      MILVUS_HOST: 127.0.0.1
      # The milvus host.
      MILVUS_PORT: 19530
      # The milvus username.
      MILVUS_USER: root
      # The milvus password.
      MILVUS_PASSWORD: Milvus
      # The milvus tls switch.
      MILVUS_SECURE: 'false'
      # Mail configuration, support: resend
      MAIL_TYPE: ''
      # default send from email address, if not specified
      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'
      # the api-key for resend (https://resend.com)
      RESEND_API_KEY: ''
      RESEND_API_URL: https://api.resend.com
      # relyt configurations
      RELYT_HOST: db
      RELYT_PORT: 5432
      RELYT_USER: postgres
      RELYT_PASSWORD: difyai123456
      RELYT_DATABASE: postgres
      # pgvector configurations
      PGVECTOR_HOST: pgvector
      PGVECTOR_PORT: 5432
      PGVECTOR_USER: postgres
      PGVECTOR_PASSWORD: difyai123456
      PGVECTOR_DATABASE: dify
      # tidb vector configurations
      TIDB_VECTOR_HOST: tidb
      TIDB_VECTOR_PORT: 4000
      TIDB_VECTOR_USER: xxx.root
      TIDB_VECTOR_PASSWORD: xxxxxx
      TIDB_VECTOR_DATABASE: dify
      # Notion import configuration, support public and internal
      NOTION_INTEGRATION_TYPE: public
      NOTION_CLIENT_SECRET: you-client-secret
      NOTION_CLIENT_ID: you-client-id
      NOTION_INTERNAL_SECRET: you-internal-secret
      # Indexing configuration
      INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
+     # Add proxy settings
+     HTTP_PROXY: 'http://192.168.11.9:3128'
+     HTTPS_PROXY: 'http://192.168.11.9:3128'
    depends_on:
      - db
      - redis
    volumes:
      # Mount the storage directory to the container, for storing user files.
      - ./volumes/app/storage:/app/api/storage
    networks:
      - ssrf_proxy_network
      - default

  # Frontend web application.
  web:
    image: langgenius/dify-web:0.6.10
    restart: always
    environment:
      # The base URL of console application api server, refers to the Console base URL of WEB service if console domain is
      # different from api or web app domain.
      # example: http://cloud.dify.ai
      CONSOLE_API_URL: ''
      # The URL for Web APP api server, refers to the Web App base URL of WEB service if web app domain is different from
      # console or api domain.
      # example: http://udify.app
      APP_API_URL: ''
      # The DSN for Sentry error reporting. If not set, Sentry error reporting will be disabled.
      SENTRY_DSN: ''
    # uncomment to expose dify-web port to host
    # ports:
    #   - "3000:3000"
+     # Add proxy settings
+     HTTP_PROXY: 'http://192.168.11.9:3128'
+     HTTPS_PROXY: 'http://192.168.11.9:3128'
  # The postgres database.
  db:
    image: postgres:15-alpine
    restart: always
    environment:
      PGUSER: postgres
      # The password for the default postgres user.
      POSTGRES_PASSWORD: difyai123456
      # The name of the default postgres database.
      POSTGRES_DB: dify
      # postgres data directory
      PGDATA: /var/lib/postgresql/data/pgdata
+     # Add proxy settings
+     HTTP_PROXY: 'http://192.168.11.9:3128'
+     HTTPS_PROXY: 'http://192.168.11.9:3128'
    volumes:
      - ./volumes/db/data:/var/lib/postgresql/data
    # uncomment to expose db(postgresql) port to host
    # ports:
    #   - "5432:5432"
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 1s
      timeout: 3s
      retries: 30

  # The redis cache.
  redis:
    image: redis:6-alpine
    restart: always
    volumes:
      # Mount the redis data directory to the container.
      - ./volumes/redis/data:/data
    # Set the redis password when startup redis server.
    command: redis-server --requirepass difyai123456
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
    # uncomment to expose redis port to host
    # ports:
    #   - "6379:6379"

  # The Weaviate vector store.
  weaviate:
    image: semitechnologies/weaviate:1.19.0
    restart: always
    volumes:
      # Mount the Weaviate data directory to the container.
      - ./volumes/weaviate:/var/lib/weaviate
    environment:
      # The Weaviate configurations
      # You can refer to the [Weaviate](https://weaviate.io/developers/weaviate/config-refs/env-vars) documentation for more information.
      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'
    # uncomment to expose weaviate port to host
    # ports:
    #  - "8080:8080"
+     # Add proxy settings
+     HTTP_PROXY: 'http://192.168.11.9:3128'
+     HTTPS_PROXY: 'http://192.168.11.9:3128'
  # The DifySandbox
  sandbox:
    image: langgenius/dify-sandbox:0.2.1
    restart: always
    environment:
      # The DifySandbox configurations
      # Make sure you are changing this key for your deployment with a strong key.
      # You can generate a strong key using `openssl rand -base64 42`.
      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
+     # Add proxy settings
+     HTTP_PROXY: 'http://192.168.11.9:3128'
+     HTTPS_PROXY: 'http://192.168.11.9:3128'
    volumes:
      - ./volumes/sandbox/dependencies:/dependencies
    networks:
      - ssrf_proxy_network

  # ssrf_proxy server
  # for more information, please refer to
  # https://docs.dify.ai/getting-started/install-self-hosted/install-faq#id-16.-why-is-ssrf_proxy-needed
  ssrf_proxy:
    image: ubuntu/squid:latest
    restart: always
    volumes:
      # pls clearly modify the squid.conf file to fit your network environment.
      - ./volumes/ssrf_proxy/squid.conf:/etc/squid/squid.conf
    networks:
      - ssrf_proxy_network
      - default
  # Qdrant vector store.
  # uncomment to use qdrant as vector store.
  # (if uncommented, you need to comment out the weaviate service above,
  # and set VECTOR_STORE to qdrant in the api & worker service.)
  # qdrant:
  #   image: langgenius/qdrant:v1.7.3
  #   restart: always
  #   volumes:
  #     - ./volumes/qdrant:/qdrant/storage
  #   environment:
  #     QDRANT_API_KEY: 'difyai123456'
  #   # uncomment to expose qdrant port to host
  #   # ports:
  #   #  - "6333:6333"
  #   #  - "6334:6334"

  # The pgvector vector database.
  # Uncomment to use qdrant as vector store.
  # pgvector:
  #   image: pgvector/pgvector:pg16
  #   restart: always
  #   environment:
  #     PGUSER: postgres
  #     # The password for the default postgres user.
  #     POSTGRES_PASSWORD: difyai123456
  #     # The name of the default postgres database.
  #     POSTGRES_DB: dify
  #     # postgres data directory
  #     PGDATA: /var/lib/postgresql/data/pgdata
  #   volumes:
  #     - ./volumes/pgvector/data:/var/lib/postgresql/data
  #   # uncomment to expose db(postgresql) port to host
  #   # ports:
  #   #   - "5433:5432"
  #   healthcheck:
  #     test: [ "CMD", "pg_isready" ]
  #     interval: 1s
  #     timeout: 3s
  #     retries: 30


  # The nginx reverse proxy.
  # used for reverse proxying the API service and Web service.
  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"
      #- "443:443"
networks:
  # create a network between sandbox, api and ssrf_proxy, and can not access outside.
  ssrf_proxy_network:
    driver: bridge
    internal: true

修正がおわったら docker compose up コマンドでコンテナを起動します。

$ cd dify/docker

$ docker compose up -d

$ docker ps
CONTAINER ID   IMAGE                              COMMAND                  CREATED       STATUS                 PORTS                               NAMES
4bed53ca7cce   nginx:latest                       "/docker-entrypoint.…"   2 hours ago   Up 2 hours             0.0.0.0:80->80/tcp, :::80->80/tcp   docker-nginx-1
bf3129805a71   langgenius/dify-api:0.6.10         "/bin/bash /entrypoi…"   2 hours ago   Up 2 hours             5001/tcp                            docker-worker-1
ec2bc6bf860d   langgenius/dify-api:0.6.10         "/bin/bash /entrypoi…"   2 hours ago   Up 2 hours             5001/tcp                            docker-api-1
d6f546a6ebd4   langgenius/dify-web:0.6.10         "/bin/sh ./entrypoin…"   2 hours ago   Up 2 hours             3000/tcp                            docker-web-1
fca4ae5c2ab4   langgenius/dify-sandbox:0.2.1      "/main"                  2 hours ago   Up 2 hours                                                 docker-sandbox-1
361d126ef3ba   ubuntu/squid:latest                "entrypoint.sh -f /e…"   2 hours ago   Up 2 hours             3128/tcp                            docker-ssrf_proxy-1
6034908d1378   semitechnologies/weaviate:1.19.0   "/bin/weaviate --hos…"   2 hours ago   Up 2 hours                                                 docker-weaviate-1
849c68f67fd1   redis:6-alpine                     "docker-entrypoint.s…"   2 hours ago   Up 2 hours (healthy)   6379/tcp                            docker-redis-1
0152977f8d27   postgres:15-alpine                 "docker-entrypoint.s…"   2 hours ago   Up 2 hours (healthy)   5432/tcp                            docker-db-1

コンテナが起動したら、ブラウザを立ち上げ http://localhost/install にアクセス。
こんな画面が開きます。
image.png

画面の案内通りにメアドとユーザ名とパスワードを入れて、管理者アカウントをセットアップ。
セットアップが完了するとログイン画面が開くので、先ほど入力したメアドとパスワードでログインします。
スタジオの画面に遷移したらOK!
image.png

【参考にした記事】

(5) Dify で「ワイのかわりに検索くん」を作る

みのるんさん @minorun365 の記事に沿って手を動かしてみました。

最初から作成 ボタンを押すとポップアップが開きます。
「チャットボット」、「テキスト ジェネレーター」、「エージェント」、「ワークフロー」から選べるようです。

チャットボット
チャット形式のアプリケーションを構築します。このアプリは質問と回答の形式を使用し、複数のラウンドの継続的な会話を可能にします

テキスト ジェネレーター
プロンプトに基づいて高品質のテキストを生成するアプリケーションを構築します。記事、要約、翻訳などを生成します

エージェント
タスクを自動的に完了するためのツールを選択できるインテリジェント エージェントを構築します

ワークフロー
高度なカスタマイズが可能なワークフローに基づいて高品質のテキストを生成するアプリケーションを構築します。経験豊富なユーザー向けです

いろんなことがやれそうで既にワクワクが止まりません!
今回は「ワークフロー」を選択。
アプリ名に「ワイのかわりに検索くん」と入力し、作成する ボタンを押します。
アイコンカスタマイズできるのちょっと嬉しいw
image.png

最初に配置されている「開始」というモジュールをクリックして、「入力フィールド」に Input という名前の変数を定義しておきます。
これによって、まずアプリの開始時にユーザーから質問を受け取れるようにします。

image.png

次に、開始モジュール右側の「+」ボタンから新しいコンポーネントを追加します。
ユーザーの質問をもとに、まずGoogle検索をさせたいので「GoogleSearch」を追加しましょう。

image.png
image.png

承認するには ボタンをクリックし、画面上でSerpApiのAPIキーを入れると、入力変数が定義できるようになります。

入力変数に、先ほど「開始」モジュールで設定した Input を指定し、Result typeをURLではなく text に設定しておきましょう。

image.png

その後、検索結果を受け取って推論する「LLM」モジュールを追加します。
モデルは、無料で選べる中で高性能な gpt-3.5-turbo-16k-0613 を選択し、Systemプロンプトに以下を入力します。

モジュール追加してモデルを、、 おや、、? 何も表示されない?
ローカル環境のDifyだとモデルは自分で登録しないとダメみたいですね。
image.png

というわけでモデルを登録します。
画面右上のユーザー名をクリックし、表示されるメニューから設定 を選択。
左のメニューから モデルプロバイダー を選択します。
image.png

今回はAnthropicを選択。
API Key にAPIキーを入れて 保存 ボタンをクリックします。
※APIキーはダイアログ左下の Get your API Key from Anthropic をクリックして、遷移先のページで取得すると楽です。
image.png

登録されたっぽい。
image.png

「LLM」モジュールからClaudeが選べるようになりました!
image.png

今回は claude-3-sonnet を選び、SYSTEM 欄にプロンプトを書きます。
半角スラッシュ / 打ったら変数のサジェスト出てくるの便利~~! ※Qiita感覚で使えるw

> SYSTEM
以下の「ユーザーの質問」に対して、「Google検索結果」を用いて回答してください。
「ユーザーの質問」:※変数
「Google検索結果」:※変数

後述しますが、Claudeの場合、SYSTEM 欄だけでなく USER 欄にもプロンプトを書く必要がありました。

image.png

最後に「終了」モジュールを追加すれば完成です。
LLMの回答が出力されるように、出力変数に LLM / text を設定しておきましょう。

image.png

コンポーネント横一列に並べるのきつくなってきたので、ドラッグアンドドロップで位置を変えてみました。
便利~~!
image.png

いざ、テスト!
それでは実際に使ってみます。
画面右上の「実行」を押して、テストウィンドウの入力に「Difyって何?」と入力してみます。素のGPTはまだ知らない知識なので、Google検索しないと正しく回答できない質問です。

image.png

おや、、??
image.png
LLMからエラーが返ってきました。

Node LLM run failed: [anthropic] Bad Request Error, Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'messages: at least one message is required'}}

ふむ、、パラメータがイケてないっぽい。
「LLM」モジュールの設定画面から +メッセージを追加 ボタンをクリックし、USER の入力フォームを表示します。
SYSTEMUSER について、以下のようにプロンプトを入力し直しました。

> SYSTEM
あなたはIT知識に乏しい日本人向けのアドバイザーです。
質問に対する回答は必ず日本語で記述してください。

> USER
以下の「ユーザーの質問」に対して、「Google検索結果」を用いて回答してください。
「ユーザーの質問」:※変数
「Google検索結果」:※変数

image.png

いざ再テスト!うまくいった!

Difyとは、プログラミングの知識がなくてもAIアプリケーションを簡単に作成できるオープンソースのプラットフォームです。
主な特徴は以下の通りです。

  • 直感的なインターフェースでドラッグ&ドロップによる操作が可能
  • 大規模言語モデル(LLM)を活用して、チャットボットからAIワークフローまで幅広いアプリを作成可能
  • RAG(Retrieval-Augmented Generation)エンジンを使い、大量のデータを参照しながらアプリを生成
  • LangChainよりも本番環境に適した設計
  • オープンソースなので無料で利用可能

プログラミング知識がなくても、Difyの直感的なインターフェースを使えば、AIチャットボットやデータ分析ツール、業務自動化アプリなど、様々なAIアプリケーションを手軽に作ることができます。AIの発展に伴い、こうしたノーコードAIツールの需要が高まっています。

image.png

先ほども触れた「LLM」モジュールの SYSTEMUSER の役割の使い分けについて、「ワイのかわりに検索くん」に聞いてみると、以下のように答えてくれました。
有能!!

DifyのLLMには、SYSTEMとUSERという2つの役割があります。

SYSTEMは、LLMに与える指示や設定を記述する部分です。例えば、LLMに与えるタスクの内容、制約条件、出力形式などを指定します。SYSTEMはLLMの振る舞いを制御する役割を担います。

一方、USERは、LLMに入力する実際のデータや質問を記述する部分です。USERからの入力に対してLLMが応答を生成します。

つまり、SYSTEMではLLMの動作設定を記述し、USERではLLMに与える具体的な入力データを記述するという使い分けになります。この2つを適切に使い分けることで、目的に応じたLLMの動作を実現できます。SYSTEMを適切に設定し、USERに適切な入力を与えることが、DifyでLLMを効果的に活用するためのポイントになります。

(6) 「ワイのかわりに検索くん」をBedrockする

image.png
image.png
(出典) 宇宙最速!? でAmazon Bedrockを本格導入したプロダクト「2つ」開発してみた件

ということで張り切っていきましょう。
まずは、先ほどと同様の手順で、モデルとしてBedrockを登録します。

画面右上のユーザー名をクリックし、表示されるメニューから設定 を選択。
左のメニューから モデルプロバイダー を選択します。

Bedrockがいました。
image.png

セットアップ画面を開き、パラメータを入れていきます。
image.png

スタジオの画面に戻り、「LLM」モジュールを選択。
モデル のプルダウンを開き、Bedrockのアイコンが付いているものに変更します。
今回は Claude 3 Haiku に変えてみます。
image.png
image.png

Bedrockできました!簡単!
再び「Difyって何?」と聞いてみると、先ほどとは少し違うものの、似たような内容が返ってきました。

Difyは、プログラミングの知識がなくてもドラッグ&ドロップで簡単にAIアプリケーションを作成できるオープンソースのプラットフォームです。
主な特徴は以下の通りです:

  • GPT-4やClaude 3などの最新のAIモデルを統合しているため、高度なAIアプリケーションを開発できます。
  • 直感的なインターフェースにより、プログラミング経験がなくても簡単にアプリを作成できます。
  • RAGエンジンを使用して、エージェントから複雑なAIワークフローまでLLMアプリを開発できます。
  • オープンソースのため、無料で利用できます。
  • LangChainよりも本番環境に適しているため、実用的なAIアプリの開発に向いています。

つまり、Difyを使えば、プログラミングの知識がなくても、簡単にAIアプリケーションを開発できるというものです。ノーコードでAIアプリを作れるため、これからAIを活用したいと考えている日本人にとても便利なツールだと言えます。

【参考にした記事】

終わりに

以上、プロキシ環境下のローカルPCに "Dify" を導入して、Bedrockしてみました!
結構大変でした笑
おとなしくインターネット経由でサービスを使っておけばよいものを!! 思う反面、実際の仕事では、簡単にはその選択ができない事情もあると思います。
そんな大人の世界で戦ってらっしゃる皆様に、この記事がお役に立てば幸いです。

最後までお目通しいただき、ありがとうございました。

30
37
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
37

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?