search
LoginSignup
39

More than 3 years have passed since last update.

posted at

Organization

ngrokを無料プランでURL固定してみる

この記事は スマートスピーカー2 Advent Calendar 2018 8日目 の穴埋め記事です。

ngrokとは

httpトンネリングサービスです。
ローカルPCで立ち上げているプログラムをポート開放したりせず、ngrokが発行するURLを経由して外部公開することができます。
さらにhttpsや他のtcpプロトコルにも対応しています。

ngrok

私はスマートスピーカースキル開発でngrokを使用しており、シミュレーターや実機テストの際にLambda等FaaSへデプロイせずにngrokでローカルでスキルのプログラムを動かしテスト/デバッグを行っています。

なぜngrokを使うのか

理由は3つあります。

1. デプロイが手間

まずスマートスピーカースキルのデプロイ先としてはAWS LambdaやFirebase Functionsが一般的ですが、ソース修正する度にソース固めてデプロイするのが手間である点です。
シェルやバッチ組めばコマンドで一発ですが、その一発も手間です。

対してngrokはローカルで動いているのでデプロイもクソもありません。
ここで「プログラムの再起動でコマンド叩くだろ」と思われるでしょうが、後述するnodemonとの組み合わせで何もする必要がありません。

2. ログ反映が遅い

1つ目に関連しますが、クラウドではログの反映が遅いことです。
ここはぶっちゃけ、AWS(CloudWatch)は半年ぐらい前は1~2分はかかりほんと我慢ならなかったのですが、最近はわりとすぐにログ出てくれてます。
しかしラグは当然あります。

Firebaseも半年ぐらい前は同じぐらいログ反映に時間かかっていました。
(最近触ってないので今どうかはわかりません…)

対してngrokではプログラムはローカルで動いているので、当然ログは即出ます。

3. nodemon/ts-nodeとの組み合わせがすこぶる便利

nodemon」とは、プログラムを実行しつつ、ソースに修正があったら自動でプロセスを再起動してくれるNode.jsツールです。
これを組み合わせることでCtrl + Sで修正が即反映されます。

ts-node」は.tsファイルを自動でコンパイル実行してくれるツールです。
TypeScriptを使っている場合はこれも組み合わせることで爆速ローカル開発ができます。
(コンパイルは多少重いのでマシンスペックに依存します)

参考
Node.jsのソース修正後、nodemonで自動再起動
ts-nodeでCLI上でのtypescriptの検証がめっちゃ楽になった話
【ホットリロード】nodejs + TypeScriptでサーバーサイドを開発している時に、コードを編集したら自動リロードさせる。

ngrok(無料版)の弱点

ngrokの素晴らしさは分かって頂けたかと思いますが、そんなngrokにも1点弱点があります。
ngrokには無料版/有料版があり、無料版ではURLが固定できないという点です。
ngrokのコマンド実行時に払い出されるURLのドメイン部が毎回乱数となるのです。

以下はngrokコマンド実行結果になりますが、ForwardingにあるURLのドメイン部が実行するたび変わります。

$ ngrok http 3000

ngrok by @inconshreveable                                       (Ctrl+C to quit)

Session Status                online
Account                       Miso Tanaka (Plan: Free)
Version                       2.2.8
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://xxxxxxxx.ngrok.io -> localhost:3000
Forwarding                    https://xxxxxxxx.ngrok.io -> localhost:3000

Connections                   ttl     opn     rt1     rt5     p50     p90
                              26      0       0.00    0.00    5.05    9.54

HTTP Requests
-------------

無料プランでURL固定する方法

「無料プランでURL固定化」自体が限りなく黒いグレーな行為であるため、以下自己責任でお願い致します。

ちなみにURLを固定化しても1点、有料版には届かない点があります。
それは起動から8時間が経過するとトンネリングが無効化されるという点です。
しかしこれは開発やデバッグで使う分には不都合ないと思います。

結論はAmazon API Gateway(AWS)とAWS CLI

方法は至って簡単で、AWSのAPI Gatewayでngrokが生成したURLをパススルーさせます。
そしてngrokをNode.jsから実行し、同時にAWS CLIでAPI Gatewayを更新するコマンドを叩くだけです。

以下細かい手順になります。

API GatewayからAPIを作成

AWSコンソールよりAmazon API Gatewayを開き、「APIをの作成」ボタンを押します。
image

「API名」に「ngrok」とでも入れて(なんでもいいです)、「APIの作成」ボタンを押します。
image

このような画面になるので、「アクション」ボタン > 「メソッドの作成」と選択します。
image

リソースの「/」の下にセレクトボックスが出てくるのでとりあえず「ANY」を選択し、すぐ右にあるチェックマークを押します。
※ここは必要なメソッドに絞ってもいいです。例えばスマートスピーカースキルならPOSTを選択すれば十分でしょうし。
image

この画面まできたらコンソールの操作は完了です。
2箇所の赤枠部分にそれぞれ乱数のIDが入っているので、メモっておきます。
image

ngrok URL固定スクリプトを実行

以下のNode.jsプログラムを実行します。
前提として、Node.js、AWS CLIがインストールされていることです。

ngrokもNode.js版をインストールしていなければ入れます。

npm i -g ngrok

実行プログラムは以下になります。
先頭のconfigオブジェクトをいじります。

restApiIdには先ほどメモしたngrok(xxxxxxxx)の乱数部を入れます。
resourceIdには先ほどメモした/(xxxxxxxx)の乱数部を入れます。
httpMethodには先ほどANYを指定していればそのままで、ANY以外ならそれを指定してください。
portはローカル実行させるプログラムのポート番号を指定してください。

index.js
const config = {
    restApiId: "xxxxxxxx",
    resourceId: "xxxxxxxx",
    httpMethod: "ANY",
    port: 3000,
}

const execSync = require('child_process').execSync
const ngrok = require('ngrok')

const main = async () => {
    const ngrokUrl = await ngrok.connect(config.port)
    console.log(ngrokUrl)

    execSync(`aws apigateway put-integration --rest-api-id ${config.restApiId} --resource-id ${config.resourceId} --http-method ${config.httpMethod} --type HTTP_PROXY --integration-http-method ${config.httpMethod} --uri ${ngrokUrl}`)
    execSync(`aws apigateway create-deployment --rest-api-id ${config.restApiId} --stage-name prod`)
    console.log(`https://${config.restApiId}.execute-api.ap-northeast-1.amazonaws.com/prod`)
}
main()

あとは実行するだけです。

$ node index.js
https://xxxxxxxx.ngrok.io
https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod

返ってくる結果のうち、上の行がngrokが生成する乱数URLです。
これは一応表示していますが気にしなくていいです。

下の行が固定化されたURLになります。
xxxxxxxxxxの部分はrestApiIdが入ってきます。

あとは下の行のURLを開発やテストで使い回せばおっけーです。
ngrokを使う時にnodemonとあわせ上記のプログラムを実行しておきます。

以上、シェルやバッチ置いてパス通してすぐ実行できるようにしてもいいと思います。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
39