Launch Firebase Local Emulator Suite in Docker.

Introduction

Firebase Local Emulator Suite is an environment that allows you to emulate components of your Firebase project such as Firestore and Cloud Functions in your local environment. https://firebase.google.com/docs/emulator-suite?hl=ja

In this article, I would like to build the above environment using Docker and Docker Compose.

Development environment

The code used in this article is here.

I will actually make it.

First, let's create a Firebase project. https://console.firebase.google.com/ It is required to use the Emulator Suite UI (console that can manage the emulator on the GUI) described later. Make a note of the ID of your project in the .env file.

$ mkdir empty_dir && cd empty_dir
$ touch .env

.env


GCP_PROJECT_ID=YOUR_PROJECT_ID

Let's create it from the Dockerfile immediately. Create an image to meet the operating requirements of the emulator. https://firebase.google.com/docs/emulator-suite/install_and_configure?hl=ja

$ mkdir docker
$ touch ./docker/firebase.dockerfile

docker/firebase.dockerfile


FROM ubuntu:20.04

RUN apt-get update -y

RUN apt-get install -y curl openjdk-11-jre-headless

RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - \
    && apt-get install -y nodejs

RUN npm install -g firebase-tools

Next, create a Docker Compose configuration file. Create a directory as appropriate to mount the volume.

$ mkdir firebase
$ touch docker-compose.yaml

docker-compose.yaml


version: "3"

networks:
    backend:
    
services:
    workspace:
        image: golang:1.15
        environment:
            FIRESTORE_EMULATOR_HOST: "firebase:8080"
            GCP_PROJECT_ID: "${GCP_PROJECT_ID}"
        volumes:
            - ./gopath/:/go:cached
            - ./workspace/:/opt/workspace:cached
        ports:
            - 8000:8000
        working_dir: /opt/workspace
        networks:
            - backend
        command: bash
        tty: true
    firebase:
        build:
            context: ./docker
            dockerfile: firebase.dockerfile
        volumes:
            - ./firebase/emulators/:/opt/workspace:cached
            - ./firebase/bin/:/root/.cache:cached
            - ./firebase/config/:/root/.config:cached
        ports:
            - 4000:4000 # Emulator Suite UI
            - 5000:5000 # Firebase Hosting
            - 5001:5001 # Clound Functions
            - 9000:9000 # Realtime Database
            - 8080:8080 # Cloud Firestore
            - 8085:8085 # Cloud Pub/Sub
        working_dir: /opt/workspace
        networks:
            - backend
        command: bash
        tty: true

This time I would like to hit the Firestore API from Go language.

go:./workspace/go.mod


module github.com/kyhei/firebase_emu_sample

go 1.15

require (
	cloud.google.com/go/firestore v1.3.0
	golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect
	golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 // indirect
	golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f // indirect
	golang.org/x/tools v0.0.0-20200904185747-39188db58858 // indirect
	google.golang.org/api v0.31.0 // indirect
	google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d // indirect
)

go:./workspace/main.go


package main

import (
	"context"
	"log"
	"os"

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

func main() {
	ctx := context.Background()
	client, err := firestore.NewClient(ctx, os.Getenv("GCP_PROJECT_ID"))
	defer client.Close()
	if err != nil {
		log.Fatal(err.Error())
	}

	doc, _, err := client.Collection("users").Add(ctx, map[string]interface{}{
		"name": "kyhei",
		"age":  123,
	})
	if err != nil {
		log.Fatal(err.Error())
	}

	log.Println(doc.ID)

	q := client.Collection("users").Select("name", "age")
	docs, err := q.Documents(ctx).GetAll()
	if err != nil {
		log.Fatal(err.Error())
	}

	for _, doc := range docs {
		log.Println(doc.Data())
	}

}

Let's run Docker Compose with the contents so far.

$ docker-compose up -d
$ docker-compose ps

It is OK if two containers are running.

Emulator startup and configuration

Log in to the firebase container and initialize your Firebase project.

$ docker-compose exec firebase bash
root@da35c7925947:/opt/workspace# firebase login --no-localhost
root@da35c7925947:/opt/workspace# firebase init

In firebase init, select an existing project and Select Emulators as the service option. (Anything else is OK.)

Check all emulators in Emulators Setup! After that, you will be asked for the settings for each, but all are okay by default.

After the initialization is complete, edit firebase.json.

json:./firebase/emulators/firebase.json


{
  "emulators": {
    "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": 5000
    },
    "pubsub": {
      "host": "0.0.0.0",
      "port": 8085
    },
    "ui": {
      "enabled": true,
      "host": "0.0.0.0",
      "port": 4000
    }
  }
}

Now let's actually start the emulator with the following command.

root@da35c7925947:/opt/workspace# firebase emulators:start

The first time the executable file is downloaded. When the emulator starts up, it's OK if you can access the console with [http: // localhost: 4000](http: // localhost: 4000)!

スクリーンショット 2020-09-09 16.11.06.png

Checking the Firestore emulator

Let's execute the script created in the previous section and check the connection to Firestore.

$ docker-compose exec workspace bash
root@c64fed9c2890:/opt/workspace# go run main.go
2020/09/09 07:17:08 6WQVScx2NGm4oli8f7iw
2020/09/09 07:17:08 map[age:123 name:kyhei]

If you check the console, you can see that the document has been added successfully.

スクリーンショット 2020-09-09 18.58.37.png

Thank you for your hard work!

In order to start Cloud Functions and Hosting, each initialization is required. Initialization commands etc. are instructed from the log when the emulator starts, so it is OK if you execute them.

Recommended Posts

Launch Firebase Local Emulator Suite in Docker.
I tried Firebase Local Emulator Suite in Flutter
Docker in LXD
Docker × Laravel HTTPS (SSL) communication in local environment
SSL in the local environment of Docker / Rails / puma
How to launch Swagger UI and Swagger Editor in Docker
Launch MariaDB with Docker