Prisma cloud & Nodejs deploy

自分用メモ
![イラスト.jpg](https://qiita-image-store.s3.amazonaws.com/0/385539/3b5d7b0c-aff0-592e-d242-c24eb8763025.jpeg)


### Prisma Cloud (free)
1. https://www.prisma.io/cloud アクセス
2. Pricing free でアカウント作成 ⇒ ログイン　⇒　ダッシュボードへ
3. 流れ：ServerページでPrisma Instanceを作成してHerokuにDeployする（localhost4466のやつと同じ）
4. ServerページでADD SERVERをクリック
5. 表示されるウィザードで Sever name を入力(グローバルに参照されるのでジェネリックな名前は避けよう)してCREATE A SERVERをクリック
6. Create a new database をクリック ⇒ Herokuを選択　⇒ Herokuアカウントと接続
7. CREATE DATABASEをクリック

![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/385539/98e00293-9986-0c84-fb69-f4d8ac1ac360.jpeg)
8. SET UP A SERVER をクリック

![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/385539/bb760a66-3921-b600-cffd-50c7de660fa6.jpeg)
9. Choose a server provider でHerokuを選択
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/385539/c9761663-2b89-1dc2-50be-7c5d91caf404.jpeg)
10. Planを選択して　CREATE SERVER をクリック
11. 終了したらServersページに行くと、作成されたServerを確認できる
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/385539/d48db507-5602-7d74-fc39-79d3e6ae9dcf.jpeg)
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/385539/513b3b3c-9799-6c30-f3c4-de2124c284d0.jpeg)
Server⇒Prisma docker container の Host
Database⇒Production database

### PrismaAPIのDeploy
1. prisma.ymlを変更

```yml:prisma.yml
endpoint: ${env:PRISMA_ENDPOINT}   ( 元々はhttp://192.168.99.100:4466 )
datamodel: datamodel.graphql
secret: xxx
```
⇒ datamodelを指定のendopointに送信する

2.dev.env / prod.envを作成（この時点でprod.envは空でよい）
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/385539/23e8acd2-3de0-4c77-5938-224dda50c712.jpeg)

```:dev.env
PRISMA_ENDPOINT=http://192.168.99.100:4466
```
この状態で「prisma deploy -e ../config/dev.env」を実行するとこれまでと同様にローカルDeployが行える。

3.Production deploy
①「prisma login」
②「prisma deploy -e ../config/prod.env」

```
 !    [WARNING] in C:\Users\xxx\Downloads\g-06-09-secrets\g-06-09-secrets\graphql-prisma\prisma\prisma.yml: A valid environment variable to satisfy the declaration 'env:PRISMA_ENDPOINT' could not
 !    be found.

 !    [WARNING] in C:\Users\xxx\Downloads\g-06-09-secrets\g-06-09-secrets\graphql-prisma\prisma\prisma.yml: A valid environment variable to satisfy the declaration 'env:PRISMA_ENDPOINT' could not
 !    be found.

 !    [WARNING] in C:\Users\xxx\Downloads\g-06-09-secrets\g-06-09-secrets\graphql-prisma\prisma\prisma.yml: A valid environment variable to satisfy the declaration 'env:PRISMA_ENDPOINT' could not
 !    be found.

? Set up a new Prisma server or deploy to an existing server? xxx（Deploy先のサーバーを選択）
? Choose a name for your service hugo-blog-app
? Choose a name for your stage prod
```
以上のプロンプトが終了すると、prisma.ymlファイルが自動で書き換えられてProduction ServerへのDeployが始まる。

③ この状態で、prisma.ymlは以下のようになっている

```yml:prisma.yml
#endpoint: ${env:PRISMA_ENDPOINT}
endpoint: https://hugo-blog-app-xxx.herokuapp.com/hugo-blog-app/prod
datamodel: datamodel.graphql
secret: xxx
```

ここで、prisma.ymlとprod.envを以下のように書き換える（ついでにsecretも環境変数にしておく）

```yml:prisma.yml
endpoint: ${env:PRISMA_ENDPOINT}
datamodel: datamodel.graphql
secret: xxx
```
```:prod.env
PRISMA_ENDPOIN=https://hugo-blog-app-xxx.herokuapp.com/hugo-blog-app/prod
```

これで、「prisma deploy -e ../config/dev.env」も「prisma deploy -e ../config/prod.env」もどちらも問題なく実行できるようになった。

この状態でPrisma Cloudを覗くと、新たにServiceが追加されているのを確認できる。
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/385539/1fcbf960-f56f-bcf7-3ef4-37f43d87b830.jpeg)

### Nodejs App Deployment
前提
・git installed in your OS
・npm install -g heroku

1. `heroku login`
2. これまではNodejsのGraphQLAPIはport4000を使用していたが、Herokuでは異なる。デプロイするまでportが分からない。Herokuの環境変数としてInjectする形で対処する。

```javascript:index.js
// HerokuにDepoloyされるとprocess.env.PORTに値が入る
// Heroku外では入らないのでport4000を使用する
server.start({ port: process.env.PORT || 4000 }, () => {
    console.log('The server is up!')
})
```
3.

```javascript:prisma.js
const prisma = new Prisma({
    typeDefs: 'src/generated/prisma.graphql',
    endpoint: process.env.PRISMA_ENDPOINT,  // 環境変数に書き換える
    secret: xxx,      
    fragmentReplacements
})
```
```
// 環境変数inject用に以下のライブラリをインストール
npm install env-cmd
```
```json:package.json
  "scripts": {

    "start": "node dist/index.js",
    
    // srcフォルダの中身をbabelでパース⇒結果をdistフォルダに保存
    // jsファイル以外はそのままコピーして保存する
    "heroku-postbuild": "babel src --out-dir dist --copy-files",
    
    // dev.env をInjectしつつindex.jsをbabel-nodeで実行する（オートリロード）
    "dev": "env-cmd ./config/dev.env nodemon src/index.js --ext js,graphql --exec babel-node",
    
    "get-schema": "graphql get-schema -p prisma --dotenv config/dev.env"
  },
```

babel-nodeにはbabel/polyfillも含まれていたけど、今回の `npm run start`では含まれていないので、index.jsの先頭でimportする。

```
npm install @babel/polyfill
```

```javascript:index.js
// index.jsの先頭でimportする
import '@babel/polyfill/noConflict'
```

```:ターミナル
// app 作成
heroku create

// prod.envの中身を環境変数に設定する 
heroku config:set PRISMA_ENDPOINT=https://hugo-blog-app-xxx.herokuapp.com/hugo-blog-app/prod

// 設定した環境変数には確認できる
heroku config 

// PORTは自動で作成される、PRISMA_ENDPOINT
```

gitを作成する

```:.gitignore
node_modules/
config/
dist/
```

```:ターミナル
project-file> git init
project-file> git add .
project-file> git commit -m "comment"
project-file> git push heroku master
```
Herokuにデプロイすると以下の処理が行われる
1. install dependencies
2. npm run heroku-postbuild
3. npm run start
⇒ デプロイが終わったらherokuが提供するURLにアクセスすると、NodejsのGraphQL Playgroundが表示される

### Sensitive data
secretを環境変数に置き換えていなかったので処理する。

```yml:prisma.yml
endpoint: ${env:PRISMA_ENDPOINT}
datamodel: datamodel.graphql
secret: ${env:PRISMA_SECRET}
```
```javascript:prisma.js
const prisma = new Prisma({
    typeDefs: 'src/generated/prisma.graphql',
    endpoint: process.env.PRISMA_ENDPOINT,
    secret: process.env.PRISMA_SECRET,
    fragmentReplacements
})
```
```:dev.env
PRISMA_ENDPOINT=http://192.168.99.100:4466
PRISMA_SECRET=pi4asdfhsdfhjtjt234643-8u9 (適当に好きなのをセット)
```
```:prod.env
PRISMA_ENDPOINT=https://hugo-blog-app-xxx.herokuapp.com/hugo-blog-app/prod
PRISMA_SECRET=aoguj89043qjggrewgki2n435423n　(適当に好きなのをセット)
```
```:ターミナル
> heroku config:set PRISMA_SECRET=aoguj89043qjggrewgki2n435423n
> git commit -am "comment"
> git push heroku master
> prisma deploy -e ../config/dev.env    // localにDeploy　環境変数を使うので -eに続くコマンドが必要
> prisma deploy -e ../config/prod.env   // HerokuのNodejsアプリにDeploy
```