Difyをrootlessで動かし、Notionと連携したチャットボットを作成する

## はじめに
ComfyUIのノードにキーロガーが含まれていたというタイトルを見て（記事の中身は見てない）、コンテナで提供されるアプリのサプライチェーン怖いよなーと思いつつ、ブラックボックスノードで実行されてしまう事は防ぎようがないんだけど、何でもかんでもrootで動かしちゃだめだよなぁ...と思い立ったので、今流行りのDifyをrootlessで動かしてみた。

## Difyインストール
今回はAlmaLinux9のminimalをベースにインストール ※一般ユーザーで実施

``` sh
# SELinuxオフ
sudo grubby --update-kernel ALL --args selinux=0
sudo reboot

# dnf update
sudo dnf update -y

# Dockerインストール
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# rootless実行設定
sudo dnf install -y iptables
sudo modprobe ip_tables
curl -fsSL https://get.docker.com/rootless | sh
sudo loginctl enable-linger $USER

# 特権ポート許可
sudo setcap cap_net_bind_service=ep $(which rootlesskit)
systemctl --user restart docker

# Gitインストール
sudo dnf install -y git

# 80ポート開放
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --reload

# Difyインストール
cd
mkdir container
cd container
git clone https://github.com/langgenius/dify.git
cd dify/docker
docker compose up -d
```

## Dify LLM設定
今回はLLMにGeminiを利用します。
また、今回私が構築したAlmaLinuxが192.168.56.113なので、http://192.168.56.113 へアクセスし、メールアドレス、パスワードを登録してログイン
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/d13ca7e5-80d1-b72f-dd40-4c83997ee65c.png" width=800px>

設定ボタンを押下
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/564092d9-cde3-f6d3-1343-48ce17386ef3.png" width=800px>

今回はGeminiを利用しようと思います。モデルプロバイダーを押下し、Geminiのセットアップボタンを押下
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/9b3aa502-2c70-705a-d20b-2d6f652d3d8c.png" width=800px>

「Get your API Key from Google」を押下し、Geminiにログインする
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/6aba7e8a-f2a2-b28f-c643-038b84aed357.png" width=800px>

画面上部の「Gemini API」タブを押下し、「Google AI StudioでAPIキーを取得する」ボタンを押下する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/26ff4196-9645-3249-6093-2b3c1811d22b.png" width=800px>

「キー APIキーを作成」ボタンを押下する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/c8705467-7087-9c07-818d-9e7bd31781ea.png" width=800px>

「OK」ボタンを押下する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/b21527d6-ebc6-0f71-f322-b0584604290b.png" width=800px>

「キー 新しいプロジェクトでAPIキーを作成」ボタンを押下する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/3b8accdb-cf9e-5be4-3bb4-f92b0507638a.png" width=800px>

APIキーが作成されるので、表示し、値をコピーする
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/aba2fc00-92a7-aafc-ca88-fa61dd2a2752.png" width=800px>

Difyに戻り、コピーしたAPIキーを貼り付け、「保存」ボタンを押下する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/5a0aff7d-7b3f-4073-30bf-07688aadd79a.png" width=800px>

Geminiがセットアップされたことを確認する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/3853f1b7-aecf-de8b-86bf-20465590fcc3.png" width=800px>

## Notion 連携シークレット取得
次に、Notion側でDifyからアクセスを許容する設定を行います。
また、NotionにはDifyというページにDifyの説明と本記事上部にあるインストール手順を乗せたページを用意しました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/99510b38-cdff-b7aa-158f-d2813c6b12da.png" width=800px>

https://www.notion.so/my-integrations にアクセスし、接続するためのシークレットキーを生成します。
「+ 新しいインテグレーション」ボタンを押下
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/a0ea67f8-38b3-f65b-9319-2a15ea5a9ab2.png" width=800px>

任意の名前を入力し、「送信→」ボタンを押下
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/2e0c267a-24b5-ba02-4c37-e09b1de98218.png" width=800px>

シークレットが作成されるので、表示し、値をコピー
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/bb7aeecf-541b-7721-0b32-e9dc59913e9b.png" width=800px>

ここで、一旦Difyを停止（docker compose down）し、docker-dompose.yamlのパラメタを修正 <font color=red><b>※2カ所あるので、2ヵ所とも修正</b></font>
修正後、docker compose up -dで起動

NOTION_INTEGRATION_TYPE: public
NOTION_INTERNAL_SECRET: you-internal-secret
↓
NOTION_INTEGRATION_TYPE: internal
NOTION_INTERNAL_SECRET: コピーしたシークレット値
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/c8a1193d-f869-b224-9385-ccdb425d3486.png" width=600px>

## Difyナレッジ登録
Difyが参照するナレッジを登録します。
ナレッジから「知識を作成」ボタンを押下
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/de2ec52b-5f4e-ab6b-1525-fa0bf9318842.png" width=800px>

「Notionから同期」を選択し、「接続する」ボタンを押下
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/cab11322-944e-d511-f1ec-9e1596b81aac.png" width=800px>

「+ Add workspace」ボタンを押下
<font color=red><b>ところが、バグなのか何も起きません。何も起きませんが、ちゃんと動いている様子</b></font>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/c5c3cfd9-5f2f-8461-059a-cfbfbd3902b2.png" width=800px>

元の画面に戻ると、Notionが登録されています。しかし、どのページも読み込まれていません。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/8de6f985-6dae-57c3-61e9-0a305b36976d.png" width=800px>

## Notion コネクタ設定
Notionのページに戻り、Difyに読み込ませたいページの設定から、接続先にシークレット作成時の名前を選択
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/585423d4-6770-7049-3eeb-0a7f6ca41de4.png" width=800px>

「はい」ボタンを押下
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/d0b3e6a0-0ce3-d76e-cf34-0e4cd85ef7a8.png" width=800px>

## Dify データソース同期
Difyに戻り、連携したNotionの歯車アイコンを押下
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/6cf8455e-bfc6-e887-dc4a-254c5fa3284d.png" width=800px>

連携されているNotionの「Sync」メニューを押下
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/f9b2aff9-ccbb-b201-702b-9492acfdfc34.png" width=800px>

同期されたことを確認
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/c26ff45f-395b-8bb2-e812-50acb1d2868c.png" width=800px>

元のページに戻ると、読み込まれたページが表示されているので、チェックして「次へ」ボタンを押下
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/4bab90a6-6593-14bd-ea91-9dbe8b9a53d3.png" width=800px>

「保存して処理」ボタンを押下
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/14f12360-1788-5c12-1bb7-ca36693881dd.png" width=800px>

ページが読み込まれて100%になる事を確認する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/77ec68d9-15cf-bf9e-a566-d1aa0b1d36bb.png" width=800px>

## Dify チャットボット作成
Difyのトップページに戻り、「テンプレートから作成」ボタンを押下
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/97dad94f-13f9-046e-fcbf-6b76f9b34d39.png" width=800px>

「Knowledge Retreival + Chatbot」の「+ このテンプレートを使用する」ボタンを押下
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/f95f37ad-d13c-744a-a08c-750dfa098b45.png" width=800px>

「作成」ボタンを押下
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/b661e95a-c64a-8555-4a95-368e9053725c.png" width=800px>

このような画面が表示される
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/3fff7f19-c122-50cc-2438-9e9725669344.png" width=800px>

「Knowledge Retreival」ブロックを選択し、「N-to-1リトリーバル」のシステム推論モデルをGeminiに変更する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/0dd60fa0-265f-7dea-7d7a-68edee333aaa.png" width=800px>

知識の「+」を押下し、Notionから読み込んだナレッジを選択後「追加」ボタンを押下する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/d562bd45-9e0b-bd12-91ad-5d9998eb0c63.png" width=800px>

ナレッジが設定されていることを確認する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/10c365ee-f7b5-4caf-e50a-17ca870ce81b.png" width=800px>

LLMブロックを選択し、モデルをGeminiに変更する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/df3145ff-8ad1-3281-923b-454e7ceb9325.png" width=800px>

コンテキストに「result」を設定する。以上終了
※resultはナレッジからのアウトプット。これを設定しないとボットはナレッジを検索してくれない
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/2258a1d8-8f60-b6f6-d2b0-dc559676a09c.png" width=800px>

## 動作確認
「デバッグとプレビュー」を押下し、チャット画面を表示する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/86b77eca-9944-bc22-03bf-a9ca1bc26503.png" width=800px>

「Difyとは何ですか？」と質問すると、Notionに記載したDifyの説明を表示してくれる
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/953003ab-9fb0-eb5c-6ca4-da59c36378c9.png" width=400px>

「Difyに必要なpkgをリストアップして」と言うと、Notionに記載されている手順から必要なpkgをリストアップしてくれる
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82651/9f7869b8-d3f6-c178-6ef3-e7ce8865154d.png" width=400px>

あとは前段にSSLオフロードする機構を入れればいいかなと思います。

## 参考
https://note.com/jolly_dahlia842/n/n7b8b029316cd