【Firebase】Firebase EmulatorをDocker上で起動する
割と既出かもしれませんが、DockerでFirebase Emulatorを動かしてみました。しかし、終了時のexportなどちょい手こずった箇所があったのでまとめてみます。
2024年03月13日
関連記事
毎度のこと、このリポジトリを使用して作業を進めていきます。
前提
- DockerでFirebaseEmulatorを動かしたい人
- Firebase Emulatorのセットアップが完了していること(firebase.jsonを確認)
- Firebase Storageのセットアップが完了していること
- Firebase Authのセットアップが完了していること
ディレクトリ構成
詳細はこちらをご覧ください
containers/
├── Dockerfile
├── bin
├── config
├── data
├── export.sh
└── start_firebase.sh
docker-compose.yml
package.json
yarn.lock
node_modules
.output
.firebaserc
firebase.json
firestore.indexes.json
firestore.rules
storage.rules
Dockerfile
エミュレーターを動かすだけなので、基本的にこのままでいいと思います。
FROM ubuntu:20.04
RUN apt update && \
apt install -y ca-certificates-java && \
update-ca-certificates -f && \
apt install -y curl openjdk-17-jdk && \
curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && \
apt install -y nodejs imagemagick
RUN npm install -g yarn firebase-tools
RUN ln -sf /usr/share/zoneinfo/Japan /etc/localtime
docker-compose.yml
コンテナ名やvolumesは各々お好きなように。
ちなみにFirebase Functionsには対応させておりませんのでご了承を。
version: '3.9'
services:
firebase:
container_name: study-firebase
build:
context: .
dockerfile: ./containers/Dockerfile
volumes:
- ./package.json:/usr/src/app/package.json
- ./yarn.lock:/usr/src/app/yarn.lock
- ./node_modules/:/usr/src/app/node_modules
- ./.output/:/usr/src/app/.output
- ./.firebaserc:/usr/src/app/.firebaserc
- ./firebase.json:/usr/src/app/firebase.json
- ./firestore.indexes.json:/usr/src/app/firestore.indexes.json
- ./firestore.rules:/usr/src/app/firestore.rules
- ./storage.rules:/usr/src/app/storage.rules
- ./containers/:/usr/src/app/containers
- ./containers/bin/:/root/.cache:cached
- ./containers/config/:/root/.config:cached
ports:
- 9099:9099 # Firebase Authentication
- 8080:8080 # Cloud Firestore
- 5000:5000 # Firebase Hosting
- 9199:9199 # Cloud Storage
- 4000:4000 # Emulator Suite UI
- 9150:9150 # Firestore Emulator UI websocket
working_dir: /usr/src/app
command: ./containers/start_firebase.sh ${EXPORT_INTERVAL}
tty: true
もし認証情報が必要な場合は以下のコマンドを。
docker compose run --rm firebase firebase login --no-localhost
ちょっとした問題点
通常、エミュレータ起動のコマンドの引数に--export-on-exit
をつければ、終了時にエクスポートできるのですが…
どうにも再起動時にデータが保存されていないようで、各所で悲鳴が上がっています。
定期的にexportする
docker-compose.ymlにも記載しましたが、./containers/start_firebase.sh ${EXPORT_INTERVAL}
としています。
ちょっと力技な気がしますが、デフォルトで60秒おきに。EXPORT_INTERVAL=0
とすると保持しないようにしています。
#! /bin/bash
SCRIPT_DIR="$(dirname "$0")"
BASE_DIR="$(dirname "$SCRIPT_DIR")"
DATA_DIR="${BASE_DIR}/containers/data"
# Set export interval
EXPORT_INTERVAL=${1:-60}
if ! [[ $EXPORT_INTERVAL =~ ^[0-9]+$ ]]; then
echo "デフォルトの60秒に設定します。"
EXPORT_INTERVAL=60
fi
echo "INTERVAL: ${EXPORT_INTERVAL}"
# Javaオプションを設定し、Firebaseエミュレータを起動
export JAVA_TOOL_OPTIONS="-Xms4g -Xmx8g"
TZ=JST firebase emulators:start --project=default --import="${DATA_DIR}" &
# エミュレータが起動したかどうかをチェック
EMULATOR_URL="http://127.0.0.1:4000"
MAX_RETRIES=5
for ((i=1; i<=MAX_RETRIES; i++)); do
sleep 5
if curl -LI "${EMULATOR_URL}" -o /dev/null -w '%{http_code}\n' -s | grep -q "200"; then
echo "Firebaseエミュレータが起動しました。"
break
fi
echo "エミュレータの起動を待っています... 試行回数 $i / $MAX_RETRIES"
done
# スクリプト終了時の処理関数
cleanup() {
echo "Firebaseエミュレータを停止しています..."
firebase emulators:export "${DATA_DIR}"
exit
}
# シグナルトラップの設定
trap cleanup SIGINT SIGTERM
# 定期的なエクスポート
while [ ${EXPORT_INTERVAL} -ne 0 ]; do
sleep "${EXPORT_INTERVAL}"
"${SCRIPT_DIR}/export.sh"
done
wait
エクスポート用のスクリプトは以下の通り。
#! /bin/bash
SCRIPT_DIR="$(dirname "$0")"
BASE_DIR="$(dirname "$SCRIPT_DIR")"
DATA_DIR="${BASE_DIR}/containers/data"
firebase emulators:export -f ${DATA_DIR}
おわり
今後この環境で認証、テストなどを書いていきます。
今回の記事では要点のみを書いておりますので、試したい方はこちらのリポジトリをご参考にどうぞ。