はじめに
ngrokを最近知って、ちょっと使ってみたいなと思ったので実践をする。
環境
Windows 11 Professional
Docker Desktop 4.34.1 (166053)
準備
ngrok
アカウントの取得- ローカル環境で適当なWebサーバを立てる
ngrokアカウントの取得
- ngrok の
Sign up
を選択する。 Sign up with GitHub
で、GitHub
アカウントを使って登録する。
※ここはお好みで- 出てくる内容に従って進めていき、ダッシュボードの表示まで行けば完了。
ローカル環境で適当なWebサーバを立てる
例によって、Docker
で構築をする。
compose.yml
を以下のように作成して、docker compose up -d
で立ち上げる。
services:
web:
image: nginx:1.27.1
ports:
- 80:80
localhost
で下記の画面になっていればOK.
ngrokを導入する
今回は、Docker
を利用しているので https://hub.docker.com/r/ngrok/ngrok のイメージを利用して実践をする。
https://ngrok.com/docs/getting-started/ を見てみると、
ngrok
エージェントをインストール- ngrok authtokenを設定
- ngrokを起動
上記で設定できるようだ。
Docker
で設定する場合は以下を見ればよさそうだ。
https://ngrok.com/docs/using-ngrok-with/docker/
compose.ymlにngrokのサービスを追加
バージョンは、現時点で最新の 3.15.0
を使用する。
イメージはngrok/ngrok:3.15.0-debian
とした。
services:
web:
image: nginx:1.27.1
ports:
- 80:80
ngrok:
image: ngrok/ngrok:3.15.0-debian
restart: unless-stopped
command:
- "start"
- "--all"
- "--config"
- "/etc/ngrok.yml"
volumes:
- ./ngrok.yml:/etc/ngrok.yml
ports:
- 4040:4040
※ Using ngrok with Docker Composeに沿って、構築をした。
バージョンの指定だけ自我を入れた。
ngrok.ymlの作成
ngrok.yml
をcompose.yml
と同じ階層に作成をする。
https://ngrok.com/docs/http/
https://ngrok.com/docs/agent/config/v3/ をもとに作成をする。
version: "3"
agent:
authtoken: [取得したauthtokenを入力]
endpoints:
- name: web
upstream:
url: http://web:80
protocol: http
動作確認
Docker
のビルド&コンテナの立ち上げ
docker compose up -d --build
- http://localhost:4040/ にアクセスをして、公開URLを取得する。
- 公開URLにアクセスをすると、
ngrok
のページが出てくるので「Visit Page」でページ遷移をする。
nginx
のスタートページ(ローカルと同じ)が表示されていればOK
補足:エラー内容
ngrok.yml
のurl
を間違えている
web
としてコンテナを定義しているのに、nginx
と誤った名前でurl
を記載してしまったため下記のエラーが発生した。
このようなエラー画面になる。
※わかりやすくエラーが書いてあるのでありがたい。
ローカル環境で対応していないhttp2プロトコルで接続しようとしている
http2
をupstream
のprotocol
に指定していたが、ローカル環境ではhttps
での接続は許可していないので使用できない。
おまけ: ngrokの動作の理解をしたい
ngrok
を起動してから、公開されるまでの流れの細部を知りたいので少し調べた。
まずは、公式ドキュメントにある下記を読んだ。
https://ngrok.com/docs/how-ngrok-works/
最初に疑問となったのは、接続の確立の仕方である。
一般的なPCであればファイアウォールがあるので、どうやってインターネットからローカル環境にアクセスできるのだろうと思った。
どうやら、ローカルのエージェントから ngrok
クラウドサーバに接続をしに行って、データのやり取りをするTLSのトンネルを作成することで実現しているようだ。
Unlike traditional reverse proxies, ngrok does not transmit traffic to your upstream services by forwarding to IP addresses. Instead, you run a small piece of software alongside your service that we call an agent which connects to ngrok’s global service via secure, outbound persistent TLS connections. When traffic is received on your endpoints at the ngrok edge, it is transmitted to the agent via those TLS connections and finally from the agent to your upstream service.
の部分で説明がされている。
エージェントをローカルで実行し、TLS接続を介してngrok
のサーバとやり取りするようだ。
上記から、ファイアウォールのアウトバウンド接続で、ngrok
で使用するポートが拒否されていたりすると、恐らく使用できないのだと思われる。
この点は注意が必要そうだ。
ローカルで起動→公開してアクセスするまでの流れをシーケンス図にまとめてみたので、下記のような理解でよいのだろう。
sequenceDiagram participant User as 開発者 participant ngrokLocal as ngrokローカルエージェント participant ngrokCloud as ngrokクラウドサーバー participant LocalServer as ローカルサーバー participant Client as 外部クライアント User->>ngrokLocal: ngrok起動とポート指定 (例: 80) ngrokLocal->>ngrokCloud: トンネル接続リクエスト送信 ngrokCloud-->>ngrokLocal: 公開URLの生成と通知 (例: https://abcdef.ngrok.io) Client->>ngrokCloud: 公開URLにリクエスト送信 (例: https://abcdef.ngrok.io) ngrokCloud->>ngrokLocal: リクエストをトンネル経由で転送 ngrokLocal->>LocalServer: ローカルサーバーにリクエストを転送 LocalServer-->>ngrokLocal: レスポンスを返す ngrokLocal-->>ngrokCloud: トンネルを通してレスポンスを返す ngrokCloud-->>Client: クライアントにレスポンスを返す
ローカルエージェントからngrok
クラウドサーバまではTLS接続で暗号化されているので、この点は盗聴の対策などもできている。
参考
Dockerでngrokを利用する
https://qiita.com/ntm718/items/9c374406f5b9457e7878ngrokをdocker composeで使う
https://brainlog.jp/server/docker/post-3669/
おわりに
ngrok
というサービスを最近知ったので使用してみた。
ローカル環境を外部に公開できるは便利かと思ったが、業務だと大体のケースでテスト環境を作成しているのでどういうケースで使うかは考えてみたい。
作ったサービスをサーバを立てずにサクッとみてもらいたいというときには便利そうだ。
ただ、その場合のセキュリティ担保をどうするかについては、ngrok
のドキュメントとか読んでみればわかるのだろうか、今後の課題としよう。