[備忘]fly.ioへのデプロイ手順

## アプリケーションの構成
- ORMapperとしてprismaを使用
DBはpostgresを使用することを前提に設定
- REST-APIとしてFastifyを使用

一からコードを書くのは面倒だったので、Fastifyがgithubに用意している[こちらのコード](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-fastify)をローカルにダウンロードした。

```
npx try-prisma@latest --template typescript/rest-fastify
```

### ファイルの修正
### shcema.prisma修正
ダウンロードしたファイルは、sqliteを使用することになっていたので、postgresを使用するように`/prisma/schema.prisma`を
```
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}
```
から
```
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}
```

### .env追加
に変更し、`.env`ファイルを作成して下記の環境変数を設定した。
```
 DATABASE_URL=postgresql://postgres:password@localhost:5432/postgres
```

:::note warn
Dockerでpostgresコンテナが起動していることを前提にした設定です。
:::

### package.json修正
scriptに下記コマンドを追加
```
"build": "tsc -p tsconfig.json",
"start": "node dist/src/index.js"
```
### マイグレーション
prismaを利用して、ローカルのマイグレーションする
```
npx prisma migrate dev --name init
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "postgres", schema "public" at "localhost:5432"

- Drift detected: Your database schema is not in sync with your migration history.

The following is a summary of the differences between the expected database schema given your migrations files, and the actual schema of the database.

It should be understood as the set of changes to get from the expected schema to the actual schema.

[+] Added tables
  - Post
  - User

[*] Changed the `Post` table
  [+] Added foreign key on columns (authorId)

[*] Changed the `User` table
  [+] Added unique index on columns (email)

- The following migration(s) are applied to the database but missing from the local migrations directory: 20240419132011_init
```
20240419132011_init/migration.sqlが作成された。


### ローカルでの起動確認
```
npm run dev
```
ローカルでアプリを起動させ、API叩いて結果が返ってくることを確認する。
（[こちら](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-fastify)のREADME通りにした）

## fly.ioへの初回デプロイ
ローカルで動作確認できたので、早速fly.ioにデプロイしてみる。
初回デプロイは`fly launch`を使用するといいらしい。
アプリのあるディレクトリ配下に移動し、初回デプロイを実行した。
```
cd rest-fastify
fly launch

----結果----
Scanning source code
Detected a NodeJS app
Creating app in /Users/username/app/typescript_rest-fastify2
We're about to launch your NodeJS app on Fly.io. Here's what you're getting:

Organization: username                                                             (fly launch defaults to the personal org)
Name:         typescript-rest-fastify2                                             (derived from your directory name)
Region:       Amsterdam, Netherlands                                               (this is the fastest region for you)
App Machines: shared-cpu-1x, 1GB RAM                                               (most apps need about 1GB of RAM)
Postgres:     (Fly Postgres) 1 Node, shared-cpu-1x, 256MB RAM (1GB RAM), 10GB disk (determined from app source)
Redis:        <none>                                                               (not requested)
Sentry:       false                                                                (not requested)
```
RegionがAmsterdamになってしまっているが、postgresを使用することを自動的に読み取ってくれている。
このままデプロイを進めると
`Dockerfile`とアプリ設定ファイルの`fly.toml`等が作成される。

:::note info
Dockerfileやfly.tomlの内容は、それっぽい内容になっていたが、作成の精度は使用しているフレームワーク等によっても変わると思う。
今回はRegionがNaritaではなく、Amsterdamになってしまっていた。
`fly launch`後、「Do you want to tweak these settings before proceeding?」と聞かれるので、yesで答えると設定を微調整できる。
:::

:::note warn
build
:::


### デプロイ結果
fly.ioにアプリは作られていたが、起動に失敗していた。
（自動で作られた設定をもとにデプロイを実行したのだから、失敗するだろうとは思ってたが、微調整が必要そう）

ただ何回かファイルを微修正すれば起動した。

#### エラー
```
2024-04-20T09:43:53.948 proxy[e82d921f0529e8] ams [error] [PC01]
instance refused connection. 
is your app listening on 0.0.0.0:3000? 
make sure it is not only listening on 127.0.0.1 
(hint: look at your startup logs, servers often print the address they are listening on)
```
0.0.0.0でリッスンしてないと書かれていた。
ググると[公式に回答](https://fastify.dev/docs/latest/Reference/Server/#listen:~:text=When%20deploying%20to%20a%20Docker%2C%20and%20potentially%20other%2C%20containers%2C%20it%20is%20advisable%20to%20listen%20on%200.0.0.0%20because%20they%20do%20not%20default%20to%20exposing%20mapped%20ports%20to%20localhost%3A)があったので、その通りにschema.presmaファイルを修正した。
```
fastify.listen({ port: 3000, host: '0.0.0.0' }, (err, address) => {
  if (err) {
    fastify.log.error(err)
    process.exit(1)
  }
})
```
デプロイ後、上記エラーは解消し、ひとまずデプロイが完了した。

ホストにアクセスして、アプリが立ち上がっていることを確認してみてください。

:::note info
Nodeのバージョンによっては、Dockerfileに下記のようにopensslの設定を追記する必要があるかも。
```
RUN apt-get update -y && apt-get install -y openssl
RUN apt-get upgrade openssl -y
```
:::


これで完了。
うまくデプロイできなくてたくさん時間を使ったけど、ひとまずアプリが動いてよかった。