車輪の二度漬け

railsを触っていましたが、最近はreactに興味あります。

Next.js + Vercel + TypeScript + Firebaseでアプリを作る。環境構築編

Next.jsの勉強をしようと思い、せっかくなので自分の知らないところややったことないことのキャッチアップをしつつプリを作ってみることにした。
構成としては、VercelとFirebaseあたりを使う想定。
今回は環境構築だが、フロントとバックの疎通などはまだ未確認なのであしからず。
今回の環境構築はとりあえずDockerに載せて動かすというところがゴールなので、このままだと疎通できないかも。
必要に応じて後で修正する予定。

0. 前提:firebaseにプロジェクトを作成しておく

Firebaseに飛んでプロジェクトを作成後、Firestoreなどの使いたいサービスについても作成しておく。
ここで各サービスを作成しておかないと、あとでfirebase initをしてFirebaseの初期設定をする時に「そんなサービスないよ!」と怒られる。

1. Dockerの設定

今回のディレクトリ構成は

.
├── web/
│   ├── docker-compose.yml
│   ├── Dockerfile
│   └── Next.jsのコード諸々
└── app/
    ├── Dockerfile
    └── Firebaseのコード諸々

という感じにしようと思っている。
webにはNext.jsのコードを入れて、appにはFirebase関連のコードを入れて、webappはそれぞれ別のリポジトリで管理する想定。
docker-compose.ymlは以下:

version: '3.8'

services:
  web:
    container_name: xxxx
    build:
      context: ./
    volumes:
      - ./:/usr/src
    working_dir: /usr/src
    ports:
      - '3000:3000'
    depends_on:
      - app
    tty: true
  app:
    container_name: xxxx
    build:
      context: ../app
    volumes:
      - ../app:/usr/src
    ports:
      - '9005:9005' # firebase loginのために必要
      - '4000:4000' # firebase ui これはこっちで割り当てた(公式のデフォルトポート設定では4000だったが、ウィザードには出てこなかった)
      - '5001:5001' # Cloud Functions
      - '8080:8080' # Cloud Firestore
      - '9099:9099' # Firebase Auth
    working_dir: /usr/src
    tty: true

また、Firebaseをローカルで使うためにはfirebase-toolsJavaを入れておく必要があるので、appDockerfileにそれも記述しておく。

FROM node:14.15.0-alpine3.12

RUN apk update && \
    apk upgrade

RUN apk add openjdk8

RUN npm install -g firebase-tools

webについては今のところ特筆することはないが、webDockerfileは一応こんな感じ:

FROM node:14.15.0-alpine3.12

WORKDIR /usr/src

RUN apk update && \
    apk upgrade

あとで追加するかも。

ここまでしたら

$ docker-compose build
$docker-compose up -d

2. Next.jsの設定

まずはNext.jsの設定をしていく。

$ docker exec -it <webのコンテナ名> sh

webコンテナに入った後、

# npx create-next-app --example with-typescript-eslint-jest

として、Next.jsの初期設定を行う。
なお、今回はTypeScriptとeslint、Jestがセットになった初期設定を行っている。
Blog - Introducing Create Next App | Next.js←ここを見ると、初期設定には他にも色々と用意されているので、必要であれば見てみるといいかも。

ここまできたら

# yarn dev

http://localhost:3000にアクセスして、画面が表示されたらOK。
ちなみに、webで使っているnodeイメージには初めからyarnが入ってる様子。
yarnで立ち上げたのは、Next.jsの初期設定を行った後にコンソールに「yarn devで立ち上げて」というメッセージが表示されたからだが、npm run devでも立ち上がる。
npmに揃えた方がいいかもという気がしないでもない。

3. Firebase側の環境構築

$ docker exec -it <appのコンテナ名> sh

appのコンテナに入った後、

# firebase login

で、あらかじめ作っておいたfirebaseプロジェクトのGoogleアカウントでログイン。
ログインできたら、その後、

# firebase init

で、Firebase向けの設定を行う。
今回使うものは - Cloud Firestore - Storage - Firebase Auth - Emulator - Firebase UI(ローカル用のFirebaseコンソール) いくつか質問があるが、基本的にはyesだったりデフォルトで設定されている項目で大丈夫なはず。
ただ、Firebase UIはデフォルトのポート設定がなかったので4000を入力。
ちなみに、ここに各サービスのデフォルトポートがまとまっている。

ここまできたら、次はfirebase.jsonの編集。
firebase initの後にappディレクトリ直下にfirebase.jsonが以下のような中身であるはず:

{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "functions": {
    "predeploy": [
      "npm --prefix \"$RESOURCE_DIR\" run lint",
      "npm --prefix \"$RESOURCE_DIR\" run build"
    ]
  },
  "storage": {
    "rules": "storage.rules"
  },
  "emulators": {
    "auth": {
      "port": 9099
    },
    "functions": {
      "port": 5001
    },
    "firestore": {
      "port": 8080
    },
    "ui": {
      "enabled": true,
      "port": 4000
    }
  }
}

このままだと、localhostではアクセスできないのでemulators:配下の各項目に

    "auth": {
      "host": "0.0.0.0",
      "port": 9099
    },

と言うような感じで"host": "0.0.0.0",を追加。
これでlocalhostからアクセスできる。
最後に、

# firebase emulators:start

した後、http://localhost:4000でFirebaseのコンソールにアクセスできればOK。

最後に

Docker使った環境構築ってこういうかんじでいいのかよくわからないなあ。
あと、今回Firebaseを使うのは初めてなので、Firebaseを使う環境構築ってのもこれでいいのかわからない。
ちなみに、ざっと調べた限り、Firestore Local Emulator のデータを擬似的に永続化する←こういうのもあるみたいで、必要そうなら後でやろう。

何かあれば教えて下さい。

参考

https://firebase.google.com/docs/emulator-suite/install_and_configure
https://docs.docker.com/compose/compose-file/
https://qiita.com/kyhei_0727/items/343602fa184c84d593c4
https://a2c.tech/2020/08/nextjs-container/