はじめに
Flutterでアプリを作成するにあたって、Firebaseを使用しようと考えたのですが、
複数人で作成を行う場合にローカル環境を横展開できれば良いなと思い、環境構築を行いました。
(最終的にはローカルでFireStoreを使用できるようにする予定)
本題
前提
FlutterアプリにFirebaseを組み込む部分に関しては、本記事では割愛します。
- Dockerfileの作成(Flutter)
- Dockerfileの作成(Firebase)
- imageの作成
- docker-compose.yamlの作成
- firebaseとの疎通確認
1. Dockerfileの作成(Flutter)
Flutter用のDockerfileをubuntuベースで作成。
AndroidSDK用に必要なものが多く、パッケージのインストール時にエラーが出た場合は適宜追加します。
FROM ubuntu:20.04
LABEL manintainer hogehoge
ENV TZ=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update && apt-get install -y \
autoconf \
bash \
bzip2 \
curl \
file \
wget \
unzip \
gnupg \
software-properties-common \
vim \
git \
clang \
cmake \
ninja-build \
pkg-config \
libgtk-3-dev
#Flutter
RUN echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list \
&& wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& add-apt-repository ppa:maarten-fonville/android-studio
RUN apt-get update && \
apt-get -y -q install \
xz-utils libglu1-mesa openjdk-8-jdk google-chrome-stable android-studio \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Android
WORKDIR /usr/local
RUN mkdir -p Android/sdk
ENV ANDROID_SDK_ROOT /usr/local/Android/sdk
RUN mkdir -p .android && touch .android/repositories.cfg
RUN wget -O sdk-tools.zip https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip
RUN unzip sdk-tools.zip && rm sdk-tools.zip
RUN mv tools Android/sdk/tools
RUN cd Android/sdk/tools/bin && yes | ./sdkmanager --licenses
RUN cd Android/sdk/tools/bin && ./sdkmanager "build-tools;29.0.2" "patcher;v4" "platform-tools" "platforms;android-29" "sources;android-29"
ENV PATH "$PATH:/usr/local/Android/sdk/platform-tools"
# Dart
RUN sh -c 'curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list'
RUN apt-get update && \
apt-get -y -q install \
dart \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Download Flutter SDK
RUN git clone https://github.com/flutter/flutter.git
ENV PATH "$PATH:/usr/local/flutter/bin"
# Flutter Web
RUN flutter config --enable-web
RUN mkdir /flutter
WORKDIR /flutter
2. Dockerfileの作成(Firebase)
Firebase用のDockerfileをubuntuベースで作成。
今回はFirebase Local Emulator Suite をlocalで使用することを目的としています。
FROM ubuntu:20.04
RUN apt-get update -y
RUN apt-get install -y curl openjdk-11-jre-headless vim
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - \
&& apt-get install -y nodejs
RUN npm install -g firebase-tools
RUN mkdir /firebase
WORKDIR /firebase
3. imageの作成
各Dockerfileのあるディレクトリでそれぞれbuildします。
docker image build -t flutter:latest .
docker image build -t firebase:latest .
4. docker-compose.yamlの作成
それぞれimageの作成が完了したのち、docker-compose.yamlの作成をします。
プロセスが動いていないと、コンテナがすぐに落ちてしまうため、
tty:true
の指定かそれでも解決しない場合はコマンドの指定をしておくとよいと思います。
環境変数やportの指定は適宜調整。
version: '3.4'
services:
flutter:
container_name: "flutter"
hostname: "flutter-base"
image: "flutter:latest"
volumes:
- ../../hoge/:/flutter
command: /bin/bash -c "/bin/bash"
environment:
- FIRESTORE_EMULATOR_HOST=localhost:8080
tty: true
firebase:
container_name: "firebase"
hostname: "firebase-tools"
image: "firebase:latest"
volumes:
- ../../hoge/firebase/:/firebase
- ../../hoge/firebase/bin/:/firebase
- ../../hoge/firebase/config/:/firebase
ports:
- 8081:8081 # Emulator Suite UI
- 5002:5002 # Firebase Hosting
- 5001:5001 # Clound Functions
- 9000:9000 # Realtime Database
- 8080:8080 # Cloud Firestore
- 8085:8085 # Cloud Pub/Sub
working_dir: /firebase
command: /bin/bash -c "/bin/bash"
tty: true
networks:
hogehoge:
external: true
5. firebaseとの疎通確認
docker-compose up -d
でコンテナの立ち上げを行います。
コンテナがそれぞれ立ち上がったら、firebaseのコンテナにアクセスし、
firebaseへのログインとプロジェクトの初期化を行います。
$ docker exec -it 1e4812964fba bash
root@firebase-tools:/firebase# firebase login --no-localhost
root@firebase-tools:/firebase# firebase init
その後、firebase.jsonのhost/portの指定を以下のように変更します。
"emulators": {
"auth": {
"host": "0.0.0.0",
"port": 9099
},
"functions": {
"host": "0.0.0.0",
"port": 5001
},
"firestore": {
"host": "0.0.0.0",
"port": 8080
},
"database": {
"host": "0.0.0.0",
"port": 9000
},
"hosting": {
"host": "0.0.0.0",
"port": 5002
},
"pubsub": {
"host": "0.0.0.0",
"port": 8085
},
"ui": {
"enabled": true,
"host": "0.0.0.0",
"port": 8081
},
"storage": {
"host": "0.0.0.0",
"port": 9199
},
"singleProjectMode": true
},
上記完了後、コンテナ内でfirebase emulators:start
を叩くと、以下のように
UIViewのURLが出るので、アクセスをします。
┌─────────────────────────────────────────────────────────────┐
│ ✔ All emulators ready! It is now safe to connect your app. │
│ i View Emulator UI at http://127.0.0.1:8081/ │
└─────────────────────────────────────────────────────────────┘
┌────────────────┬────────────────┬─────────────────────────────────┐
│ Emulator │ Host:Port │ View in Emulator UI │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Authentication │ 0.0.0.0:9099 │ http://127.0.0.1:8081/auth │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Functions │ 0.0.0.0:5001 │ http://127.0.0.1:8081/functions │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Firestore │ 0.0.0.0:8080 │ http://127.0.0.1:8081/firestore │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Database │ 0.0.0.0:9000 │ http://127.0.0.1:8081/database │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Hosting │ 0.0.0.0:5002 │ n/a │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Pub/Sub │ 0.0.0.0:8085 │ n/a │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Storage │ 0.0.0.0:9199 │ http://127.0.0.1:8081/storage │
└────────────────┴────────────────┴─────────────────────────────────┘
Emulator Hub running at 127.0.0.1:4400
Other reserved ports: 4500, 9150
Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files.
http://localhost:8081/
で以下のように表示されます。
疎通確認のため、適当なデータを作成します。
下記サイトにあるcurlのコマンドをflutterコンテナから叩いて、データが削除されていれば
コンテナ間での通信ができていることを確認できます。
https://firebase.google.com/docs/emulator-suite/connect_firestore?hl=ja#:~:text=your%2Dproject%2Did%22-,%E3%83%86%E3%82%B9%E3%83%88%E9%96%93%E3%81%A7%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%82%92%E3%82%AF%E3%83%AA%E3%82%A2%E3%81%99%E3%82%8B,-Firestore%20%E3%81%AE%E6%9C%AC%E7%95%AA
networkを作成している場合は、http://{コンテナ名}
で指定してあげます。
root@flutter-base:/flutter# curl -v -X DELETE "http://firebase:8080/emulator/v1/projects/hoge-project/databases/(default)/documents"
* Trying 172.18.0.2:8080...
* TCP_NODELAY set
* Connected to firebase (172.18.0.2) port 8080 (#0)
> DELETE /emulator/v1/projects/hoge-project/databases/(default)/documents HTTP/1.1
> Host: firebase:8080
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: application/json
< content-length: 4
<
{
}
* Connection #0 to host firebase left intact
これでEmulatorの立ち上げと疎通確認までが完了になります。
最後に
firestoreをローカルで使えるようになることは大きなメリットだと思っているので、
具体的なアプリとの実装含め、引き続き調べてみようと思います。