📱

Caddyでローカル開発サーバにモバイル実機からアクセスする

に公開

はじめに

Webアプリケーションのモバイルでの実装にあたり、PCブラウザのdeveloper toolのエミュレータを用いてモバイル向けのUI実装を行う場面は多いと思います。

UIの実装だけならそれでも十分なのですが、接続機器の動作確認、モバイルに固有の問題の調査などではどうしても実機で動作させたいこともあります。

開発時はローカルPCに開発用のサーバを建てて行うことがほとんどなので、プロキシサーバ経由で実機からのアクセスをローカルPCのサーバで受け付けるようにする解決策を採用する方が多いでしょう。

個人的には以前に Charles Proxy を使っていたのですが、今回Caddy を使ってみたところ、設定も容易でやりたいことも素早く実現できたのでご紹介します。

Caddyとは

Go言語で実装された、2015年発表の比較的新しいWebサーバです。

今回は開発用途なので使用していないですが、大きな特徴として、HTTPS通信を自動化することができるという点があります。
ドメイン設定を行うとまだ登録されていないドメインへのリクエストであれば自動でACMEを経由して、証明書を発行してくれます。Let's Encryptがデフォルトの認証局となります。
サーバが起動中であれば更新も自動化されます。
Certbotの設定が要らないのは良いですね。

Caddyfileの設定もわかりやすく、Go言語の実装でコマンド一発で立ち上げられるバイナリが提供されているのも、特に今回の開発用途では非常に魅力的です。

筆者の環境

今回紹介するコードは以下の環境での動作確認をしています。

  • MacOS: 15.4.1
  • iOS: 26.0.1(iPhone 17 Pro)
  • Caddy: v2.10.2

セットアップ方法

今回はforwardproxy pluginを使うので、xcaddyをインストールして、ソースコードからビルドします。

$ go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
$ xcaddy build \
    --with github.com/caddyserver/forwardproxy \
    --output "$YOUR_OUTPUT_PATH"

pluginが必要のない方は、以下の手順でそれぞれのプラットフォームに沿ったインストールをするのが良いです。

https://caddyserver.com/docs/install

サンプルプロジェクト

以下にサンプルプロジェクトを作成しました。
この記事ではCaddyの動作を中心に説明するので、細かいセットアップ方法などは以下を参照してください。

https://github.com/joe-re/caddy-my-todo

Caddyfile

{
    admin off
    log {
        output stdout
        format console
        level DEBUG
    }
}

app.my-todo.localhost {
    tls internal
    reverse_proxy localhost:3000 {
        header_up Host {host}
    }
}

api.my-todo.localhost {
    tls internal
    reverse_proxy localhost:3001 {
        header_up Host {host}
    }
}

:3128 {
    forward_proxy {
        hide_ip
        hide_via
        acl {
            # 特定のドメインを許可
            allow cdn.jsdelivr.net
            allow *.jsdelivr.net
            allow *.cdnjs.cloudflare.com
            allow *.my-todo.localhost

            deny all
        }
    }
}

forward proxy設定

ここの設定。

:3128 {
    forward_proxy {
        hide_ip
        hide_via
        acl {
            # 特定のドメインを許可
            allow cdn.jsdelivr.net
            allow *.jsdelivr.net
            allow *.cdnjs.cloudflare.com
            allow *.my-todo.localhost

            deny all
        }
    }
}

3128ポートをプロキシサーバに割り当てています。

モバイル側では、プロキシ設定よりホストのプライベートIPと3128ポート指定して、プロキシサーバを通します。

ここでcdnなどアプリケーション要件で必要な宛先と、アプリケーションの宛先を通すようにしています。
今回は別でDNSサーバを建てたりはしていないので、宛先の解決はhostに任せることになります。
/etc/hostsを設定し、アプリケーションの宛先は解決できるようにしておきます。

127.0.0.1 app.my-todo.localhost
127.0.0.1 api.my-todo.localhost

reverse proxy設定

ここの設定

app.my-todo.localhost {
    tls internal
    reverse_proxy localhost:3000 {
        header_up Host {host}
    }
}

api.my-todo.localhost {
    tls internal
    reverse_proxy localhost:3001 {
        header_up Host {host}
    }
}

reverse proxyを設定し、それぞれの宛先でローカルで起動しているサーバに向くようにします。

addressの記法と動作はこちらのドキュメントにまとまっています。
https://caddyserver.com/docs/caddyfile/concepts#addresses

From the address, Caddy can potentially infer the scheme, host and port of your site. If the address is without a port, the Caddyfile will choose the port matching the scheme if specified, or the default port of 443 will be assumed.

とあるので、TLSのデフォルトである443ポートがバインドされます。

tls internalで証明書を有効にしていますが自己証明書なので、ブラウザで動作確認を行う際には直接URLを入力してブラウザ上でアクセスして、api、app両方ともにアクセス許可をする必要があります。

おわり

今回はCaddyを用いて、ローカルサーバにモバイルの実機からアクセスを行い、動作確認を行う方法を紹介させていただきました。

Caddyの有用性が伝わっていれば嬉しいです。

どなたかの参考になれば幸いです。

PeopleXテックブログ

Discussion