前編では Cloudflare DNS を使用してドメインを運用する環境を整えました。
後編は Dify Server をインターネット側から接続できるようにしていきます。

インターネット接続用 トンネルの作成
Dify Server からインターネットへ接続する「専用線」にあたる『トンネル』を作成します。
このトンネルの入り口ですが、実はインターネットに直結してはいません。
Cloudflare Netwaork の先には「Edge Server(エッジサーバー)」と呼ばれるサーバーが多数 存在し、外部のPC/スマホからのアクセスは すべて エッジサーバー を介して Dify Server へ到着する仕組みです。

一般的に、ブラウザは 地理的に一番近いエッジサーバーへアクセスします。
① トンネルの作成
Zero Trust 画面を開き、「ネットワーク」-「Tunnels」をクリックします。

画面中央の「トンネルを追加する」ボタンをクリックします。

トンネルの種類として「Cloudflared」を選択します。
枠内 または「選択する Cloudflared」ボタンをクリックします。

「トンネル名」欄に任意の名前を入力します。
入力後、「トンネルを保存」ボタンをクリックします。

トンネル名は後から変更することも可能です。
② cloudflared の導入
トンネルを形成するために Cloudflare Naetrork との通信を行う、「cloudflared」のインストトール環境を選択します。
今回は Dify と同じ Docker 環境に導入するので、「Docker」ボタンをクリックします。

「cloudflared」のコンテナイメージを導入するコマンドが表示されます。
右端のコピーアイコンで、docker run
コマンド全体をコピーしてください。

そのままでも問題なく実行できますが、次の二つのオプションを付加することにします。
オプション | 説明 |
---|---|
-d | プロセスをバックグラウンドで実行する。 |
--network=host | ホストOSのネットワーク環境へダイレクトに接続する。 ポートマッピング や NAT 処理も行われないので、ネットワーク性能の低下を抑制できる。 |
--network=host
を指定するとネットワーク利用時のオーバーヘッドが軽減する代わりに、ホストOS との「論理的なネットワーク境界」も無くなります。
コンテナ内のアプリケーションに脆弱性が含まれていた場合、コンテナを介してホストOSが危険にさらされる恐れもあります。
docker run
コマンドのオプションに、上表のオプションを追加します。

Ubuntu の端末画面を開き、コマンドを実行します。
$ docker run -d --network=host cloudflare/cloudflared:latest tunnel --no-autoupdate run --token eyJhIjoiZGZ (以下省略)
Unable to find image 'cloudflare/cloudflared:latest' locally
latest: Pulling from cloudflare/cloudflared
51c1b6699f43: Pull complete
2e4cf50eeb92: Pull complete
4e9f20d26c87: Pull complete
0f8b424aa0b9: Pull complete
d557676654e5: Pull complete
d82bc7a76a83: Pull complete
d858cbc252ad: Pull complete
1069fc2daed1: Pull complete
b40161cd83fc: Pull complete
3f4e2c586348: Pull complete
80a8c047508a: Pull complete
e95e5abe292b: Pull complete
04155d74e8b4: Pull complete
7c2744d8f2aa: Pull complete
Digest: sha256:522827fe622024 (以下省略)
Status: Downloaded newer image for cloudflare/cloudflared:latest
d45d53821 (以下省略)
docker run
コマンドが成功すると「Connectors」欄の表示が切り替わります。
この状態は、トンネルが開通したことを示しています。
続けて「次へ」ボタンをクリックします。

③ パブリックホスト名の登録
トンネル経由で接続する「パブリックホスト」を登録します。
登録したパブリックホスト名(サブドメイン名)は DNS の Aレコード として登録され、インターネット側からの名前問い合わせに対して「サーバーのIPアドレス」を返却します。
登録画面には IPアドレス の入力欄がありません。
にも関わらず nslookup
や dig
コマンドでは IPアドレスが返却されます。
実は 返却されるのは「cloudflare が運用する IPアドレス」です。
パブリックホスト名 一つに対して複数の IPアドレス が自動的に割り当てられます。
以下は、dig
コマンドの実行結果(一部)です。
dify.■■■■■■■.■■■. 105 IN A 104.21.80.1
dify.■■■■■■■.■■■. 105 IN A 104.21.96.1
dify.■■■■■■■.■■■. 105 IN A 104.21.48.1
dify.■■■■■■■.■■■. 105 IN A 104.21.112.1
dify.■■■■■■■.■■■. 105 IN A 104.21.64.1
dify.■■■■■■■.■■■. 105 IN A 104.21.16.1
dify.■■■■■■■.■■■. 105 IN A 104.21.32.1
■■■■■■■.■■■. 172605 IN NS aliza.ns.cloudflare.com.
■■■■■■■.■■■. 172605 IN NS mitch.ns.cloudflare.com.
上記は、パブリックホスト名として「dify」を登録した後の確認結果です。
cloudflare 管理下の IPアドレス や ネームサーバー名 が登録されています。
パブリックホスト名 として、「サブドメイン」「ドメイン」「パス(省略可)」を入力します。(インターネット側からアクセスするときの URL を表しています)
サービス の「タイプ」「URL」には、「cloudflared コンテナからアクセスするときの プロトコル/URL」を入力します。
項目 | 設定内容 | 備考 |
---|---|---|
サブドメイン | dify | |
ドメイン | (登録先ドメイン) | |
タイプ | HTTP | |
URL | localhost:20080 |
--network=host オプションを付けてコンテナを起動しているので、localhostでも接続可能。 |

「トンネルを保存」ボタンをクリックすると、パブリックホスト名の登録は完了です。
接続確認
Dify Server と同じネットワーク内に存在する、別PCのブラウザからアクセスしてみます。
接続先の URL は「https://dify.■■■■■■■.■■■ 」です。

特に問題なくログインページが表示されました。
証明書も正式なものが適用されているようです。

なぜ dify.■■■■■■■.■■■ でアクセスできるのか?
同じネットワーク内に存在するとは言え、別のPC から「dify.■■■■■■■.■■■」という名前で Dify Server へアクセスできています。
Home Network 内の DNS サーバー や PC内の hosts ファイルも編集していません。
どういう理屈で接続できているのでしょうか?

「一度 インターネットへ出た後、cloudflare の Edge Server 経由でアクセスしている」が、その答えとなります。
かなりの回り道なので通信パフォーマンスの低下は否めませんが、特に何もしなくても 同じ URL でアクセスできるなら それに越したことはありません。
(正直、Home Network 内で独自の名前解決を図るのは面倒くさいのです)
回り道の影響が顕著に表れるまで、当面 このまま運用することにします。
HTTPS通信の強制
ところで、この時点では「http://dify.■■■■■■■.■■■ 」を指定したときも Dify Server へ接続できてしまいます。
デリケートな情報を扱うことを考えると、暗号化されない「HTTP通信」が可能 という状況は 好ましくありません。
通信設定を変更し、「HTTP で接続されたら強制的に HTTPS に切り替える」ことにします。
cloudflare へログインし、アカウント ホーム画面の ドメイン名をクリックします。

SSL/TLS メニューを展開し、「エッジ証明書」をクリックします。

「常に HTTPSを使用」を「ON」状態に変更します。(既定は「OFF」)

これで「http://dify.■■■■■■■.■■■ 」の接続が 自動的に「https://dify.■■■■■■■.■■■ 」へ切り替わるようになりました。
終わりに
「Dify によるアプリ開発」の環境構築が、ようやく ひと段落付きました。
自宅・外出先 のどちらでも、全く同じように開発作業を進めることが可能です。
ただ…
公開したアプリに対する アクセス制限 を行う仕組みがありません。
アプリの URL を知っているユーザーは、何の確認もなくアプリを利用できてしまうのです。
これはセキュリティの観点からは「問題あり」です。
「アプリへのアクセス制限」の実現方法を模索する必要がありそうです。
いろいろと検討中ですが、別の機会を設けて 試行錯誤 することにしましょう。