Cloudflareを使用してDockerコンテナに安全なアクセスを設定する方法


はじめに

CloudflareのZero Trust Network Access(ZTNA)を使って、Dockerコンテナに安全にアクセスする方法を解説します。ZTNAは、特定のリソースへのアクセスをセキュアに管理する技術です。このガイドでは、CloudflareでDNSを設定し、cloudflared をDockerコンテナに追加する方法を紹介します。

類似のサービスとしては、ngrokがありますが、恒常的にコンテナを特定のURLで公開できる点が、ZTNAを使うメリットとなります。

なお、ZTNAは以前は、Cloudflare Tunnel、もしくはCloudflare Accessと呼ばれていたものがリブランディングで名称が変わり、機能追加されたものです。

必要な前提条件

このガイドを開始する前に、以下の条件を満たしていることを確認してください:

  1. CloudflareでDNSが設定されている。
  2. CloudflareにてZTNAが有効になっている。

今回は、使用するドメイン名として XXX.mydomain.com を使用するもの仮定しています。


また、今回公開するdockerコンテナーは、最近話題のdifyをセルフホストするcompose.yamlを使うものと仮定して進めます

Step 1: cloudflaredの設定

始めに、Cloudflareの管理画面を開き、メニューより「Zero Trust」を選びます

ここで新しくトンネルを追加します。これは、インターネットからあなたのコンテナに対してセキュアな経路を提供します。

トンネルにはわかりやすい名前をつけてください。今回は、dify-containerという名前にします。

cloudflared(CloudflareのZTNAクライアントソフトウェア)をコンテナとして追加します。コンテナ用の設定トークンもこの段階で生成されますので、コピーしておきす。

Step 2: Docker Composeファイルの編集

次に、docker-compose.yaml ファイルを編集して、cloudflared コンテナを設定します。下記はその一例です:

version: '3.5' # Ver 3.5以上でサポートされる機能を使っています

networks:
  my-network:
    driver: bridge

# 定義済みのコンテナにmy-networkを使う設定を追加します
services:
  api:
    # (中略)
    networks:
      - my-network

  # 残りの他すべてのコンテナーについてもmy-networkを使う設定を追加します

  # 最後にcloudflaredコンテナーを追加します
  cloudflared:
    image: cloudflare/cloudflared:latest
    command: tunnel --no-autoupdate run --token ここにトークンを入力
    restart: always
    networks:
      - my-network

Step 3: コンテナの再起動

編集した設定でコンテナを再起動します。これには次のコマンドを使用します:

docker-compose down && docker-compose up -d

Step 4: Cloudflare管理画面で接続確認

コンテナが再起動したら、Cloudflareの管理画面でcloudflaredが正しく接続されているかを確認します。

Step 5: コンテナー公開の設定

まず公開したいコンテナー名を調べます。今回は、docker-nginx-1です。

docker ps
CONTAINER ID   IMAGE                              COMMAND                  CREATED      STATUS                PORTS                               NAMES
7d682c400a5e   nginx:latest                       "/docker-entrypoint.…"   2 days ago   Up 2 days             0.0.0.0:80->80/tcp, :::80->80/tcp   docker-nginx-1
a93bef1dc17e   langgenius/dify-api:0.6.6          "/bin/bash /entrypoi…"   2 days ago   Up 2 days             5001/tcp                            docker-api-1
e2532afc0e2a   langgenius/dify-api:0.6.6          "/bin/bash /entrypoi…"   2 days ago   Up 2 days             5001/tcp                            docker-worker-1
7ae98669ce0c   langgenius/dify-sandbox:0.1.0      "/main"                  2 days ago   Up 2 days                                                 docker-sandbox-1
940dbd84d824   postgres:15-alpine                 "docker-entrypoint.s…"   2 days ago   Up 2 days (healthy)   5432/tcp                            docker-db-1
582389a4b6be   semitechnologies/weaviate:1.19.0   "/bin/weaviate --hos…"   2 days ago   Up 2 days                                                 docker-weaviate-1
2dbd8cbed049   langgenius/dify-web:0.6.6          "/bin/sh ./entrypoin…"   2 days ago   Up 2 days             3000/tcp                            docker-web-1
c50662adbb30   redis:6-alpine                     "docker-entrypoint.s…"   2 days ago   Up 2 days (healthy)   6379/tcp                            docker-redis-1
7d04f184a7e6   cloudflare/cloudflared:latest      "cloudflared --no-au…"   2 days ago   Up 2 days                                                 docker-cloudflared-1

ZTNAのTunnel管理画面で、先ほどのトンネルの設定をします

Public Hostname タブを開き

公開したいFQDNと、どのコンテナーに通信を転送するかを指定します

Step 6: 動作確認

最後に、外部からHTTPS経由でCloudflareにアクセスし(今回は、https://dify.mydomain.com/ )、内部ではHTTPでNginxコンテナに接続されていることを確認します。これにより、セキュアな接続が確立されていることを確かめられます。

なお、HTTPSで利用するサーバー証明書はLets Encryptにて発行され、自動的に適用されます

まとめ

この記事では、Cloudflareを使用してDockerコンテナへのセキュアなアクセスを構築する方法を紹介しました。これにより、インターネットからのローカルコンテナー環境へアクセスが必要な開発も可能になります。