GoのアプリをGithub Actionsを使って自動デプロイする/Heroku編

2022/05/29に公開

初めに

(あなたのLikeが励みになります、感謝します。)
皆さん、デプロイしているでしょうか?ローカルで動かして満足していませんか?
今回はなるべく細かく Heroku へのデプロイについて書いていく。
AWS へのデプロイやフロントサーバとの共存については別途書いていく。

想定読者

  • デプロイしたことがない/ほとんどない
  • heroku で気軽にデプロイしたい
  • Github Actions で auto deploy したい

Herokuへの登録

まだHerokuに登録していない方はこちらから登録しておきましょう
マイページはこんな感じ↓。ここから「create new app」をする。

app name については重複が許されていない?のか簡単な名前だと通らない。ディレクトリ名そのままだとダメなときもありという感じ。適当につけておきましょう。regionもデフォルトで大丈夫。

heroku CLIの導入

後からログ見たりとか、CLIでもデプロイが出来たりするので入れておいて損ない。というかログ必須なので入れてください(ここからできます)。
ターミナルから一連のコマンドを打ってログインだけしておく。

$ heroku login
$ heroku container:login
$ heroku git:remote -a <appの名前>

heroku→githubへの連携

↓の感じのページにリダイレクトされると思うので、「Deploy method」で Github を連携しておく。レポジトリ名で検索すると表示される( Github にデプロイするレポジトリを用意しておいてください)。

github→herokuへの連携

githubまわり

ここら辺はいろいろやり方があるが、今回は「Github Actions」を使う。比較対象として Circle CI があったが、こちらを選んだ理由としては

  • heroku との連携が割と楽(自分は Circle CI 諦めたので)
  • ドキュメントがちゃんとしてる
  • Github で完結させれるならその方がいい

あたりが挙げられる。Github Actions では、レポジトリ直下に.github/workflows/(設定ファイル.yml)
があれば、そこを起点にいろいろやってくれる。その前に事前設定として、連携に必要な環境変数をGithubで設定しておく。

該当プロジェクトの settings/secrets から「New repository secret」を押し、以下の情報を加えておく。

  • HEROKU_API_KEY → herokuのaccount_settingsから「API Key」をコピペ
  • HEROKU_APP_NAME → 初めにつけた名前です
  • HEROKU_EMAIL → 登録時に使用したEmailです

これらをなぜここにおいておくの?env file でよくないか?などと思った方ももしかしたらいるかもしれないが、API Key を Git に乗せることになるのでやめましょう。

レポジトリまわり

今回使っているレポジトリはこちら
ここからは上のレポジトリでファイル構成などを確認していただけるとわかりやすいはず......。具体的な流れを言うと

  1. まず.github/workflows/deploy-to-heroku.yml がエントリーポイント。uses の部分でよしなにデプロイに必要なものとか集めてくれたりしてくれてる。
  • on push → 特定の動作に連動する。今回の例だとmainにpushされたときだけデプロイが入る。
  • ${{}}で宣言されているものは環境変数、ここでの変数は github 側で宣言されたものが反映される。
  • appdir → デプロイするディレクトリ(普通はアプリごとにディレクトリが作成されているはず)。今回は server ディレクトリをデプロイする。
name: Deploy

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: akhileshns/heroku-deploy@v3.12.12
        with:
          heroku_api_key: ${{secrets.HEROKU_API_KEY}}
          heroku_app_name: ${{secrets.HEROKU_APP_NAME}}
          heroku_email: ${{secrets.HEROKU_EMAIL}}
          appdir: "server"
          stack: "container"
  1. 対象のディレクトリ内に heroku.yml を配置。ここが heroku のエントリーポイントになる。
  • run の部分については Dockerfile が実行してから初期に入れるコマンド、デフォルトだとDockerfile での CMD が入れられるらしい。
build:
  docker:
    web: Stage_Dockerfile
run:
  web: air

例として server の Stage_Dockerfile も載せておく(基本的に Dockerfile は実行環境ごとに分けたほうがいい、Heroku は割り当てポートもランダムだったりするので)。

FROM golang:1.16.3-alpine

RUN apk add --update &&  apk add git curl

ADD ./app /go/src/app

WORKDIR /go/src/app

ENV GO111MODULE=on

RUN go get -u github.com/cosmtrek/air

RUN go mod download

EXPOSE $PORT

CMD ["air"]

$PORT → Heroku側で設定してくれる、ランダムなので固定しないこと。アプリに埋め込みで入れている場合は該当箇所をすべて os.Getenv("PORT") とかにすること。

実際にデプロイしてみる

↓こんな感じになって動作が見れる。楽しい。自分はCircle CIとの連携もしているのでどちらかに寄せたいな~とか思ってる。あとtestによるブロックとかも入れたい。

↓実際に詳細を見れる。

エラーが起こってるときは以下をチェックしておくこと

  • ymlファイルのインデントとかが間違っていないか
  • そもそもローカルで立ち上がるのか(エラーがビルド依存なのか)
    よさそうであればHerokuのページから動作を見てみます。Open app からいける。

    ダメそうであればログを見ましょう。少なくともGithub Actionsは通っているはずなので、そこらへんとは別のエラーが起こっているという感じ(PORTとかハードコーディングとか)。
$ heroku logs --tail

最後に

忙しすぎてじっくり記事が書けてないのでCIとの連携、docker-composeを使っている場合のデプロイ手順などはまた今度で....CI/CDはいくらでも便利にできるのが困る。

Discussion