LoginSignup
16
14

More than 1 year has passed since last update.

【爆速】Go × Docker で構築したアプリを GitHub Actions を使って GCP Cloud Run にデプロイする方法

Last updated at Posted at 2023-04-02

はじめに

最近は Go でのバックエンド開発やインフラ周りも少しずつ触る機会が増えてきたので備忘録としてまとめてみました。

この記事で書くこと

  • Go と Docker で作ったアプリを docker-compose で起動する方法
  • 上記で作ったアプリを Github Actions 経由で Cloud Run にデプロイする方法

この記事で書かないこと

  • Go言語の基礎
  • Docker / docker-compose の基礎
  • Github Actions の基礎

事前準備

以下の項目は事前に設定しておいてください。
すでに登録済みの方はスルーでOKです。

GCPアカウントの作成

  • Google Cloud の公式サイトにアクセス
  • ページ右上の [無料で始める] ボタンをクリック
  • Google アカウントでログインしてください。もし Google アカウントをお持ちでない場合は、[アカウントを作成] ボタンをクリックして新しい Google アカウントを作成
  • アカウント作成フォームに必要事項を入力(必要な情報については、Google の指示に従ってください)
  • 必要な情報を入力したら、Google Cloud Platform にアクセスするための支払い情報を入力(クレジットカード情報を入力するか、銀行
  • 口座情報を使用して支払いを行うことができます。ただし、無料枠を超えた場合にのみ、料金が発生することに注意してください。)

プロジェクトの作成

  • アカウントを作成した後、Google Cloud Console にアクセスして、[プロジェクトを作成] ボタンをクリック
  • プロジェクト名を入力し、[作成] ボタンをクリック。プロジェクトIDが自動的に生成されます。
  • Cloud Run APIを有効にします。左側のメニューから[APIとサービス] > [ダッシュボード]をクリックします。[Cloud Run API] を検索し、APIを有効にする。

gcloud コマンドを使えるように

gcloudコマンドは、Google Cloud Platformの様々なリソースを管理するために使用されるコマンドラインツールです。gcloudコマンドを使用することで、仮想マシン、データストレージ、データベース、アプリケーションサービスなどのGoogle Cloud Platformのリソースを作成、管理、監視することができます。

  • こちらから gcloud コマンドをインストール
  • gcloudコマンドを使用してログイン。gcloudコマンドを使用して、Google Cloud Platformにログインすることができます。以下のコマンドを使用してログインしてください。
gcloud auth login
  • 作成したプロジェクト一覧を以下のコマンドで確認。プロジェクトが作成されていたら表示されるはず。
gcloud projects list 

手順 1. Go と Docker の環境構築

早速 Docker コンテナ上で Go言語を使ってアプリを作成していきましょう。ここでは

  • docker-compose でコンテナを起動
  • ルートパス("/")にリクエストが来たときに HTTP レスポンスとして "Hello, World!!" という文字列を返す
    までやっていきます。

プロジェクトの作成

適当なディレクトリでプロジェクトを作成し、以下のようなディレクトリ構成を作成します。go.mod と go.sum は go mod init した時に自動生成されるので手動で作る必要はありません。

project
├── Dockerfile
├── README.md
├── backend
│   ├── cmd
│   │   └── main.go
│   ├── go.mod
│   └── go.sum
└── docker-compose.yml

Goプロジェクトの作成

backend ディレクトリに移動し、以下のコマンドを実行してGoプロジェクトを作成します。ここでgo.mod と go.sumが生成されます。

cd backend
go mod init example.com/myproject

main.go を作成します。

mkdir cmd
cd cmd
touch main.go

main.go ファイルにアプリケーションのコードを追加します。

package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, World!!")
	})

	http.ListenAndServe(":8080", nil)
}

Dockerfile の作成

プロジェクトのルートディレクトリに Dockerfile を作成します。

FROM golang:1.18-alpine

WORKDIR /app

COPY backend/ .

RUN go build -o main ./cmd/main.go

EXPOSE $PORT

CMD ["/app/main"]
  • FROM golang:1.18-alpine: golang:1.18-alpine イメージをベースにして新しいイメージを作成します。これは、Go 1.18 がインストールされた軽量な Alpine Linux ベースのイメージです。
  • WORKDIR /app: 作業ディレクトリを /app に設定します。以降のコマンドはこのディレクトリで実行されます。
  • COPY backend/ .: backend/ ディレクトリの内容を、現在の作業ディレクトリ(/app)にコピーします。
  • RUN go build -o main ./cmd/main.go: go build コマンドを実行し、./cmd/main.go をコンパイルして実行可能なバイナリ main を作成します。
  • EXPOSE $PORT: 環境変数 $PORT で指定されたポート番号を公開します。これにより、コンテナ外からアプリケーションにアクセスできるようになります。
  • CMD ["/app/main"]: コンテナが実行されると、/app/main バイナリが実行されます。これにより、アプリケーションが起動します。

docker-compose.yml の作成

version: '3'

services:
  backend:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - '8080:8080'

  • version: '3': この docker-compose.yml ファイルが使用する Docker Compose のバージョンを 3 に設定します。
  • services: このセクションでは、Docker Compose で定義するサービス(コンテナ)をリストします。
    • backend: サービス名として backend を定義します。このサービスは、以下の設定に従ってコンテナを作成および実行します。
      • build: このセクションでは、Docker イメージのビルド方法を指定します。
        • context: .: イメージのビルドコンテキストとして、現在のディレクトリを指定します。
        • dockerfile: Dockerfile: Dockerfile という名前のファイルを使用してイメージをビルドします。
      • ports: ホストとコンテナ間で公開するポートのマッピングを指定します。
        • - '8080:8080': ホストのポート 8080 をコンテナのポート 8080 にマッピングします。これにより、ホストからコンテナ内のアプリケーションにアクセスできるようになります。

イメージの作成とアプリケーションの起動

docker-compose up --build 

http://localhost:8080/ にアクセスすると Hello World が表示されているはず。ここまでできたら Github への push も忘れずにしましょう。

スクリーンショット 2023-04-02 17.35.05.png

手順 2. コンテナを Cloud Run にデプロイ

docker-compose で起動できることが確認できたらまずは手動で cloud run へデプロイしてみましょう。

Dockerイメージをビルド/プッシュする

手順1で作成した Dockerfile を下記コマンドでビルドします。

docker build -t gcr.io/[PROJECT_ID]/[IMAGE_NAME]:[TAG] .

gcr.io/[PROJECT_ID]/[IMAGE_NAME]:[TAG]は Google Container Registry(GCR)を使ってイメージを管理する場合のリポジトリ名の形式です。gcr.io は GCR のホスト名、[PROJECT_ID] は GCP プロジェクトの ID、[IMAGE_NAME] はイメージ名、[TAG] はタグ名です。

次にビルドしたコンテナイメージを、Google Container Registry(GCR)などのコンテナレジストリにアップロードします。

docker push gcr.io/[PROJECT_ID]/[IMAGE_NAME]:[TAG]

Cloud Run にデプロイする

下記コマンドを実行すると Clou Run にデプロイできます。

gcloud run deploy [SERVICE-NAME] \
  --image gcr.io/[PROJECT-ID]/[IMAGE-NAME]:[TAG] \
  --platform managed \
  --allow-unauthenticated \
  --region [REGION]

手順 3. GitHub Actions で自動デプロイ

Cloud Run へのデプロイを Github Actions 経由で自動デプロイできるようにしていきます。

deploy.yml の作成

プロジェクトのルートに .github/workflows/deploy.ymlを作成してください。

name: Deploy to Google Cloud Run

on:
  push:
    branches:
      - main

# 下記は適宜書き換えてください
env:
  GCP_PROJECT_ID: プロジェクトの名前
  GCP_REGION: リージョン
  IMAGE_NAME: gcr.io/プロジェクトの名前/イメージの名前

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v1

      - name: Authenticate with Google Cloud
        uses: google-github-actions/auth@v0.4.0
        with:
          credentials_json: ${{ secrets.GCP_SA_KEY }}

      - name: Configure Docker
        run: gcloud auth configure-docker

      - name: Build and push Docker image
        run: |
          TAG=$(echo $GITHUB_SHA | head -c7)
          docker build -t ${IMAGE_NAME}:${TAG} .
          docker push ${IMAGE_NAME}:${TAG}

      - name: Deploy to Cloud Run
        run: |
          TAG=$(echo $GITHUB_SHA | head -c7)
          gcloud run deploy web-push-demo \
            --image ${IMAGE_NAME}:${TAG} \
            --platform managed \
            --region ${GCP_REGION} \
            --allow-unauthenticated
  • name: ワークフローの名前です。この例では、Deploy to Google Cloud Run としています。
  • on: ワークフローのトリガーとなるイベントを指定します。この例では、main ブランチへの push イベントがトリガーとなります。
  • env: ワークフロー全体で使用する環境変数を定義します。この例では、GCP_PROJECT_IDGCP_REGIONIMAGE_NAME の 3 つの環境変数が設定されています。
  • jobs: ワークフロー内で実行されるジョブを定義します。この例では、deploy という名前のジョブが 1 つあります。
  • runs-on: ジョブが実行される GitHub Actions のランナーを指定します。この例では、ubuntu-latest を使用しています。
  • steps: ジョブの中で実行されるステップを定義します。この例では、以下のステップがあります。
    • Checkout code: actions/checkout@v2 アクションを使用して、リポジトリのコードをチェックアウトします。
    • Set up Cloud SDK: google-github-actions/setup-gcloud@v1 アクションを使用して、Google Cloud SDK をセットアップします。
    • Authenticate with Google Cloud: google-github-actions/auth@v0.4.0 アクションを使用して、Google Cloud への認証を行います。GCP_SA_KEY シークレットを使用して、サービスアカウントの認証情報を提供します。
    • Configure Docker: gcloud auth configure-docker コマンドを実行して、Docker クライアントが Google Container Registry への認証を行えるように設定します。
    • Build and push Docker image: Docker イメージをビルドし、Google Container Registry にプッシュします。このステップでは、GITHUB_SHA(コミットの SHA)を使用してタグを生成し、イメージをビルドしてプッシュします。
    • Deploy to Cloud Run: Cloud Run にデプロイを行います。先ほどビルドされた Docker イメージを使用して、Cloud Run サービスをデプロイします。環境変数 GCP_REGION および IMAGE_NAME が使用されます

GCPコンソールからサービスアカウントの作成

  • 先ほど作成したGCPのプロジェクトへ移動し、左側のナビゲーション メニューから、IAM と管理 をクリックし、「サービス アカウント」を選択します。
  • 「サービスアカウント」ページが表示されます。「+サービスアカウントの作成」ボタンをクリックします。
  • 「サービスアカウント名」フィールドに、わかりやすい名前を入力します。オプションで「サービスアカウントの説明」も入力できます。 「作成」ボタンをクリックして次に進みます。
  • 「サービスアカウントの権限を付与する」画面で、このサービスアカウントに必要なロールを追加します(他のサイトでは「Cloud Run サービスエージェント」「Cloud Run 管理者」「ストレージ管理者」だけ追加しておけばOKと書いてたのですが、自分は「storageオブジェクト」の権限も付与しないと上手くいきませんでした)

スクリーンショット 2023-04-02 14.35.25.png

  • オプションで、ユーザーアカウントやサービスアカウントを追加して、このサービスアカウントのリソースへのアクセスを制御することができます。設定が完了したら、「完了」をクリックします。

GitHub リポジトリに秘密鍵を設定

deploy.yml では、秘密鍵は ${{ secrets.GCP_SA_KEY }} として参照されています。この値は、GitHub リポジトリのシークレットから取得されます。シークレットは、リポジトリ設定の「Secrets」セクションに保存されており、GitHub Actions のワークフローでのみアクセス可能です。

GCPコンソールからの操作

  • 先ほどGCPコンソール上から作成したサービスアカウントの行にある「編集」アイコン(鉛筆)をクリックします。
  • 「キー」タブに移動し、「キーの追加」ボタンをクリックし、「JSON」を選択して、「作成」をクリックします。
  • サービスアカウントキーの JSON ファイルがダウンロードされます。このファイルには、サービスアカウントの認証情報が含まれています

スクリーンショット 2023-04-02 15.20.51.png
自動でJSONファイルがダウンロードされます

Github リポジトリからの操作

  • ソースコードを管理してる Github リポジトリを開き、Settings > Secrets And Variables を開き、New repository secret をクリックしてください

スクリーンショット 2023-04-02 15.19.01.png

  • Name を GCP_SA_KEY、Secret に先ほどダウンロードしたJSON形式の秘密鍵を貼り付けてください

スクリーンショット 2023-04-02 15.34.01.png

ここまで設定できると main ブランチにマージされることで Cloud Run に自動デプロイされるようになっているはずです。

スクリーンショット 2023-04-02 15.41.01.png
詳細画面
スクリーンショット 2023-04-02 15.43.36.png

デプロイされたURLにアクセスすると「Hello World」が表示されます。
スクリーンショット 2023-04-02 15.51.53.png

さいごに

備忘録として Go と Docker で使ったアプリを Github Actions を使って Cloud Run へデプロイする方法をまとめてみました。もし不明点やおかしな点があればご指摘ください。

16
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
14