I tried to build a Firebase application development environment with Docker in 2020

This article is the 15th day article of "[Meister Guild] Genuine Advent Calendar 2020".


Not long ago, Windows System for Linux2 (WSL2) was released. You can now run Linux on Windows. Also, by using WSL2, you can use Docker Desktop for Windows even on home Windows. Unexpectedly, some people may not know this. Home I used to use Docker ToolBox, but it wasn't a very good experience and I didn't have much motivation for Docker. However, when I used Docker Desktop for Windows, it was very easy to use, so I tried to build an environment to develop a TS application with Firebase Cloud Functions as the back end with Docker. I will try Vue.js for the front. This is an article summarizing the results.

↓ is a directory structure diagram of files related to environment construction explained in this article. Of course, there are other source files and application configuration files as well.

Directory configuration diagram


.
├──app
│  ├──functions
│  │  ├──lib
│  │  ├──node_modules
│  │  ├──.dockerignore
│  │  ├──copy-node_modules.sh
│  │  ├──Dockerfile
│  │  └──package.json
│  │     
│  ├──vuejs
│  │  ├──dist
│  │  ├──node_modules
│  │  ├──.dockerignore
│  │  ├──copy-node_module.sh
│  │  ├──Dockerfile
│  │  └──vue.vonfig.js
│  │
│  └──firebase.json
│
├──swagger
│  └──index.yml
│
└──docker-compose.yml

The Docker container group looks like ↓. image.png

By the way, this time I happened to develop an application that does not use DB. If you use DB, you probably keep this configuration if you use Firebase's Cloud Firestore, but if you need something like MySQL, you'll probably want to add a db container.

This was the first time for me to develop a TS app, but when I built a development environment with Docker, I encountered the following problems.

--Hot reload does not work when sharing TS build destination with Windows --Building is very slow when sharing node_modules with Windows -If * .d.ts is not on the editor side, you will not receive the benefits of the type during development.

The next Firebase spec also bothered me.

--When you launch the emulator, the API will be prefixed with project name/region name /

Let's take a look at each container.

firebase container

package.json


"scripts": {
  ...
  "emulators": "tsc-watch --onFirstSuccess \"firebase emulators:start --token ${FIREBASE_TOKEN}\""
  ...
},
...
"dependencies": {
  ...
  "firebase-admin": "^9.2.0",
  "firebase-functions": "^3.6.1",
  ...
}
...
"devDependencies": {
  ...
  "tsc-watch": "^4.2.9"
  ...
}

Use the Firebase CLI Cloud Functions Emulators (https://firebase.google.com/docs/functions/local-emulator). Introduce tsc-watch to enable hot reload development.

$ npm run emulators

Launches an emulator that allows you to develop while hot reloading.

firebase.json


...
  "hosting": {
    "public": "vuejs/dist",
    ...
    "rewrites": [
      {
        "source": "/get-users",
        "function": "get-users"
      }
    ]
  },
  "emulators": {
    "functions": {
      "host": "0.0.0.0",
      "port": 5001
    },
    "hosting": {
      "host": "0.0.0.0",
      "port": 5000
    },
    "ui": {
      "enabled": true,
      "host": "0.0.0.0",
      "port": 4000
    }
  }
...

Firebase settings. hosting first specifies the public directory as the default build destination for Vue.js (public). In rewrites, each function of Cloud Functions can be called by accessing/~ . This is because the API endpoint provided by Cloud Functions Emulators has the project name and region name in the prefix, but I want to ignore this prefix part when hitting the API from Swagger (project in Swagger's yml file). I don't want to write the name and region name). If the API increases, it will be necessary to add it here. In emulators, host is specified so that it can be accessed from outside Docker, and the UI screen of Cloud Functions Emulators is enabled so that the smallest port number is assigned. You may not use it often, but this will open the dashboard-like screen of the emulator with "OPEN IN BROWSER" of Docker Desktop for Windows.

docker-compose.yml


volumes:
  firebase-node_modules:
  firebase-lib:

services:
  firebase:
    build: ./app/functions
    image: firebase
    container_name: firebase
    ports:
      - 4000:4000
      - 5000:5000
      - 5001:5001
    volumes:
      - ./app:/app
      - firebase-lib:/app/functions/lib
      - firebase-node_modules:/app/functions/node_modules
    environment:
      - FIREBASE_PROJECT
      - FIREBASE_TOKEN

I don't want to share node_modules with the host, so I create separate volumes and store them there. If the code after transpiling the TS is also shared with the host side, it will prevent hot reloading, so we do the same. FIREBASE_TOKEN is for hitting the Firebase CLI without logging in. You can get it at https://firebase.google.com/docs/cli?hl=ja#cli-ci-systems.

Dockerfile


FROM node:10

RUN apt-get update && \
  npm install -g firebase-tools

WORKDIR /app/functions

COPY package*.json ./

CMD npm install \
  && firebase use ${FIREBASE_PROJECT} --token ${FIREBASE_TOKEN} \
  && npm run emulators

EXPOSE 4000 5000 5001
  1. Install firebase-tools
  2. Install the npm package
  3. Firebase project settings
  4. Start the emulator (with hot reload)

I am doing. I'm copying package * .json here because the volume mount I wrote in docker-compose.yml isn't in Docker yet because it's after processing the contents of the Dockerfile.

.dockerignore


node_modules

The host node_modules are not needed, so write them in .dockerignore.

copy-node_modules.sh


#! /bin/bash

SCRIPT_DIR=$(cd $(dirname $0); pwd)

docker cp -a -L firebase:/app/functions/node_modules $SCRIPT_DIR

It is a script that copies the .d.ts file installed in the Docker container to the host side for development with VS Code on the host. It would be nice to be able to specify the extension with the docker cp command, but I can't, so I bring node_modules entirely. It takes time. Furthermore, I think that it is related to symbolic links, but it is necessary to execute it with administrator privileges.

Actually, I want to develop by connecting to the Docker container with VS Code's Remote WSL plug-in, but the operation is still unstable in the Preview version, or it freezes frequently in my environment ... I would like to try again when it becomes the official version. If you can use this well, you don't need this script.

After launching the firebase container, you can access the emulator UI from OPEN IN BROWSER. image.png

swagger container

docker-compose.yml


services:
  #Other settings...
  swagger:
    image: swaggerapi/swagger-ui
    container_name: swagger
    ports:
      - 8000:8080
    volumes:
      - ./swagger:/var/www
    environment:
      SWAGGER_JSON: /var/www/index.yml

Make the ./swagger/index.yml file visible on port 8000 on the host side.

After launching the swagger container, you can access the Swagger UI from OPEN IN BROWSER. image.png This container is simple because it simply publishes index.yml.

vuejs container

docker-compose.yml


volumes:
  #Other settings...
  vuejs-node_modules:

services:
  #Other settings...
  vuejs:
    build: ./app/vuejs
    image: vuejs
    container_name: vuejs
    ports:
      - 3000:3000
      - 3001:3001
    volumes:
      - ./app:/app
      - vuejs-node_modules:/app/vuejs/node_modules
    environment:
      - CHOKIDAR_USEPOLLING=true

Make port 3000 for Vue CLI UI and port 3001 for serve. Again, I don't want to share node_modules with the host, so I'll avoid it with another volume. The environment variable CHOKIDAR_USEPOLLING seems to be what you need for a hot reload on serve.

Dofkerfile


FROM node:10

RUN apt-get update && \
    npm install -g @vue/cli

WORKDIR /app/vuejs

COPY package*.json ./

CMD npm install \
    && vue ui --host 0.0.0.0 --port 3000

EXPOSE 3000 3001

I have installed the Vue CLI and specified the following in the options of the vue ui command

---- host 0.0.0.0 Allow access to the WebUI from outside the Docker container ---- port 3000 Launch WebUI on port 3000

.dockerignore


node_modules

Again, the host node_modules is not needed, so write it in .dockerignore.

vue.config.js


module.exports = {
    devServer: {
        port: 3001,
        host: '0.0.0.0'
    }
}

Specify the options of the server to be launched by serve in the same way as vue ui.

copy-node_modules.sh


#! /bin/bash

SCRIPT_DIR=$(cd $(dirname $0); pwd)

docker cp -a -L vuejs:/app/vuejs/node_modules $SCRIPT_DIR

It is a script that copies the .d.ts file installed in the Docker container to the host side in order to develop with VS Code on the host like the firebase container. It takes time. Execution with administrator privileges is required.

After launching the vuejs container, you can access the Vue CLI UI from OPEN IN BROWSER. image.png

That's all for building a development environment for Firebase + Vue.js + TS apps using Docker. It seems that the contents here will change depending on the version upgrade of each tool in the future, but as of 2020/12, it was an article that it became like this. Docker is convenient.

Recommended Posts

I tried to build a Firebase application development environment with Docker in 2020
I tried to create a padrino development environment with Docker
I tried to create a java8 development environment with Chocolatey
Build a Wordpress development environment with Docker
I tried to build the environment of PlantUML Server with Docker
I tried to build an http2 development environment with Eclipse + Tomcat
I tried to build a laravel operating environment while remembering Docker
Build a WordPress development environment quickly with Docker
How to build a Ruby on Rails development environment with Docker (Rails 6.x)
How to build a Ruby on Rails development environment with Docker (Rails 5.x)
[Note] Build a Python3 environment with Docker in EC2
Try to build a Java development environment using Docker
I tried to build an environment using Docker (beginner)
I tried to make a machine learning application with Dash (+ Docker) part3 ~ Practice ~
Build a development environment to create Ruby on Jets + React apps with Docker
Build a Node.js environment with Docker
I tried to make a machine learning application with Dash (+ Docker) part1 ~ Environment construction and operation check ~
I made a development environment with rails6 + docker + postgreSQL + Materialize.
I tried to modernize a Java EE application with OpenShift.
I tried to build the environment little by little using docker
How to build Rails, Postgres, ElasticSearch development environment with Docker
Build a Node-RED environment with Docker to move and understand
I tried to build the environment of WSL2 + Docker + VSCode
I tried to implement a buggy web application in Kotlin
[Rails] [Docker] Copy and paste is OK! How to build a Rails development environment with Docker
How to quit Docker for Mac and build a Docker development environment with Ubuntu + Vagrant
How to build Rails 6 environment with Docker
Build a simple Docker + Django development environment
Procedure for building a Rails application development environment with Docker [Rails, MySQL, Docker]
I tried to create a Spring MVC development environment on Mac
Build a browser test environment using Capybara in the Docker development environment
I tried to build a simple application using Dockder + Rails Scaffold
Build a development environment for Django + MySQL + nginx with Docker Compose
Steps to build a Ruby on Rails development environment with Vagrant
I was addicted to WSl when trying to build an android application development environment with Vue.js
Build a development environment for Docker + Rails6 + Postgresql
I tried to verify AdoptOpenJDK 11 (11.0.2) with Docker image
How to execute with commands of normal development language in Docker development environment
Creating a java web application development environment with docker for mac part1
How to build an environment with Docker, which is the minimum required to start a Rails application
01. I tried to build an environment with SpringBoot + IntelliJ + MySQL (MyBatis) (Windows10)
[Copy and paste] Build a Laravel development environment with Docker Compose Part 2
I tried to make a machine learning application with Dash (+ Docker) part2 ~ Basic way of writing Dash ~
Build a simple Docker Compose + Django development environment
Build a local development environment for Rails tutorials with Docker (Rails 6 + PostgreSQL + Webpack)
[Copy and paste] Build a Laravel development environment with Docker Compose Participation
[Win10] Build a JSF development environment with NetBeans
I tried to take a look at the flow of Android development environment construction with Android Studio
I tried to build Micra mackerel in 1 hour!
I tried to make a talk application in Java using AI "A3RT"
I tried to develop an application in 2 languages
How to migrate a web application created in a local docker environment to AWS
Build a development environment for Docker, java, vscode
[Rails] How to build an environment with Docker
Template: Build a Ruby / Rails development environment with a Docker container (Ubuntu version)
[First team development ②] Build an environment with Docker
Create a java web application development environment with docker for mac part2
I tried to break a block with java (1)
I tried migrating the portfolio created on Vagrant to the Docker development environment
Template: Build a Ruby / Rails development environment with a Docker container (Mac version)
Create a Spring Boot development environment with docker