M1 macOS x Docker で Firebase Project の開発環境を構築しよう

9 min read

はじめに

2021年4月15日、Apple Silicon に正式対応した Docker for Mac が一般公開されました。

これにより、Apple Silicon な macOS でも Docker による仮想環境の構築や共有をすることが可能になりました。

この記事では Docker for Mac を利用して M1 macOS 上に Docker Container を立て、Firebase Project の開発環境を構築することを目指します。

この記事は、先日作成した こちら のスクラップを記事として清書したものになります。

目次

- Docker for Mac の導入
- 仮想環境(Container)の設定ファイルを作成
- 仮想環境(Container)の生成
- Firebase CLI を利用して Container 内に Firebase Project の設定ファイル群を作成
- 各サービスの開発環境を整える

環境

  • Macbook Air (M1, 2020)
  • macOS: Big Sur (11.3.1)
  • Docker for Mac: 3.3.3
  • Visual Studio Code: 1.56.2
    • Remote - Containers: v0.177.2

Docker for Mac の導入

まず、Docker for Mac を macOS にインストールします。

ここでは、dmg ファイルからインストールする方法と Homebrew-cask を利用してインストールする方法を紹介します。

2021/05/23 現在、Docker for Mac を利用するためには Rosetta2 をインストールする必要があります。
事前に softwareupdate --install-rosetta コマンドを使用し、Rosetta2 を macOS 内にインストールしておいてください。

dmg ファイルからインストールする

  1. こちら から dmg ファイルを直接ダウンロードする
  2. dmg ファイルを開き、ドライバ内の Docker for Mac アプリを /Applications フォルダにコピーする

Homebrew-cask を利用してインストールする

Homebrew-cask を利用してインストールするには、

  1. (Homebrew を導入していない場合) Homebrew を導入
  2. Homebrew-cask プラグインを利用して Docker for Mac をインストール

の手順が必要となります。

Homebrew の導入

こちら を参考に、Homebrew をインストールします。

$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
$ export PATH=/opt/homebrew/bin:$PATH

Docker for Mac のインストール

先程インストールした Homebrew のプラグインである Homebrew-cask を利用して Docker for Mac をインストールします。

$ brew install --cask docker

これで Docker for Mac が /Applications にインストールされます。

仮想環境(Container)の設定ファイルを作成

次に、Container を構築するための環境を設定します。

Dockerfile の作成

まずは、Dockerfile を作成して環境構築の手順を指定します。

.devcontainer/firebase/Dockerfile
# Base image
FROM node:12.22.1-buster-slim

# Maintainer
LABEL maintainer="nagakuta <xxx@example.com>"

# Workdir
WORKDIR /workspace

# Install Firebase CLI
RUN npm config set registry http://registry.npmjs.org && \
    npm install --production -g firebase-tools --verbose

今回のベース環境は node:12.22.1-buster-slim を選択しました。
なぜ軽量 image として有名な Alpine を利用しなかったかというと、開発時のエディタとして利用する VSCode の拡張機能である Remote - Containers が 2021/05/16 時点で Alpine に対応していない(参考)ためです。

docker-compose.yml の作成

次に、docker-compose.yml を作成して Container を build する際に利用するファイルや Volume を指定します。

.devcontainer/docker-compose.yml
version: '3.8'
services:
    build:
      context: .
      dockerfile: firebase/Dockerfile
    volumes:
      # VSCode settings
      - ../.vscode:/workspace/.vscode:cached
    command: /bin/sh -c "while sleep 1000; do :; done"
    env_file:
      - firebase/.firebase.env

今回は

  • docker compse build 時に .devcontainer/firebase/Dockerfile を参照
  • VSCode の Workspace 設定を Container 内で開いた VSCode にも適用するために、.vscode ファイルを /workspace ディレクトリにマウント
  • 秘密鍵等は .devcontainer/firebase/.firebase.env に環境変数として定義、docker compose build 時に Container 側へ展開

とすることにしました。

仮想環境(Container)の生成

先程作成した Dockerfiledocker-compose.yml をもとに Container を生成し、その Container 内へ接続します。

ここでは、docker コマンドを使用する方法と、VSCode の Remote - Containers 拡張を使用する方法を紹介します。

docker コマンドを利用する場合

docker コマンドは Docker for Mac をインストールしただけでは macOS にインストールされていないので、以下のコマンドを使用する前にアプリを起動して docker コマンドをインストールします。

$ docker compose build
$ docker compose up -d
$ docker exec -it <Container ID> /bin/bash

VSCode の Remote - Containers を利用する場合

  1. VSCode にて Remote - Containers をインストールする
  2. Remote - ContainersReopen in Container > From docker-compose.yml をクリック

Firebase CLI を利用して Container 内に Firebase Project の設定ファイル群を作成

Container 内へ接続することができたら、次は Container 内で Firebase CLI を利用して Firebase Project の開発環境を作成します。

まず、以下のコマンドを使用して Firebase にログインします。

$ firebase login:ci

コマンドを使用すると URL を開くよう指示されるので、ブラウザで開いて Google アカウントにてログインします。
ログイン成功時に Firebase を CLI で動かすためのトークンが発行されるので、.env ファイルに環境変数(FIREBASE_TOKEN=xxx)として定義します。
これで、Container をビルドして環境を再構築する際に Firebase へ都度ログインしなくても Project に対して操作できるようになります。

次に、Firebase Project の設定ファイル群を生成します。

この操作を行う前に、Firebase Console で Project を作成しておく必要がありますが、この記事では省略します。

Firebase Console にて Project が作成できたことを確認したら、Container 内で以下のコマンドを使用し、 Project と連携した設定ファイル群を生成します。

$ firebase init

コマンドを使用すると、

  • どのプロジェクトと連携させるか
  • どの Firebase のサービスを利用するか(後に設定可)
  • 指定したサービスのエミュレータ(Firebase Local Emulator Suite)を利用するか(後に設定可)

を指定することができます。

これにて、Firebase の開発環境を Container 内に作成することができました。

各サービスの開発環境を整える

以下は、特定のサービスを利用することを選択した際に追加で必要となる設定項目となります。

Firebase Local Emulator Suite にて Firestore を動かすための設定

firebase init にて、「Firestore を利用する」かつ「Firestore のエミュレータを利用する」ことを選択した場合、現在の開発環境ではエミュレータを立ち上げることができません。
なぜなら、Firestore のエミュレータは Java を使用しますが、Container 内に Java がインストールされていないためです。

なので、Firestore のエミュレータを動かすために Container 作成時に Java をインストールするようにします。

.devcontainer/firebase/Dockerfile
# Base image
FROM node:12.22.1-buster-slim

# Maintainer
LABEL maintainer="nagakuta <xxx@example.com>"

# Workdir
WORKDIR /workspace

+# Install Java JRE
+RUN mkdir -p /usr/share/man/man1 && \
+    apt-get update && \
+    apt-get install -y default-jre --no-install-recommends && \
+    apt-get clean -y && \
+    apt-get autoremove -y && \
+    rm -rf /var/lib/apt/lists/*

# Install Firebase CLI
RUN npm config set registry http://registry.npmjs.org && \
    npm install --production -g firebase-tools --verbose

これにより、Container を build した際に Java JRE が Container 内にインストールされ、

$ firebase emulators:start --only firestore

のコマンドで Firestore のエミュレータを動作させることができます。

Cloud Functions for Firebase のコーディング環境を整える

firebase init にて Cloud Functions for Firebase の利用を選択した際に、「JavaScript と TypeScript のどちらで開発するか」、「コードの静的解析を利用するか」を指定することができます。

ここでは、「TypeScript で開発」かつ「静的解析を利用する」を選択した際に、

  • TypeScript の設定
  • ESLint の設定
  • Prettier の導入

を行う場合の設定例を紹介します。

TypeScript の設定

ここでは、TypeScript に関する設定を行います。
こちらは firebase init 時に自動生成された tsconfig.json を一部修正しました。

functions/tsconfig.json
{
  "compilerOptions": {
    "module": "commonjs",
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "outDir": "lib",
    "sourceMap": true,
    "strict": true,
    "target": "es2017",
+   "esModuleInterop": true,
  },
  "compileOnSave": true,
- "include": ["src"]
+ "include": ["src", "__tests__"]
}

今回新たに追加したのは、Jest によるテストを実行する際に必要な設定です。

ESLint の設定

ここでは、ESLint に関する設定を行います。
こちらは、自動生成された .eslintrc.js を JSON に書き換えたのみです。

functions/.eslintrc.json
{
  "env": {
    "es6": true,
    "node": true,
    "jest/globals": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:import/errors",
    "plugin:import/warnings",
    "plugin:import/typescript",
    "google"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "project": ["tsconfig.json", "tsconfig.dev.json"],
    "sourceType": "module"
  },
  "ignorePatterns": [
    "/lib/**/*" // Ignore built files.
  ],
  "plugins": ["@typescript-eslint", "import", "jest"],
  "rules": {
    "import/no-unresolved": "off"
  }
}

Prettier の導入

ここでは、TypeScript をサポートしている Formatter である Prettier を導入します。

まず、Container 内に接続して functions ディレクトリ直下に移動し、以下のコマンドを使用します。

$ npm install --save-dev prettier eslint-config-prettier

次に、ESLint の設定ファイルに Prettier を利用するための設定を追記します。

functions/.eslintrc.json
{
  ...
  "extends": [
    "eslint:recommended",
    "plugin:import/errors",
    "plugin:import/warnings",
    "plugin:import/typescript",
    "google",
+   "prettier",
+   "prettier/@typescript-eslint"
  ],
  ...
}

(Optional) VSCode で Prettier を使用する

VSCode にて Prettier を使用する場合、VSCode に Prettier - Code formatter 拡張をインストールし、VSCode の設定に Prettier を利用するための設定を追記します。

.vscode/settings.json
{
  ...
+ "editor.codeActionsOnSave": {
+   "source.fixAll.eslint": true
+ },
+ "javascript.format.enable": false,
+ "typescript.format.enable": false,
+ "json.format.enable": false,
+ "eslint.alwaysShowStatus": true,
+ "eslint.format.enable": true,
+ "eslint.debug": true,
+ "prettier.prettierPath": "/workspace/functions/node_modules/prettier",
+ "[typescript]": {
+   "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[json]": {
+   "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[jsonc]": {
+   "editor.defaultFormatter": "esbenp.prettier-vscode"
+ }
  ...
}

これで、VSCode にて Prettier によるコード整形が利用可能になります。

まとめ

この記事では、Apple Silicon な macOS 上に Docker Container を立て、Firebase Project の開発環境を構築する方法を紹介しました。

みなさんも、Docker Container による開発環境の構築や共有を行い、再利用性の高い開発環境を作りましょう!