LoginSignup
5
1

GolangとFirestoreの開発環境をDockerで作る

Last updated at Posted at 2023-12-08

概要

Firestoreのエミュレータ構築は gcloud CLIを使う方法Firebase CLIを使う方法 があります。

どちらを使ってもよいのですがFirebase CLIを使う場合は、ブラウザ上でFirestoreのUIが使えるため、開発効率が上がりそうです。
ということでFirebase CLIでの構築をしていきます。

こんな人向け

  • CLIをローカル環境に入れたくない(Dockerを使いたい)
  • FirestoreにGoで読み書きをしたい
  • デプロイは特に考えず、お手軽にFirestoreの動作確認ができる環境を作りたい

環境構築

Dockerfileの設定

Firebaseエミュレータコンテナ用

Emulator Suite をインストールする前に、以下が必要です。

  • Node.js バージョン 16.0 以降
  • Java JDK バージョン 11 以降

公式ドキュメントによると、Firebaseエミュレータを使うには NodeとJavaが必要 とのことなので、nodeコンテナにJavaをインストールしました。
ついでにnpmでFirebase CLIをインストールしておきます。

firebase/Dockerfile
FROM node:20.10.0-slim

RUN apt-get -y update && apt-get -y install default-jdk
RUN npm install -g firebase-tools

Goコンテナ用

Goのアプリケーション用のコンテナです。
1行なので、わざわざDockerfileにすることもないですが、開発を進めていくと色んなパッケージをイメージに入れておきたくなるのでDockerfileにしてます。
個人の好みで必要なパッケージをインストールしましょう。

app/Dockerfile
FROM golang:1.21

Firebaseの設定

エミュレータを動かすのに必要なファイルは下記の2つです。

  • .firebaserc
  • firebase.json

まずは.firebasercです。
エミュレータ用なのでプロジェクト名は何でもOKです。

firebase/.firebaserc
{
  "projects": {
    "default": "test-project"
  }
}

次にfirebase.jsonですが、Dockerで使用する場合は"host": "0.0.0.0"を指定しないとdocker-composeでポートフォワードしてもブラウザで確認できないようです。
公式ドキュメントのこの辺の記載が該当しそうです。

デフォルトでは、エミュレータは localhost からのリクエストにのみ応答します。つまり、ホストされているコンテンツには同じパソコンのウェブブラウザからアクセスできますが、ネットワーク上の他のデバイスからはアクセスできません。

firebase/firebase.json
{
  "emulators": {
    "singleProjectMode": false,
    "ui": {
      "host": "0.0.0.0",
      "port": 4000
    },
    "firestore": {
      "host": "0.0.0.0",
      "port": 8080
    }
  }
}

これらのファイルはfirebase loginをしてfirebase initによるプロジェクト初期化設定を進めていくと自動で作成されます。
今回はFirestoreのエミュレータだけの構成なので事前に作ってバインドしますが、別のサービス(Authentication, Cloud Functionsなど)を使ったり複雑な構成にする場合は、事前に作るの大変なので自動作成するのが良いかと思います。

またfirebase initによる初期化時に「Firestoreを使用する」選択をした場合は、下記のファイルも自動で作成されます。

  • firestore.indexes.json
  • firestore.rules

今回はデプロイは特に考えず、開発環境だけ作りたいので firestore.indexes.json, firestore.rulesは不要です。

docker-composeの設定

Firestoreエミュレータに接続するのに、接続する側はFIRESTORE_EMULATOR_HOSTを環境変数に設定しておく必要があるので忘れず設定しておきます(公式ドキュメント)。

docker-compose.yaml
version: '3.9'

services:
  app:
    tty: true
    build:
      context: .
      dockerfile: ./app/Dockerfile
    environment:
      FIRESTORE_EMULATOR_HOST: "firebase:8080"
    volumes:
      - ./:/workspace
    working_dir: /workspace

  firebase:
    build:
      context: .
      dockerfile: ./firebase/Dockerfile
    ports:
      - 4000:4000
    volumes:
      - ./firebase/.firebaserc:/firebase/.firebaserc
      - ./firebase/firebase.json:/firebase/firebase.json
    tty: true
    working_dir: /firebase
    command: firebase emulators:start

Goサンプルコードの作成

Firebase側のドキュメントではFirebaseのクライアントライブラリとしてfirebase.google.com/goを使用しています。

GCP側のドキュメントではFirestoreのクライアントライブラリとしてcloud.google.com/go/firestoreを使用しています。

firebase.google.com/goのドキュメントによると、firebase.google.com/goはFirestoreクライアントインスタンスを作るのにcloud.google.com/go/firestoreを使っているため、Firestoreだけを使うのであれば後者だけインストールしておけばOKです。

Firestore returns a new firestore.Client instance from the https://godoc.org/cloud.google.com/go/firestore package.

main.go
package main

import (
	"context"
	"log"

	"cloud.google.com/go/firestore"
)

func main() {
	ctx := context.Background()
	client := createClient(ctx)
	defer client.Close()
	createSample(ctx, client)
}

func createClient(ctx context.Context) *firestore.Client {
	projectID := "test-project"

	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}
	return client
}

func createSample(ctx context.Context, client *firestore.Client) {
	_, _, err := client.Collection("users").Add(ctx, map[string]interface{}{
		"first": "Ada",
		"last":  "Lovelace",
		"born":  1815,
	})
	if err != nil {
		log.Fatalf("Failed adding alovelace: %v", err)
	}
}

サンプルコードはクイックスタートのものを拝借しました。

確認

dockerを立ち上げてGoのサンプルコードを実行してFirestoreのUI上で、サンプルユーザーが追加されることを確認します。

コマンドライン
# コンテナ起動
docker compose up -d

# ログ確認してエミュレータの起動を確認
docker compose logs

スクリーンショット 2023-12-03 14.59.59.png

上のようなログが出ていれば無事Firebaseのエミュレータが起動できてるので、ブラウザで http://localhost:4000 にアクセスしてエミュレータUIを確認しましょう。
エミュレータの起動には少し時間がかかるのでコンテナが異常終了してなければ少し待ってみるといいです。

続いてGoの初期設定をしてから、サンプルコードを実行してFirestoreエミュレータにデータが登録されることを確認します。

コマンドライン
# モジュール初期化
docker compose exec app go mod init firestore-test

# クライアントライブラリインストール
docker compose exec app go get cloud.google.com/go/firestore

# サンプルコード実行
docker compose exec app go run main.go

http://localhost:4000/firestore にアクセスしてみましょう。
処理が完了すれば以下のようにFirestoreエミュレータにサンプルデータが登録されます。

スクリーンショット 2023-12-03 15.05.29.png

まとめ

複雑なデータ構造になってくると、データを確認したいときにデータ構造を加工して読みやすい形にして出力する必要が出てくると思います。
FirestoreのUI上で構造を確認できた方が直感的に理解できるので効率的に作業を進められるでしょう。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1