OSS版Difyの環境構築方法

# はじめに

OSS版のDifyの環境を構築する方法を紹介する。

# 動作確認環境
* Ubuntu 22.04 x86_64
* Docker Engine Version 27.3.1
  * Docker Compose Version v2.29.7 

# 方法

Docker Composeを使って環境構築する。

## OSS版Difyのクローン

```bash
cd {your_workspace}  # 任意のワークスペース
git clone https://github.com/langgenius/dify.git
```

## .envファイルの編集

用意されている```.env.example```をコピーする。

```bash
cd dify/docker
cp .env.example .env
vi .env
```

以下に主要な.envファイルに記載されている環境変数の修正方法を記載する。.envファイルに記載の環境変数の詳細については、[公式ドキュメント](https://docs.dify.ai/ja-jp/getting-started/install-self-hosted/environments)を参照。ただし、ドキュメントが更新されていないため、最新版の情報はソースコードを参照することを推奨する。以下の2つのファイルが該当する。
* [docker-compose.yaml](https://github.com/langgenius/dify/blob/main/docker/docker-compose.yaml)
* [.env.example](https://github.com/langgenius/dify/blob/main/docker/.env.example)

### ポート番号の設定

HTTPのポート番号を変更する。変更するには、.envファイル内の```EXPOSE_NGINX_PORT```を変更する。

```bash:変更前
# ------------------------------
# Docker Compose Service Expose Host Port Configurations
# ------------------------------
EXPOSE_NGINX_PORT=80
EXPOSE_NGINX_SSL_PORT=443
```

```bash:変更後：ポート番号8080へ変更する例
# ------------------------------
# Docker Compose Service Expose Host Port Configurations
# ------------------------------
EXPOSE_NGINX_PORT=8080
EXPOSE_NGINX_SSL_PORT=443
```

### WebアプリURLの設定

デプロイ先のコンソールWebアプリのURLを設定する。Dify中のリンク先アドレスなどが設定したURLに変更される。

:::note warn
WebアプリURLを指定すると、外部から通信できなくなる場合がある。
localhost(127.0.0.1)の指定やIPアドレスの解決ができない場合は通信できなくなるので、外部から通信ができなくなった場合は、空欄のままでも良い。
:::


```bash:変更前
# ------------------------------
# Common Variables
# ------------------------------

# The backend URL of the console API,
# used to concatenate the authorization callback.
# If empty, it is the same domain.
# Example: https://api.console.dify.ai
CONSOLE_API_URL=

# The front-end URL of the console web,
# used to concatenate some front-end addresses and for CORS configuration use.
# If empty, it is the same domain.
# Example: https://console.dify.ai
CONSOLE_WEB_URL=

# Service API Url,
# used to display Service API Base Url to the front-end.
# If empty, it is the same domain.
# Example: https://api.dify.ai
SERVICE_API_URL=

# WebApp API backend Url,
# used to declare the back-end URL for the front-end API.
# If empty, it is the same domain.
# Example: https://api.app.dify.ai
APP_API_URL=

# WebApp Url,
# used to display WebAPP API Base Url to the front-end.
# If empty, it is the same domain.
# Example: https://app.dify.ai
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=
```

デプロイ先を```http://127.0.0.1:8080```に変更する例を以下に示す。

```bash:変更後：デプロイ先をhttp://127.0.0.1:8080へ変更する例

# ------------------------------
# Common Variables
# ------------------------------

# The backend URL of the console API,
# used to concatenate the authorization callback.
# If empty, it is the same domain.
# Example: https://api.console.dify.ai
CONSOLE_API_URL=

# The front-end URL of the console web,
# used to concatenate some front-end addresses and for CORS configuration use.
# If empty, it is the same domain.
# Example: https://console.dify.ai
CONSOLE_WEB_URL=http://127.0.0.1:8080


# Service API Url,
# used to display Service API Base Url to the front-end.
# If empty, it is the same domain.
# Example: https://api.dify.ai
SERVICE_API_URL=http://127.0.0.1:8080

# WebApp API backend Url,
# used to declare the back-end URL for the front-end API.
# If empty, it is the same domain.
# Example: https://api.app.dify.ai
APP_API_URL=http://127.0.0.1:8080

# WebApp Url,
# used to display WebAPP API Base Url to the front-end.
# If empty, it is the same domain.
# Example: https://app.dify.ai
APP_WEB_URL=http://127.0.0.1:8080

# 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=http://127.0.0.1:8080
```


### ログのタイムゾーンの変更

ログのタイムゾーンを変更する場合は、以下の項目を修正する。

```bash:変更前（デフォルトはUTC）
# ------------------------------
# Server Configuration
# ------------------------------

# The log level for the application.
# Supported values are `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
LOG_LEVEL=INFO
# Log file path
LOG_FILE=/app/logs/server.log
# Log file max size, the unit is MB
LOG_FILE_MAX_SIZE=20
# Log file max backup count
LOG_FILE_BACKUP_COUNT=5
# Log dateformat
LOG_DATEFORMAT=%Y-%m-%d %H:%M:%S
# Log Timezone
LOG_TZ=UTC
```


```bash:変更後：例、Asia/Tokyoの場合

# ------------------------------
# Server Configuration
# ------------------------------

# The log level for the application.
# Supported values are `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
LOG_LEVEL=INFO
# Log file path
LOG_FILE=/app/logs/server.log
# Log file max size, the unit is MB
LOG_FILE_MAX_SIZE=20
# Log file max backup count
LOG_FILE_BACKUP_COUNT=5
# Log dateformat
LOG_DATEFORMAT=%Y-%m-%d %H:%M:%S
# Log Timezone
LOG_TZ=Asia/Tokyo
```


### メール設定

ユーザ登録時のメール送信のための設定。

:::note info
招待メールのDifyリンクは、上述の`CONSOLE_WEB_URL`に設定したURLが利用される。  
メールでの登録依頼をする場合は、`CONSOLE_WEB_URL`を設定しておく。

`CONSOLE_WEB_URL`を設定せずにポート番号だけ変更するなどして、名前解決できなくなると、招待メールからのリンクが以下のように無効になってしまう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/422bee48-d5e3-4f69-96ca-4b22402cbe44.png)

:::

```bash:変更前
# ------------------------------
# Mail related configuration
# ------------------------------

# Mail type, support: resend, smtp
MAIL_TYPE=resend

# Default send from email address, if not specified
MAIL_DEFAULT_SEND_FROM=

# API-Key for the Resend email provider, used when MAIL_TYPE is `resend`.
RESEND_API_URL=https://api.resend.com
RESEND_API_KEY=your-resend-api-key


# SMTP server configuration, used when MAIL_TYPE is `smtp`
SMTP_SERVER=
SMTP_PORT=465
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_USE_TLS=true
SMTP_OPPORTUNISTIC_TLS=false
```

例としてSMTP（認証なし）で以下の設定を行う。
* SMTPサーバ: mail.example.com
* SMTPポート: 25
* 送信アドレス: my.dify@example.com

```bash:変更後：SMTP（認証なし）の設定例
# ------------------------------
# Mail related configuration
# ------------------------------

# Mail type, support: resend, smtp
MAIL_TYPE=smtp

# Default send from email address, if not specified
MAIL_DEFAULT_SEND_FROM=my.dify@example.com

# API-Key for the Resend email provider, used when MAIL_TYPE is `resend`.
RESEND_API_URL=https://api.resend.com
RESEND_API_KEY=your-resend-api-key


# SMTP server configuration, used when MAIL_TYPE is `smtp`
SMTP_SERVER=mail.example.com
SMTP_PORT=25
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_USE_TLS=false
SMTP_OPPORTUNISTIC_TLS=false
```

* 参考
  * https://note.com/masaland/n/nd2d760508f75
  * https://github.com/langgenius/dify/issues/10880


## 起動

```bash
docker compose up -d
```

## アップグレードする場合

### 【オプション】docker-composeファイルのバックアップ

```bash
cd {your_workspace}/dify
cd ./docker
cp docker-compose.yaml docker-compose.yaml.$(date +%s).bak
```

### リポジトリを最新版に更新

```bash
git checkout main
git pull origin main
```

### コンテナの停止と削除

```bash
docker compose down
```

### 【オプション】データのバックアップ

```bash
sudo tar -cvf volumes-$(date +%s).tgz volumes
```

:::note

DifyのDockerコンテナで利用されるデータは、ホストの```dify/docker/volumes```にマウントされる設定となっているのでコンテナを削除してもデータは残る。
* https://github.com/langgenius/dify/blob/cbc8ebd8f5437f6b2859872e3422d0d2b53b0af9/docker/docker-compose.yaml#L587 
:::

### コンテナ起動

```bash
docker compose up -d
```

## 起動後の設定

### 初期設定

初回アクセス時に管理者アカウントの設定画面が表示されるので、設定を行う。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/fcc93530-00ed-4474-bc69-b7f1491ead0f.png)


### ワークスペース名を変更

以下の記事を参照。

https://qiita.com/ntrlmt/items/760684054763bde436b7

### 言語とタイムゾーンの変更

「設定」-「言語」から設定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/6744162f-3cd0-4741-b5b2-78b5ccdadbb8.png)

# まとめ

OSS版Difyの環境を構築する方法を紹介した。URLの変更やメール通知設定などを行っておくと、運用しやすくなるので試してみてほしい。

また、ワークフローの最大実行時間の変更、ループブロックでの回数変更は以下の記事に記載したので参考にしてほしい。

https://qiita.com/ntrlmt/items/dcaaf500c4ef4d36716b


# 参考


https://docs.dify.ai/ja-jp/getting-started/install-self-hosted/environments

https://note.com/masaland/n/nd2d760508f75

https://github.com/langgenius/dify/issues/10880

https://github.com/langgenius/dify/releases/tag/1.3.1