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


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

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

https://blitzjs.com/docs/database-overview#switch-to-postgresql

* ここをみると最初に

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

* かえろって書いてあった
* db/schema.prisma を開く

```php:db/schema.prisma
datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}
```

* デフォルトだとこうなっている。これの sqlite を postgres に変更

```php: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 で反映されると書いてあった
* なので 

```php:
  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 する

```php:
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 の作成

https://blitzjs.com/docs/database-overview#switch-to-postgresql

* デフォルトでは 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 ファイルを作る

```yml: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 というファイルがある、これを更新する

```php:.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 は残しておく

```php
POSTGRES_USER=kaede
POSTGRES_PASSWORD=password
POSTGRES_DB=blitz-crud
```

* docker-compose run  で MySQL 動かした時の環境引数だ！
* これを既に作成されているの `.env.local`に追加する
* するとこうなる
* 一番上の行が最初からあるコードだ。

```php:
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....` という風にする

```php:
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

```json:package.json
"scripts": {
    "start": "docker-compose up -d && blitz start",
}
```

* 適用した
* 動かしてみる
* `npm start` で `blitz start` の他に `docker-compose up` が裏で走るようになった


```
npm start

> blitz-crud@1.0.0 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` を書き足して