Node16 + Cloud Functions をDocker環境に構築

# はじめに
Cloud Functionsをデプロイするまでの環境をDockerで構築する。今回は環境構築が簡単に済む Node.js を選択した。
公式より Node.js 16（推奨）とあるので（2022/05/01）バージョンは Node.js 16 選択した。


https://cloud.google.com/functions/docs/concepts/nodejs-runtime?hl=ja
# 概要
### 前提条件
* GCPにプロジェクトが存在し、Cloud Functions使用できる状態になっている
* Docker Desktopを使用

### 手順
1. docker-composeを使用してコンテナを作成する
2. firebase-toolsを使用して初期設定
3. Cloud Functionsにデプロイする

# Docker環境構築
imageは node:16-alpine を使用し、firebase-toolsをインストールする。
```:Dockerfile
FROM node:16-alpine

ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./

RUN npm install -g firebase-tools
```
```:docker-compose.yml
version: '3'
services:
  node:
    build: .
    working_dir: "/app"
    volumes:
      - .:/app
    tty: true
```
```
# コンテナ作成
docker-compose build
docker-compose up -d
```

# 初期設定
firebase-tools を使用して、firebaseの初期化を行う。
Dockerfile がある階層で次のコマンドを実行する。

```
# ログイン
firebase login --no-localhost
省略

# 初期化
firebase init

# セットアップする機能を聞かれるのでFunctionsを選択して「Enter」
Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confir
m your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
◉ Functions: Configure a Cloud Functions directory and its files

# デプロイ先のプロジェクトの選択する
省略

# JavaScript か TypeScript どちらを使うか選択する（今回はTypeScriptを選択した）
What language would you like to use to write Cloud Functions? (Use arrow keys) 

# ESLintを使用するか選択する（お好みで）
Do you want to use ESLint to catch probable bugs and enforce style?

# dependencies をインストールするか選択する
Do you want to install dependencies with npm now? (Y/n)
```

完了するとファイルが作成されて、フォルダー構成はこのようになる。
>app/
>&ensp;├ functions/
>&ensp;&ensp;&ensp;&ensp;├ ...
>&ensp;&ensp;&ensp;&ensp;├ src/
>&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;├ index.ts
>&ensp;├ Dockerfile   
>&ensp;├ docker-compose.yml
>&ensp;├ firebase.json
>&ensp;├ ...

自動で作成された /app/functions/src/index.ts を編集する。
HTTPトリガーの関数がコメントアウトされているのでこのコメントアウトを解除するだけでテストできる。
```:index.ts
import * as functions from "firebase-functions";

// Start writing Firebase Functions
// https://firebase.google.com/docs/functions/typescript

export const helloWorld = functions.https.onRequest((request, response) => {
  functions.logger.info("Hello logs!", {structuredData: true});
  response.send("Hello from Firebase!");
});
```

# Cloud Functionsにデプロイ
functionsフォルダーに移動してデプロイする。
```
cd functions/
npm run deploy

Function URL (helloWorld(us-central1)): アクセスURL
```
完了するとURLが表示されるので、アクセスすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2639110/94c3fb28-f879-61e6-23dc-f88f858577e4.png)
Hello from Firebase! が確認できた。

# 補足
デフォルトだとregionがus-central1となる。
変更するにはfunctionsにregion設定を追加する。
```:index.ts
import * as functions from "firebase-functions";

// Start writing Firebase Functions
// https://firebase.google.com/docs/functions/typescript

export const helloWorld = functions.region('asia-northeast1').https.onRequest((request, response) => {
  functions.logger.info("Hello logs!", {structuredData: true});
  response.send("Hello from Firebase!");
});
```

# 参考
https://cloud.google.com/functions/docs/concepts/nodejs-runtime?hl=ja
https://firebase.google.com/docs/functions/locations?hl=ja