Dify を さくらの VPS でセルフホストしてみる

さくらの VPS 上で、Dify を動作させる手順について簡単なメモ。Bluesky PDS を稼働していた関係で Docker が導入・動作済みの VPS という特殊環境ですが、Dify をさくらの VPS で動かしたい人には多少の参考になるかもしれません。

下記の記事でも書いたとおり、オープンソースの 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_certificatessl_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 用に 80808443 ポートを使用するようにしましたので、ファイアウォールの設定でそれらポートを開放します。

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

関連エントリー

記事をここまで御覧頂きありがとうございます。
この記事が気に入ったらサポートしてみませんか?