y-ohgi's blog

TODO: ここになにかかく

Docker でFirebase ローカルエミュレータを立ち上げる

公式のものがみつからなかったのでDockerfile を書きました。

Docker イメージの作成

予めFirebase のコンフィグ firebase.json を用意しておきます。
ここで立ち上げたいサービスの宣言をします。コンテナへのアクセスを受け付けるために host: "0.0.0.0" を忘れずに設定しましょう。

{
  "emulators": {
    "firestore": {
      "host": "0.0.0.0",
      "port": "8080"
    },
    "auth": {
      "host": "0.0.0.0",
      "port": "9099"
    },
    "ui": {
      "enabled": true,
      "host": "0.0.0.0",
      "port": "4000"
    }
  }
}

https://firebase.google.com/docs/emulator-suite/install_and_configure?hl=ja#security_rules_configuration

Dockerfile を作ります。
エミュレータの実行にはjdk とnode が必要なためインストールします。その後npm 経由でfirebase コマンドをインストールして先ほど作成した firebase.json を入れて完成です。

FROM openjdk:slim

RUN set -ex \
  && apt-get update \
  && apt-get install -y curl \
  && curl -sL https://deb.nodesource.com/setup_14.x | bash \
  && apt-get install -y nodejs \
  && npm install -g firebase-tools

COPY firebase.json firebase.json

# Emulator Suite UI
EXPOSE 4000
# Auth
EXPOSE 8080
# Firestore
EXPOSE 9099

ENTRYPOINT ["firebase"]

エミュレータの起動

まずはビルド。

$ docker build -t firebase .

アクセストークンの取得。既に存在する場合はスキップです。
ホームディレクトリの .config/configstore/ へ認証情報が作られるので、ホームディレクトリごとマウントしています。( .config ディレクトリなかったりするとめんどうなので。。。

$ docker run -it -v $HOME:/root firebase init --no-localhost

エミュレータを起動。
firebase.json で定義したポートをマッピング、先ほど作成した認証情報をマウント、最後に連携するプロジェクト名を引数へ。

$ docker run \
  -p 4000:4000 \
  -p 8080:8080 \
  -p 9099:9099 \
  -v $HOME/.config:/root/.config \
  firebase emulators:start --project <PROJECT NAME>

 :

┌─────────────────────────────────────────────────────────────┐
│ ✔  All emulators ready! It is now safe to connect your app. │
│ i  View Emulator UI at http://0.0.0.0:4000                  │
└─────────────────────────────────────────────────────────────┘

┌────────────────┬──────────────┬───────────────────────────────┐
│ Emulator       │ Host:Port    │ View in Emulator UI           │
├────────────────┼──────────────┼───────────────────────────────┤
│ Authentication │ 0.0.0.0:9099 │ http://0.0.0.0:4000/auth      │
├────────────────┼──────────────┼───────────────────────────────┤
│ Firestore      │ 0.0.0.0:8080 │ http://0.0.0.0:4000/firestore │
└────────────────┴──────────────┴───────────────────────────────┘

localhost:4000 でFirebase エミュレータUI を確認。

その他

firebase.json を起動時に渡す場合の例

$ docker run \
  -p 4000:4000 \
  -p 8080:8080 \
  -p 9099:9099 \
  -v $HOME/.config:/root/.config \
  -v `pwd`:/firebase.json \ # <- new !!
  firebase emulators:start --project <PROJECT NAME>

最後に

ローカルにJVM もNode も入ってないし入れたくないのでつくりました。
僕がここで公開したDocker イメージ含め野良イメージを使うのは何はいってるかわからないので避けたほうが良いですが、こういったローカル用のCLI をイメージに固めて自分のDockerHub に置いておくといつでも叩けるので楽ですね。
個人的にシングルバイナリのCLI であればほいほいローカルにいれたりするのですが、特定のランタイムを要求されると忘れた頃にバージョン合わせゲームが発生してしまうのがつらいです。今回とかjvm とnode の2つを要求されたりしてたり。