Blitz.js + Postgres を docker-compose で動かす


postgres への切り替え prisma に伝える

  • まずは Blitz.js が DB を読み込むために使用している prisma に
  • DB の sqlite から postgres の変更を伝える必要がある

  • ここをみると最初に

Open db/schema.prisma and
change the db provider value from
"sqlite" to "postgres" as follows:

  • かえろって書いてあった
  • db/schema.prisma を開く
db/schema.prisma
datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}
  • デフォルトだとこうなっている。これの sqlite を postgres に変更
db/schema.prisma
datasource db {
  provider = "postgres"
  url      = env("DATABASE_URL")
}

また

In .env.local, change DATABASE_URL.
For convenience, there is a commented-out PostgreSQL DATABASE_URL there already.
Depending on your setup, you may need to modify the URL.

  • DATABASE_URL は.env.local から migrate で反映されると書いてあった
  • なので
  url      = env("DATABASE_URL")
  • このまま migrate すればOK

db/schema.prisma を migrate で反映させる

  • blitz migrate をする
Error: P1001: Can't reach database server at `localhost`:`5432`

Please make sure your database server is running at `localhost`:`5432`.
  • 今度は DB サーバーが 5432 で動いてないと言われる
  • DB サーバーが動いていないと DB にアクセスする migrate 処理ができないのは当たり前
  • npm start で docker-compose up してないとダメだった(後述の compose ファイルを書く)
  • npm start した状態で migrate する
Prisma Schema loaded from db/schema.prisma
 Name of migration  sqlite to postgres
📼  migrate save --name sqlite to postgres

Prisma Migrate just created your migration 20201022102534-sqlite-to-postgres in

migrations/
  └─ 20201022102534-sqlite-to-postgres/
    └─ steps.json
    └─ schema.prisma
    └─ README.md

Datamodel that will initialize the db:

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

datasource db {
  provider = "postgres"
  url = "******"
}
  • localhost 3000 にアクセスすると sqlite で作ったデータではなく、
  • まっさらな postgres のデータが入っていて書き込めた。

docker-compose.yml の作成

  • デフォルトでは sqlite だが、docker-compose で動かすためには postgres に変える必要がある

One way to get a PostgreSQL database on your machine
is to run PostgreSQL inside a docker container.

  • PostgreSQL をマシンに入れるには Docker コンテナを使う方法がある
  • Docker を使用する

Create a docker-compose.yml file inside the root of your project with the following content

  • ルートに compose ファイルを作る
docker-compose.yml
version: "3.7"
services:
  db:
    image: postgres:latest
    volumes:
      - data:/var/lib/postgresql/data
    env_file: ./.env.local #Here we are using the already existing .env.local file
    ports:
      - "5432:5432"
volumes:
  data:
  • コピペで作成
    • 最新の postgres を取ってきて
    • var/lib/postgres/data に data を入れて
    • .env.local を 環境ファイルとして読み込んで
    • ホストの port 5432 とコンテナの port 5432 を繋ぐ
  • README と同じ階層に作る

.env.local の更新

Here we are using the already existing .env.local file

  • とあるように、.env.local というファイルがある、これを更新する
.env.local
# This env file should NOT be checked into source control
# This is the place for values that changed for every developer

# SQLite is ready to go out of the box, but you can switch to Postgres
# by first changing the provider from "sqlite" to "postgres" in the Prisma
# schema file and by second swapping the DATABASE_URL below.
DATABASE_URL="file:./db.sqlite"
# DATABASE_URL=postgresql://kaede@localhost:5432/blitz-crud
  • 最初はこうなっている
  • ここに user, db, が書いてあるからこれを使う
  • DB URL は残しておく
POSTGRES_USER=kaede
POSTGRES_PASSWORD=password
POSTGRES_DB=blitz-crud
  • docker-compose run で MySQL 動かした時の環境引数だ!
  • これを既に作成されているの .env.localに追加する
  • するとこうなる
  • 一番上の行が最初からあるコードだ。
DATABASE_URL=postgresql://kaede@localhost:5432/blitz-crud_test

POSTGRES_USER=kaede
POSTGRES_PASSWORD=****
POSTGRES_DB=blitz-crud
  • これでは URL に PASSWORD が入っていないので使えない

Given these values your DATABASE_URL
should look like this
postgresql://your_user:your_password@localhost:5432/your_database_name

  • //YOUR_USER:YOUR_PASSWORD@localhost.... という風にする
DATABASE_URL=postgresql://kaede:****@localhost:5432/blitz-crud_test

package.json の start に blitz start と docker-compose up -d を仕込む

Modify your package.json to run the database before the start of Blitz

package.json
"scripts": {
    "start": "docker-compose up -d && blitz start",
}
  • 適用した
  • 動かしてみる
  • npm startblitz start の他に docker-compose up が裏で走るようになった
npm start

> [email protected] start /Users/kaede/code/blitz-crud
> docker-compose up -d && blitz start

Creating network "blitz-crud_default" with the default driver
Creating volume "blitz-crud_data" with default driver
Creating blitz-crud_db_1 ... done
  • DB 読み込んだっぽい
ready - started server on http://localhost:3000
info  - Using external babel configuration from /Users/kaede/code/blitz-crud/.blitz/caches/dev/babel.config.js
event - compiled successfully
event - build page: /404
wait  - compiling...
  • docker 使う前のように localhost 3000 で動いてしまって、 docker compose で定義した 5432:5432 の localhost 5432 に アクセスしても見れない...

なるほど、わかりました。
* 何が 3000 ポートで動くのか
* 何が 5432 ポートで動くのか
* BlitzはどのようにしてDBを利用するのか
この辺を一度整理して考えてみましょうか。

  • まとめた。

localhost 5432 と 3000 と Blitz と postgres と

host localhost 3000 で動くもの

  • blitz 本体の動作

host (の中で動く docker の 5432 とつながっている) localhost 5432 で動くもの

  • postgres のデータベースサーバー

Blitz はどうやって DB を利用するか

  1. .env.local に DB URL (など) が記入され(てい)る
  2. docker-compose.yml.env.local から env を読み取って docker を使用して localhost 5432 (仮) に DB サーバーを立てる
  3. db/prisma.env.local から DB サーバーの URL を読み取り DB を使用する。

その通りです、あってます!
それがわかると、5432に (ブラウザとかで) アクセスしても意味がないことがわかることでしょう

  • 5432 は DB サーバーだから、アプリケーションサーバーから使うもので、ユーザーが直接アクセスするものではなかった!

What happens next

  • 現状、blitz start で host で動かした Blitz App サーバーで docker-compose up で Docker で動かした コンテナにつながっている ホストの5432 の DB サーバーを動かすの npm start に当てているが、これは両方とも docker-compose up で動くべきものですよね? docker-compose.yml を書き足して