NuxtJs2.13 + FirebaseプロジェクトをDockerを使ってコンテナ化
NuxtJs2.13 + FirebaseプロジェクトをDockerのコンテナ化
今回のプロジェクトをDockerのコンテナで管理することにしました。開発環境のためのディレクトリーを作っておきます。
下記のようなディレクトリー構成にしました。
├── docker
├ ├── node
├── Dockerfile
├ ├── firestore_saver
├── Dockerfile
├ ├── firebase
│ ├── firestore
│ ├── Dockerfile
│ ├── firestore-run.sh
│ ├── export
├──firebase-export-metadata.json
│──firestore_export
│──firestore_export.overall_export_metadata
│──all_namespaces
│──all_kinds
│──all_namespaces_all_kinds.export_metadata
│──output-<番号>
└── docker-compose.yml
└── .env
└── firebase-blog → アプリケーションコード
まずdocker-compose.ymlファイルを作っておきましょう。
3つのコンテナを設定します。
- node-front
- firestore
Firestoreのエミュレーターの起動と管理するコンテナ - firestore-saver
ローカルデータを保存するためのコンテナ
docker-compose.ymlのNodeコンテナ設定をみていきます。
node:
build:
context: ./docker/node
volumes:
- ./firebase-blog:/app/firebase-blog:cached
container_name: node-front
tty: true
working_dir: /app/firebase-blog
ports:
- "3000:3000"
environment:
- HOST=0.0.0.0
アプリケーションのコードをキャッシュすることでビルドが速くなります。ポートの設定はyarn dev
を実行する時使われるポートを開くためです。localhostにアクセスするため環境変数をHOST 0.0.0.0
の設定をします。
nodeのDockerfileの中身はこちらです
FROM node:14
RUN apt-get update && \
apt-get install -y vim procps net-tools && \
apt-get clean;
nodeコンテナ内でVimを使うため、vimをインストールしています。
docker-compose.ymlとnode用のDockerfileを作成したら以下コマンドでコンテナのビルドと起動をしてみましょう。docker-compose up --build
Nuxtバージョン12.3以上を使っている場合package.jsonのdevコマンドでポートとホストの指定が必要です
ポートとホストを指定しないとコンテナ上でyarn dev
を実行する際にsseのエラーがおきてしまいます。“scripts”: {
“dev”: “HOST=0.0.0.0 PORT=<docker-compose.ymlで定義したポート> nuxt “,
nodeのコンテナ上でyarn dev
を起動してみましょうdocker exec -it node-front bash
yarn dev
ブラウザーでlocalhost:3000
で表示を確認しましょう
次に用意するコンテナはFirestoreのローカルエミュレーター用のコンテナ
firebase.jsonファイルの中身を確認するとそれぞれのエミュレーターはどのポートにサーバされているの設定ができます。
管理をしやすくするためにFirebase関連のファイルをfirebase-configディレクトリーに入れておきます。中身はFirebaseの設定、configファイル、ログファイルなどが入ります。
ローカルシステムとマッチするため、ホストを0.0.0.0に指定して、ポートはデフォルトは好きな使ってないポートに設定します。
この設定にすることによるエミュレーターを起動したらブラウザーでlocalhost:<ポート>でアクセスできるようになります。
"emulators": {
"firestore": {
"port": 8080,
"host": "0.0.0.0"
},
"ui": {
"port": "4000",
"host": "0.0.0.0"
},
}
Firestoreのdocker-compose.yml 設定
firestore:
image: firestore
depends_on:
- node
- firestore-saver
build:
context: ./docker/firebase/firestore
volumes:
- ./firebase-blog/firebase-config:/app/firebase-config:cached
- ./firebase-blog/firebase.json:/app/firebase-
config/firebase.json:cached
- ./firebase-blog/.firebaserc:/app/firebase-
config/.firebaserc:cached
- ./docker/firebase/firestore/export:/app/firebase-config/export
- ./docker/firebase/firestore/emulator_cache:/root/.cache
container_name: firestore
tty: true
working_dir: /app/firebase-config
ports:
- "8080:8080"
- "4000:4000"
environment:
- HOST=0.0.0.0
- TOKEN=${TOKEN}
- PROJECT_ALIAS=${PROJECT_ALIAS}
command: /bin/bash run-firestore.sh
このコンテナだけで使うことがないので、depends_onの設定でfirestoreコンテナが立ち上がるとnodeとfirestore-saverの両方が起動されるように設定します。
各Volumeを説明します
./docker/firebase/firestore/export:/app/firebase-config/export
./firebase-blog/firebase.json:/app/firebase-config/firebase.json:cached
./firebase-blog/.firebaserc:/app/firebase-config/.firebaserc:cached
Firebaseに関する設定やコンフィグのファイルはfirebase-configのディレクトリーに入っています。
ディレクトリーの中身はこちらです
.
├── firebase-blog
├ ├── firebase-config
│ ├── .firebaserc
├── firebase.json
├── firestore-debug.log
├── ui-debug.log
├── firstore.indexes.json
├── firestore.rules
├── export
├──firebase-export-metadata.json
│──firestore_export
│──firestore_export.overall_export_metadata
│──all_namespaces
│──all_kinds
│──all_namespaces_all_kinds.export_metadata
│──output-<番号>
毎回エミュレーターをインストールしないためにエミューレーターのキャッシュファイルもマウントしておきます
./docker/firebase/firestore/emulator_cache:/root/.cache
FirestoreのDockerfileの中身はこちらです。
FROM node:14
RUN apt-get update && \
apt-get install -y openjdk-8-jdk jq\
ca-certificates-java \
ant \
vim procps net-tools && \
apt-get clean && \
update-ca-certificates -f;
RUN yarn global add firebase-tools
COPY run-firestore.sh /usr/local/bin/run-firestore.sh
ベースはNodeでエミュレーターを使うためのイメージにJavaとVimを使いたかったので一緒にインストールしました。。また、コンテナ内で使うためVimもインストールしました。
今回、起動時の シェルでFirebaseコマンドを使うためにFirebaseCLIもインストールしました。
Firestoreコンテナの起動時にエミューレーターを起動したいので、run-firestore.shで起動しています。エミュレーターを起動する時にローカルに保存したデータを使いたいので、マウントされているディレクトリーからインポートしています。
#!/bin/bash
set -eu
auth=" - token $TOKEN"
echo "プロジェクト設定"
firebase use $PROJECT_ALIAS $auth
echo "Firestoreのエミュレーター起動開始 約2分"
firebase emulators:start - only firestore - import="./export/" $auth
最後にローカルデータを保存するためのコンテナを用意します。
firestore-saver:
build:
context: ./docker/firebase/firestore_saver
container_name: firestore-saver
environment:
- PROJECT_ID=${PROJECT_ID}
- FIRESTORE_EMULATOR_HOST=firestore:8080
volumes:
- ./docker/firebase/firestore/export:/firebase/firestore/export
command: /bin/bash run-saver.sh
起動時に実行するrun-saver.shの中身はこちらです。
#!/bin/bash
while true
do
curl -X POST -H "Content-Type: application/json" -d "{\"database\": \"projects/$PROJECT_ID/databases/(default)\", \"export_directory\": \"./export\", \"export_name\": \"firestore_export\"}" http://firestore:8080/emulator/v1/projects/$PROJECT_ID:export
sleep 5
done
Firestore-saverのDockerfile中身
FROM google/cloud-sdk:alpine
RUN apk add --update --no-cache openjdk8 \
&& gcloud components update \
&& gcloud components install cloud-firestore-emulator beta --quiet
COPY run-saver.sh /usr/local/bin/run-saver.sh
コマンドの詳しい説明はゆうくんのブログを参考に
環境を使ってみましょう
この三つのコンテナが用意すれば使い回せる開発環境ができます。
まずdocker-compose up —-build
を実行してみます。
ターミナルでエミュレーターの起動が終わるまでfirestore-exportのコンテナからエラーが表示されます。上から見てみると Could not resolve host: firestore
のエラーはホストとなっているコンテナが立ち上がってないという意味です。次は Failed to connect to firestore port 8080: Connection refused
Firestoreのコンテナが立ち上がっているけどポート8080にローカルエミュレーターはまだ起動されていないの意味です。その次は正常な動きです。
正常に立ち上がったNodeコンテナのログは以下です。
そして、最後にFirestoreとエミュレーターが正常に立ち上がったら以下のようなメッセージが表示されているはずです。
エミュレーターが起動されたら5秒ずつfirestore-saverが動いてローカルデータが保存されます。
全部が立ち上がったらNodeコンテナを入りyarn devを実行しましょう
各ポートにアクセスすると表示される画面を載せておきます
Dockerで環境を管理すると新しい開発メンバーのジョインやバージョン管理がよりやりやすくなります。
みなさんもDockerで環境構築してみましょう。