下記の記事でも書いたとおり、オープンソースの LLM アプリ開発プラットフォームである Dify をローカル環境 (Windows 11 上の WSL2 で動作する Ubuntu 22.04) で動作させて使ってるんですが、今後の使い勝手を考えると、やっぱりローカル環境ではなくて、Web 上で使いたいなと。
じゃあどっかのサーバにデプロイするかって考えてたんですけども、ちょうど Bluesky PDS (Personal Data Server) をセルフホスト (下記記事参照) しているさくらの VPS が、Docker も入ってるし、Bluesky PDS 以外で使っていないからリソースも空いてるじゃんということに気がつきまして。
早速、同一サーバで、Dify を立ち上げてみましたという話。
今回、Bluesky PDS と共存させるためと、Dify に対して、Let's Encrypt の SSL/TLS 証明書を使用して、HTTPS でアクセスできるようにするために行った設定や、その手順などを簡単にまとめておこうと思います。
前提
- 今回使用する PVS は Bluesky PDS をセルフホストしている関係で Docker がすでにインストール、稼働済み
- Dify で使用するドメイン (e.g.
dify.example.com
) の DNS レコード設定は別途やってある - さくらの VPS は 「2G」 プラン (仮想 3 Core / メモリ 2G) だけど、Dify の推奨環境はメモリ 4GB らしいのでどうなるかわからん
もし、Docker を入れるところからという場合、各プラットフォームごとのインストール手順は下記にありますので参考まで。
簡単に済ませたいなら、docker-install を使ってもいいと思います。下記のようにコマンド入力するだけで Docker と依存関係のインストールが行われます。
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
Let's Encrypt の SSL/TLS 証明書を取得
まず、稼働中の Bluesky PDS、というか Docker を落としてしまいます。
sudo systemctl stop docker
このサーバは Bluesky PDS しか稼働していないので、普段は nginx も停止した状態 (Docker コンテナとして nginx は稼働していますが)ですが、これを一度立ち上げます。
sudo systemctl start nginx
で、一旦、適当というか、最低限のバーチャルホストの設定をします。
sudo vim /etc/nginx/sites-available/dify.example.com
---
server {
listen 80;
listen [::]:80;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name dify.example.com;
}
作った設定ファイルのシンボリックリンクを nginx が起動時に読み取る sites-enabled
ディレクトリに作成して有効に。
sudo ln -s /etc/nginx/sites-available/dify.example.com /etc/nginx/sites-enabled/
sudo systemctl restart nginx
続いて nginx 向けの certbot をインストール。
sudo apt install certbot python3-certbot-nginx
証明書を取得します。
sudo certbot --nginx -d dify.example.com
先ほど作ったバーチャルホストの設定ファイルに certbot が SSL/TLS 関連の設定を書き足してくれるので (下記例)、ssl_certificate
と ssl_certificate_key
のパスをメモって次へ。
# /etc/nginx/sites-available/dify.example.com
server {
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name dify.example.com;
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/dify.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/dify.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = dify.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name dify.example.com;
return 404; # managed by Certbot
}
ここまで行ったら、nginx を止めてしまいます。
sudo systemctl stop nginx
念のため、ポート 80 と 443 を使用しているプロセスがないかを調べておいて、もしあればそれも停止。
sudo lsof -i :80,443
sudo kill PID # killしたいプロセスの PID
Dify のインストールと立ち上げ
Dify のファイルをどこに置きたいかによるとは思いますが、今回は、/home/ubuntu
で作業します。
まず、Dify のソースコードを取得。
git clone https://github.com/langgenius/dify.git
docker
ディレクトリに移動します。
cd dify/docker
.env.example
ファイルがあるので、これを .env
にリネームして保存します。
cp .env.example .env
.env
ファイルに設定を書いていきますが、その前に、
openssl rand -base64 42
で、SECRET_KEY
に設定するキーを出力しておきましょう。こいつをコピーしたら、.env
の編集へ。
vim .env
Dify の環境変数については、下記にドキュメントがありますので、必要に応じて変更をお勧めしますが、今回は最低限設定した項目だけ抜粋。
Dify の環境変数の設定
最低限、設定した環境変数が下記。今回は、Bluesky PDS と共存させるため、Bluesky PDS がすでに使っているポート番号を避けるように変更したりしていますが、通常は変更不要です。
# ------------------------------
# Server Configuration
# ------------------------------
...略...
SECRET_KEY=[ここに先ほど出力したキーを]
...略...
# ------------------------------
# Environment Variables for Nginx reverse proxy
# ------------------------------
NGINX_SERVER_NAME=dify.example.com #← サーバ名を指定
NGINX_HTTPS_ENABLED=true #← HTTPS を有効に
# HTTP port
NGINX_PORT=80
# SSL settings are only applied when HTTPS_ENABLED is true
NGINX_SSL_PORT=443
# if HTTPS_ENABLED is true, you're required to add your own SSL certificates/keys to the `./nginx/ssl` directory
# and modify the env vars below accordingly.
NGINX_SSL_CERT_FILENAME=fullchain.pem #← 先ほど Let's Encrypt で取得した証明書ファイルのファイル名
NGINX_SSL_CERT_KEY_FILENAME=privkey.pem #← 先ほど Let's Encrypt で取得した秘密鍵ファイルのファイル名
NGINX_SSL_PROTOCOLS=TLSv1.3
...略...
# ------------------------------
# Docker Compose Service Expose Host Port Configurations
# ------------------------------
EXPOSE_NGINX_PORT=8080 #← Bluesky PDS がすでに使っているので 8080 に変更。通常は変更不要
EXPOSE_NGINX_SSL_PORT=8443 #← Bluesky PDS がすでに使っているので 8443 に変更。通常は変更不要
その他、メール関連の設定 (下記のコメント以下)
# ------------------------------
# Mail related configuration
# ------------------------------
や、DB 周りの設定 (下記のコメント以下) は、必要に応じて設定しておきましょう。
# ------------------------------
# Database Configuration
# The database uses PostgreSQL. Please use the public schema.
# It is consistent with the configuration in the 'db' service below.
# ------------------------------
HTTPS を有効にするための作業
Let's Encrypt から取得した SSL/TLS 証明書を、Docker コンテナが認識できるようにしていきます。
まず、証明書のシンボリックリンクを、/docker/nginx/ssl
に作成します。
sudo ln -s /etc/letsencrypt/live/dify.example.com/fullchain.pem nginx/ssl
sudo ln -s /etc/letsencrypt/live/dify.example.com/privkey.pem nginx/ssl
続いて、docker-compose.yaml
を 1 箇所修正。
# The nginx reverse proxy.
# used for reverse proxying the API service and Web service.
nginx:
image: nginx:latest
restart: always
volumes:
- ./nginx/nginx.conf.template:/etc/nginx/nginx.conf.template
- ./nginx/proxy.conf.template:/etc/nginx/proxy.conf.template
- ./nginx/https.conf.template:/etc/nginx/https.conf.template
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/docker-entrypoint.sh:/docker-entrypoint-mount.sh
- ./nginx/ssl:/etc/ssl
- /etc/letsencrypt:/etc/letsencrypt # ← 追加
変更したポートの開放
今回は、Dify 用に 8080
と 8443
ポートを使用するようにしましたので、ファイアウォールの設定でそれらポートを開放します。
sudo ufw allow 8080/tcp
sudo ufw allow 8443/tcp
sudo ufw reload
さくらの VPS の場合、ufw の設定以外に、サーバコントロールパネル側でパケットフィルタの設定がされていると思いますので、合わせてそちらも確認してください。
稼働
ここまで来たら、あとは Dify を立ち上げます。作業開始前に Docker を落としてるので、これを再稼働させて、
sudo systemctl start docker
Dify のコンテナを立ち上げ。
sudo docker compose up -d
問題なく立ち上がったら、https://dify.example.com:8443
にアクセスして Dify の管理者アカウント作成画面が表示されれば成功です。
ついでに、Bluesky PDS も立ち上げます。
sudo docker compose -f /pds/compose.yaml up -d
この状態で問題なく Docker コンテナが立ち上がり、エラーなどが出なければ共存成功と。
Docker コンテナの稼働状況を見てみましょう。下から 3つが Bluesky PDS で、それ以外は Dify のコンテナです。
sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
76e3b2eda28e nginx:latest "sh -c 'cp /docker-e..." 18 minutes ago Up 18 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp, 0.0.0.0:8443->443/tcp, :::8443->443/tcp docker-nginx-1
ac043aeb6899 langgenius/dify-api:0.6.14 "/bin/bash /entrypoi..." 18 minutes ago Up 18 minutes 5001/tcp docker-api-1
56adaa7df7c8 langgenius/dify-api:0.6.14 "/bin/bash /entrypoi..." 18 minutes ago Up 18 minutes 5001/tcp docker-worker-1
2daccacc94a5 ubuntu/squid:latest "sh -c 'cp /docker-e..." 18 minutes ago Up 18 minutes 3128/tcp docker-ssrf_proxy-1
8ad1ccabfc62 redis:6-alpine "docker-entrypoint.s..." 18 minutes ago Up 18 minutes (healthy) 6379/tcp docker-redis-1
3875195b6b5e semitechnologies/weaviate:1.19.0 "/bin/weaviate --hos..." 18 minutes ago Up 18 minutes docker-weaviate-1
aef72f61262f langgenius/dify-sandbox:0.2.1 "/main" 18 minutes ago Up 18 minutes docker-sandbox-1
85e835904807 langgenius/dify-web:0.6.14 "/bin/sh ./entrypoin..." 18 minutes ago Up 18 minutes 3000/tcp docker-web-1
bb98c8e01ab4 postgres:15-alpine "docker-entrypoint.s..." 18 minutes ago Up 18 minutes (healthy) 5432/tcp docker-db-1
7cd8a15993d0 caddy:2 "caddy run --config ..." 24 minutes ago Up 24 minutes caddy
688c4bf4750b ghcr.io/bluesky-social/pds:0.4 "dumb-init -- node -..." 24 minutes ago Up 24 minutes pds
cfd5c3fc0d85 containrrr/watchtower:latest "/watchtower" 24 minutes ago Up 24 minutes (healthy) watchtower
今回は、Bluesky PDS と共存させるとかいう面倒くさいことをやったので、ポート番号がどうこうとかありましたけども、単に Dify だけホストするなら上記の手順のうち、Bluesky PDS との共存のためにやった設定だけ無視ししてもらえれば比較的簡単に立ち上げできるかと思います。
あとは、Dify のポート番号を変更しちゃってる関係で、多分、Let's Encrypt の SSL/TLS 証明書を更新する段階でエラーが出そうな予感 (Dify で使用しているドメインではポート 80 が閉じてるので)、というか多分失敗するので、それを解決しないといけない。面倒くせぇ。
基本的には、HTTP-01 チャレンジを使用せず、DNS-01 チャレンジで証明書の再取得を行えばいいんですけども。
sudo certbot certonly --manual -d dify.example.com --preferred-challenges dns-01