🐟

Dockerでngrokを起動してAWS IoT Coreの講読データを捌く

2023/05/15に公開

概要

https://zenn.dev/kunimasu/articles/52d27746d61d57

以前、AWS IoT CoreのMQTTをHTTPで会話する方法を書きました。
その延長で、関係者に環境を配布するケースを以下条件で考えてみたいと思います。

  • AWS IoT Coreの環境自体は事前に作成
  • サンプルアプリなので、JavaScriptで時間を掛けずに作成
  • ngrokでローカルとIoT Coreをトンネルする
  • Dockerで配布

ディレクトリ構成

必要最小限の構成です。

ls ./
Dockerfile
compose.yml
index.mjs
node_modules
package.json
pnpm-lock.yaml

各種ファイル

package.json
{
  "name": "mqtt_web_client",
  "version": "1.0.0",
  "description": "",
  "main": "index.mjs",
  "engines": {
    "node": ">=18",
    "pnpm": ">=8",
    "preinstall": "npx only-allow pnpm"
  },
  "packageManager": "pnpm@8.1.1",
  "scripts": {
    "start": "node index.mjs"
  },
  "dependencies": {
    "@hono/node-server": "^0.6.0",
    "hono": "^3.1.8"
  }
}
compose.yml
services:
  app:
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
      - 3000:3000
    container_name: app
  ngrok:
    container_name: ngrok
    image: wernight/ngrok:latest
    ports:
      - 4040:4040
    environment:
      NGROK_PORT: app:3000
    depends_on:
      - app
    networks:
      - default
Dockerfile
FROM debian:bullseye as builder

ARG NODE_VERSION=18.13.0
ENV PATH=/usr/local/node/bin:$PATH
ENV NODE_ENV production

RUN apt-get update; apt install -y curl python-is-python3 pkg-config build-essential && \
    curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
    /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
rm -rf /tmp/node-build-master

RUN mkdir /workspace-install
WORKDIR /workspace-install

COPY . .

RUN npm install -g pnpm
RUN pnpm i

FROM debian:bullseye-slim

COPY --from=builder /usr/local/node /usr/local/node
COPY --from=builder /workspace-install /app

WORKDIR /app

ENV PATH /usr/local/node/bin:$PATH

CMD [ "pnpm", "run", "start" ]
index.mjs
import { serve } from "@hono/node-server"
import { Hono } from "hono"

const app = new Hono()
app.post("/", async (c) => {
  const data = await c.req.json()
  console.log(data)
  return c.text("Hello!")
})

serve(app, (info) => {
  console.log(`Listening on http://localhost:${info.port}`)                                      
})

Docker起動

docker-compose up すると最終的には以下のログが出ます。

docker-compose up
 ✔ Container app    Recreated                                                                                                                    0.1s 
 ✔ Container ngrok  Recreated                                                                                                                    0.1s 
Attaching to app, ngrok
app    | 
app    | > mqtt_web_client@1.0.0 start /app
app    | > node index.mjs
app    | 
app    | Listening on http://localhost:3000

ngrokのダッシュボード

http://localhost:4040

リクエストを受信していない場合は、以下の表示です。
トンネルするエンドポイントを画面に表示してくれるので、このURLを使ってIoT Coreの送信先を登録します。

AWS IoT Coreの送信先として登録

管理 > メッセージのルーティング -> 送信先のメニューからngrokのHTTPS側のURLを登録します。その後、有効化のためのトークンを発行します。

IoT Coreの送信先のリクエストを受信するなどして、何かリクエストが届くと自動的にメッセージの表示を行ってくれます。


confirmationTokenが検証のトークンになるので、IoT Coreの送信先の確認用トークンへ入力します。

IoT Coreをトンネルする

IoT Coreへの講読時のルールと送信先を設定が完了していれば、講読したデータがIoT Coreに届く毎に以下のようにngrokのダッシュボードへ蓄積します。

最後に

サンプルレベルで誰かに共有、配布したいときに、Dockerでngrokを使うというのはとても簡単で良いですね。

Discussion