こんにちは。Tomoyuki(@tomoyuki65)です。
以前にGo言語(Golang)でEchoのAPIを開発する方法に関する記事を書きましたが、今回はそのコードを使ってGoogleのCloud SQL(MySQL)とCloud Runを使って実際に動く環境にデプロイをしてみます。
Go言語(Golang)のAPIをGoogleのCloud SQLとCloud Runでデプロイする方法
まず前提として、今回はCloud Runにデプロイする際にGitHub連携を使うため、デプロイするコードはGitHubで管理している想定です。
加えて、今回はGoogle Cloudの各種サービスを使いますが、Google Cloudのアカウント自体は既に作成済みの前提で進めるので、もしまだ作成していない場合は以下の記事の「第13章の本番環境での画像アップロードをGCS(Google Cloud Storage)で行う方法」を参考に作成しておいて下さい。
そのほか、今回の例ではGoogle Cloud SQLなどの利用料がかかるため、同じように試したい方はその点について問題ないことを事前にご確認下さい。
ではまず以前作成したコードには本番環境等へデプロイするためのDockerfileがないため、以下のコマンドを実行して作成します。
$ cd api
$ touch Dockerfile entrypoint.sh
※Cloud RunのGitHub連携でDockerfileからデプロイする場合は、メインのコードがあるディレクトリと同じ場所(今回の場合は/apiの直下)にDockerfileを作成する必要があります。
次に作成したファイルをそれぞれ以下のように記述します。
##############################
# 本番環境用
##############################
####################
# ビルドステージ
####################
FROM golang:1.23-alpine AS builder
WORKDIR /go/src
# インストール可能なパッケージ一覧の更新
RUN apk update && \
apk upgrade && \
# パッケージのインストール(--no-cacheでキャッシュ削除)
apk add --no-cache \
git \
curl
COPY ./src .
# 依存関係を反映
RUN go install
# ビルド
RUN go build -o main .
####################
# 実行ステージ
####################
FROM alpine:latest
WORKDIR /go/src
# インストール可能なパッケージ一覧の更新
RUN apk update && \
apk upgrade && \
# パッケージのインストール(--no-cacheでキャッシュ削除)
apk add --no-cache \
tzdata \
curl
# ビルドステージで作成したバイナリをコピー
COPY --from=builder ./go/src/main .
# prod用の設定ファイルをコピー
COPY ./src/config/config.prod.yml ./config/
## 今回はコンテナデプロイ時にマイグレーションも実行させたいため、
## マイグレーション用ファイルのコピーとatlasコマンドのインストールも行う。
## (実務等では踏み台サーバーを用意してDBにアクセスさせるのでその場合は不要)
COPY ./src/ent ./ent
RUN curl -sSf https://atlasgo.sh | sh
# コンテナ起動時に実行させるシェルファイルをコピー
# シェルファイルからatlasコマンドでマイグレーションをできるようにする。
COPY ./docker/prod/entrypoint.sh .
RUN chmod +x entrypoint.sh
# ポートを設定
EXPOSE 8080
# シェルファイルを実行
ENTRYPOINT ["ash", "./entrypoint.sh"]
# APIサーバー起動コマンド
CMD ["./main"]
※今回はビルドする際のgoのバージョンは1.23ですが、必要に応じて変更して下さい。
#!/bin/bash
# 環境変数「EXECUTE_MIGRATION」の値で制御する
if [ "$EXECUTE_MIGRATION" == "true" ]; then
echo "マイグレーション実行"
atlas migrate apply \
--dir "file://ent/migrate/migrations" \
--url "mysql://$MYSQL_USER:$MYSQL_PASSWORD@$MYSQL_HOST:3306/$MYSQL_DATABASE"
fi
# DockerfileのCMDを実行
exec "$@"
※今回はデプロイ時にDBへのマイグレーションもさせたいため、シェルファイルでスクリプトを実行させるようにしています。マイグレーションを実行したい場合はCloud Runの設定で環境変数「EXECUTE_MIGRATION」に「true」を設定して下さい。尚、実務の場合はDBへのデプロイは踏み台サーバーを用意して行ったりするので、そういった場合は今回のようなスクリプトファイルは不要になります。(やり方は色々あります)
上記のファイル作成後、コミットおよびGitHubへの反映をして下さい。
コードの準備完了後、Google Cloudを開き、テスト用の新しいプロジェクトを作成します。
Google Cloudの画面左上のリストをクリックしてプロジェクト選択のポップアップを開き、右上の「新しいプロジェクト」をクリックします。
新しいプロジェクト作成画面が開いたら、プロジェクト名を入力し、画面下の「作成」をクリックします。
プロジェクトが作成されると通知が表示されるので、通知の「プロジェクトを選択」をクリックします。
これでテスト用の新しいプロジェクトの作成が完了です。
※尚、Google Cloudではプロジェクト単位で課金されます。利用後に料金がかかるのを完全に止めたい場合は基本的には料金が発生するリソースを削除したりする必要がありますが、よくわからなくなった場合は最悪プロジェクト自体を削除すれば料金が発生するのを止められます。(プロジェクトを削除しても既に発生してしまった分の料金は支払う必要があるのでご注意下さい)
Google Cloud SQLでMySQLのデータベースを作成
次にCloud SQLでMySQLのデータベースを作成します。画面左上のボタンからメニューを開き、「SQL」をクリックします。
次にCloud SQLの画面が開くので、画面の「インスタンスを作成」をクリックします。
次にデータベースエンジンの選択画面で、今回は「MySQLを選択」をクリックします。
次にインスタンスの作成にCompute Engine APIが必要になるため、「APIを有効にする」をクリックします。
これでインスタンス作成画面が開きます。
次に今回はテスト用なので、出来るだけ安い構成で作成するため、エディションは「Enterprise」、プリセットは「サンドボックス」を選択します。
次にインスタンス情報の項目にて、データベースのバージョン選択と、インスタンスIDおよびrootユーザーのパスワードを入力します。(パスワードにはパスワードポリシーを設定することも可能です)
次にリージョンとゾーンの可用性の選択について、基本的にデフォルト設定が一番安いと思うので今回はそのままの設定を使いますが、違うリージョンにしたい場合などは変更して下さい。
そして、さらにインスタンスのカスタマイズの「構成オプションの表示」をクリックします。
次にマシン構成では、CPUを「1 vCPU、3.75GB」に変更します。
次にストレージでは、「ストレージの自動増量を有効にする」のチェックを外します。
次に接続では、「パブリックIP」のチェックを外し、「プライベートIP」のチェックを入れます。(実務を考慮する場合、基本的にプライベートIPで接続します。この設定にすることでVPC内からしか接続できないようにします)
そして、ネットワークは今回はデフォルト設定を使いますが、もし実務で本番環境を構築する場合は別途専用のVPCを作成して割り当てることを覚えておきましょう。
さらにプライベートIPを使う場合は、プライベートサービスアクセス接続が必要になるので、表示されている「接続を設定」をクリックします。(ボタンが表示されない場合は権限が足りないです)
次に画面右側にプライベートサービスアクセス接続設定画面が表示されるので、まずは「APIを有効にする」をクリックします。
次にIP範囲の割り振るでは、今回は「自動的に割り当てられたIP範囲を使用する」を選択しますが、これについても実務で本番環境を構築するなら適切なIP範囲を指定した方がいいのは覚えておきましょう。
IP範囲の指定後、「続行」をクリックします。
次に「接続を作成」をクリックします。
これで先ほどの画面に戻って設定完了のチェックが付けばOKです。
次にデータの保護について、今回はテスト用なので「日次バックアップの自動化」と「削除からの保護の有効化」のチェックは外します。
次にメンテナンス、フラグ、Query InsightsはデフォルトのままでOKですが、ラベルについては必要に応じて設定して下さい。
もし新しいラベルを作成する場合は、キーと値を入力し、「完了」をクリックします。
これで一通りの設定が完了したので、画面に表示される料金の見積もりを確認し、問題がなければ画面左下の「インスタンスを作成」をクリックします。
これでインスタンスの作成が開始されるので、完了まで少し待ちます。
完了のチェックマークが付くか、完了の通知がくればインスタンスの作成が完了です。
データベースとユーザーの作成
次に新しいデータベースの作成を行います。
画面左のメニューから「データベース」画面を開いた後、「データベースの作成」をクリックします。
次に画面右側にデータベースの作成の設定が表示されるので、任意のデータベース名、文字セット、照合を設定し、「作成」をクリックします。
※照合の部分については、そのままだとutf8用のやつが表示されていて選びたいのを選択できませんが、一度文字セットの部分を違うやつに変えてからもう一度「utf8mb4」を選択すると、選びたいやつを選べましたのでご注意下さい。
作成処理後、データベースの一覧画面に表示されれば完了です。
次にデータベースに接続するためのユーザーを作成します。
画面左のメニューから「ユーザー」画面を開いた後、「ユーザーアカウントを追加」をクリックします。
次に画面右側にユーザーアカウント作成の設定が表示されるので、任意のユーザー名とパスワードを設定し、画面下の「追加」をクリックします。
よりセキュアにしたい場合は、パスワードポリシーを追加で設定したり、ホスト名で特定のIPからしかこのユーザーを使えないように設定することも可能です。
作成処理後、ユーザーの一覧画面に表示されれば完了です。
※ここまでで必要なDBの設定が完了です。尚パブリックIPでDBを作成した場合はセキュリティ設定でSSLの利用を有効化すべきですが、今回のようにプライベートIPでDBを作成した場合はVPC内からしかアクセスできないため、基本的にSSLの利用を有効化する必要はありません。
DB(MySQL)への接続確認
ここまででDBの設定が完了したので、新しく作成したDBに接続できるか試してみます。
画面左のメニューから「Cloud SQL Studio」画面を開いた後、上記で作成したデータベース名、ユーザー名、パスワードを入力し、「認証する」をクリックします。
下図のような画面が表示されて接続できればOKです。
DB(MySQL)に接続するためのHOSTの値を確認
次にCloud Runの環境変数に設定するHOSTの値を確認しておきます。
画面左のメニューから「概要」画面を開いた後、このインスタンスとの接続にある「プライベートIPアドレス」がHOSTの値になるのでメモしておきましょう。
Google Cloud Runで利用するサービスアカウントにCloud SQLのアクセス権限を付与
次にCloud Runを利用する前に、Cloud Runで利用する予定のサービスアカウントに対し、Cloud SQLへのアクセス権限を付与しておきます。
画面左上のメニューから「IAM」画面を開き、Compute Engine default service accountの横にある「編集アイコン」をクリックします。
次にロールの割り当て画面が表示されるので、画面下の「+別のロールを追加」から「Cloud SQL クライアント」の権限を追加し、「保存」ボタンをクリックして設定を保存します。
※ロール「Cloud SQL クライアント」は、Cloud SQLへの読み取りと書き込み権限を許可するやつです。
Google Cloud RunにGo言語(Golang)のAPIをデプロイ
次にCloud Runを使い、最初に準備したDockerfileを使ってデプロイを行います。画面左上のボタンからメニューを開き、「Cloud Run」をクリックします。
次に画面中央の「サービスを作成」をクリックします。
これでサービスの作成画面が表示されます。
今回はGitHub連携を使うので、リポジトリから継続的にデプロイする(ソースまたは関数)を選び、その下の「CLOUD BUILDを設定」をクリックします。
画面右側にCloud Buildの設定画面が表示されるので、ソースリポジトリの「認証」をクリックします。
GitHubによる認証のポップアップが表示されるので、「続行」をクリックします。
GitHubのサインイン画面が表示されるので、ユーザー名orメールアドレスおよび、パスワードを入力してサインインして下さい。
接続許可の画面が表示されるので、「Authorize Google Cloud Build」をクリックして承認します。
次にGitHubの対象リポジトリにGoogle Cloud Build用のアプリをインストールする必要があるので、前の画面で「GOOGLE CLOUD BUILDのインストール」をクリックします。
次にGitHubの画面が開くので、リポジトリの設定で「Only select repositories」を選択し、デプロイしたいリポジトリを選んだ後、画面下の「Install」をクリックします。
次に説明文を確認してからチェックを付け、「次へ」をクリックします。
次にビルド構成になりますが、ブランチの部分はmainブランチならそのままでOKで、ビルドタイプには最初に作成したDockerfileの場所を指定します。(今回の例の場合は「api/Dockerfile」を入力)
ビルド構成の設定完了後、「保存」をクリックします。
※このビルド構成ではDockerfileの場所を指定する際にビルドコンテキストの場所までは指定できないため、メインのファイルと同じディレクトリの直下にDockerfileを配置しておく必要があります。
次に構成の下に警告文が出ていますが、Cloud Run Admin APIを有効にする必要があるため、「有効にする」をクリックします。
これでリージョンを選択できるようになりますが、今回はCloud SQLで設定したリージョンと同じやつを選択しておきます。
次に認証設定は「未認証の呼び出しを許可」を選択し、画面下の「コンテナ、ボリューム、ネットワーキング、セキュリティ」の部分をクリックして開きます。
次にコンテナ設定の変数とシークレットのタブから、以下の環境変数を設定します。
ENV=prod
EXECUTE_MIGRATION=true
MYSQL_HOST=
MYSQL_DATABASE=
MYSQL_USER=
MYSQL_PASSWORD=
TZ=Asia/Tokyo
FIREBASE_TYPE=
FIREBASE_PROJECT_ID=
FIREBASE_PRIVATE_KEY_ID=
FIREBASE_PRIVATE_KEY=
FIREBASE_CLIENT_EMAIL=
FIREBASE_CLIENT_ID=
FIREBASE_AUTH_URI=
FIREBASE_TOKEN_URI=
FIREBASE_AUTH_PROVIDER_X509_CERT_URL=
FIREBASE_CLIENT_X509_CERT_URL=
FIREBASE_UNIVERSE_DOMAIN=
※今回は使いませんが、実務ではシークレットサービスを利用した方がいいです。
次にネットワークのタブから、「アウトバウンドトラフィック用のVPCに接続する」のチェックを付け、トラフィックを送信するネットワークとサブネットを選択しますが、今回はdefalut設定を使います。
そして、トラフィックルーティングは「プライベートIPへのリクエストのみをVPCにルーティングする」が選択されていることを確認します。
この設定にするとCloud Runを下図のようにVPC内に配置でき、同じVPC内にあるCloud SQLなどのサービスとプライベートIPで接続できるようになります。
次にセキュリティのタブでCloud Runを起動させるサービスアカウントを設定できますが、今回はデフォルト設定まま「Compute Engine default service account」を使います。
※サービスアカウントについては、実務では別途専用のサービスアカウントの作成および適切な権限を割り当てて利用して下さい。
次にもう一度コンテナのタブに戻り、実行環境とリビジョンの自動スケーリングについて任意のものを設定します。(今回は実行環境は第2世代、リビジョンの自動スケーリングのインスタンスの最大値を2にしました)
設定完了後、Cloud SQLの接続設定をするため、「+接続を追加」をクリックします。
次にCloud SQL Admin APIを有効にする必要があるので、「有効にする」をクリックします。
次に対象のCloud SQLのインスタンスを選択後、画面左下の「作成」をクリックします。
これでCloud Runでのデプロイ処理が実行されるので、完了後に画面中央のURLの部分をクリックします。
デプロイ処理が全て上手く行っていればブラウザからAPIの実行結果を確認することが可能です。
また、今回はデプロイ時にマイグレーションも実行するようにしていたので、もう一度Cloud SQLの画面を開いてCloud SQL Studioから対象のDBを確認してみて下さい。
対象のテーブルが作成されていればOKです。
Google Cloud RunにデプロイしたAPIを試す
次にデプロイしたAPIについて、以前の記事で開発環境で試したのと同様に、上手く動作するかを試します。
Postmanからユーザー作成用のAPIを実行します。
実行後、ステータスが201で正常終了すればOKです。
次に全てのユーザーを取得するAPIを実行し、上記で作成したユーザのデータを取得し、正常終了すればOKです。
次に以前の記事ではFirebase認証の機能も追加したので、それも試します。
まずはFirebaseのAPIを実行し、登録済みのメールアドレスとパスワードでidTokenの値を取得します。
次にユーザー取得APIで上記のidTokenを利用し、APIを実行します。
対象ユーザーの情報を取得し、正常終了すればOKです。
ではもう一度Cloud SQLの画面を開いてCloud SQL Studioから対象のDBを確認してみて下さい。
エディタからSQL「SELECT * FROM users」を入力して実行し、上記のAPIで作成したユーザー情報が取得できればOKです。
GoogleのCloud SQLとCloud Runのリソースを削除する
これでCloud SQLやCloud Runについて一通り動作確認ができたと思いますが、そのままだと利用料金が継続して発生してしまうため、不要なリソースを削除するのを忘れないようにして下さい。
まずはCloud Runの画面を開き、対象のサービスを選択後、画面上の「削除」をクリックします。
削除に関するポップアップが表示されますが、まずは「Cloud Buildトリガー」をクリックします。
トリガー編集画面が表示されるので、画面上の「削除」をクリックします。
実行後、トリガーが削除されればOKです。
次にもう一度先ほどの画面に戻り、ポップアップの「削除」をクリックします。
実行後、対象のサービスが削除されればOKです。
次にCloud SQLの画面を開き、対象のインスタンスの右側にあるメニューから、「削除」をクリックします。
ポップアップが表示されるので、対象のインスタンスIDを入力し、「削除」をクリックします。
実行後、対象のインスタンスが削除されればOKです。
これで利用したリソースを削除しましたが、次の日に利用料を確認すると今回使用した分の料金は41円でした!笑
サクッと試して学習するなら安いです!(Cloud Runは無料枠があるので、Cloud SQLの料金です)
最後に
今回はGo言語(Golang)のAPIをGoogleのCloud SQLとCloud Runでデプロイする方法について解説しました。
Cloud SQLやCloud Runの基本的な使い方については、今回ご紹介した内容で理解できると思うので、興味がある方はぜひ参考にしてみて下さい。
コメント