Dockerで開発したGoアプリケーションをRenderでデプロイする

# はじめに
こんにちは！mizukoです！
先日[PaPut](https://paput.io)という個人開発のサービスをβ版としてリリースしました！

バックエンドのリリースにRenderを利用しているのですが、意外とGo&Dockerのruntimeでデプロイしている情報が少なかったので、せっかくならアウトプットしていきたいと思います！

PaPutについてはぜひ[こちら](https://qiita.com/mizuko_dev/items/5335f93bb3c93f407796)をご覧いただけますと幸いです🤗

# この記事で扱わないこと
- Renderの基本的な使い方
    - Blueprintでのデプロイ方法など
 
# render.yaml
いきなり結論ですが、以下Blueprintの構成になります。

```yml
version: "1"

services:
  - type: web
    name: paput-api
    runtime: docker
    dockerContext: .
    dockerfilePath: ./docker/golang/Dockerfile
    repo: https://github.com/hoge
    plan: free
    region: singapore
    branch: main
    domains:
      - api.paput.io
    autoDeploy: true
    envVars:
      - key: PORT
        value: 8080
      - key: GIN_MODE
        value: release
      - key: DB_HOST
        fromDatabase:
          name: paput-db
          property: host
      - key: DB_NAME
        fromDatabase:
          name: paput-db
          property: database
      - key: DB_USER
        fromDatabase:
          name: paput-db
          property: user
      - key: DB_PASSWORD
        fromDatabase:
          name: paput-db
          property: password
      - key: DB_PORT
        fromDatabase:
          name: paput-db
          property: port
      - key: GOOGLE_CLIENT_ID
        sync: false
      - key: GOOGLE_CLIENT_SECRET
        sync: false
      - key: GOOGLE_REDIRECT_URL
        sync: false
      - key: JWT_SECRET
        sync: false
      - key: TZ
        value: Asia/Tokyo

databases:
- name: paput-db
  databaseName: hoge
  user: hoge
  plan: free
  region: singapore
  postgresMajorVersion: "15"
```

トピックとしては以下になります。
- runtimeはdockerにする
- databaseのfreeブランはBlueprintで設定できないというような記事をどこかで見かけた気がするのですが、今は普通に対応してる
- dockerfileについては後述

# ローカル開発と本番で起動方法を切り替える
## Dockerfile
Dockerfileをローカル用と本番用で切り替えられる様にしておくと便利です。

```dockerfile
FROM golang:1.22-alpine AS base

RUN apk add --no-cache postgresql-client git make
RUN go install ariga.io/atlas/cmd/atlas@latest
RUN go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
RUN go install github.com/vektra/mockery/v2@v2.42.1

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod tidy

COPY . .

EXPOSE 8080

# 開発環境用のステージ
FROM base AS local

RUN go install github.com/cosmtrek/air@latest

CMD ["air"]

# 本番環境用のステージ
FROM base AS prod

RUN go build -tags netgo -ldflags '-s -w' -o app

# スクリプトに実行権限を付与
RUN chmod +x start.sh

CMD ["./start.sh"]

# デフォルトのステージを本番環境に設定
FROM prod
```

ローカルのcompose.ymlはtargetをlocalにしておきます。
```yml
services:
  paput-api:
    container_name: paput-api
    build:
      context: .
      dockerfile: ./docker/golang/Dockerfile
      target: local # ローカル用のビルドステージを指定

~ 略 ~
```

## start.sh
アプリケーションの起動用にstart.shを準備しておきます。
以下はシンプルな構成になっていますが、必要であればアプリケーション起動前に実行しておきたコマンドなどを定義します。

```sh
#!/bin/sh

# マイグレーションの実行
make migrate

# アプリケーションの起動
./app
```

# コールドスリープ対策
freeプランだと、15分非アクティブだとコールド状態になってしまい、ユーザー影響が出てしまいます...
そのため、GASを利用してキープアライブします。
以下記事を大変参考にさせていただきました🙏

https://zenn.dev/no215/articles/ff4f1670c080e4

# おわりに
Dockerで開発したGoアプリケーションをRenderでデプロイする方法を記載してみました！
Goでアプリケーションで個人開発している方は是非参考にしていただければと思います！

冒頭でも記載しましたが、[PaPut](https://paput.io)というサービスのβ版をリリースしました！
是非手軽に使って、フィードバックいただけますと嬉しいです！
PaPutについてはぜひ[こちら](https://qiita.com/mizuko_dev/items/5335f93bb3c93f407796)もご覧ください！