Google App Engine + Google Cloud SQLでAPIサーバーを構築したので記録を残します。(Qiita初投稿!)
今回はGoで書いたプログラムをGoogle App Script(以下GAE)にアップロードしHTTPレスポンスが返ってくるところまでを記載します。(要はHello, World!)
環境
- OS: macOS Catalina Version 10.15.7
- IDE: Visual Studio Code Version: 1.50.0
- Go(Local): version go1.15.5 (GAEは2020/11現在1.14までサポートしています。この記事では1.14でGAEを使用)
GCP CLIのバージョン:
Google Cloud SDK 319.0.0
bq 2.0.62
core 2020.11.13
gsutil 4.55
実装!
1. GCPのプロジェクト作成
CLIダウンロードしたらアカウントの認証を行います。以下のコマンドを実行します。
%gcloud auth login
Your browser has been opened to visit:
https://accounts.google.com/o/oauth2/...
するとブラウザが立ち上がり以下のような画面が表示され、アクセスの許可を求められます。Allowをクリックします。
Googleのリファレンスにリダイレクトすれば認証は成功です。ターミナルに戻ると以下のように表示されます。
You are now logged in as [ ログインした際に使用したGmailアカウント].
Your current project is [None]. You can change this setting by running:
$ gcloud config set project PROJECT_ID
GCPはプロジェクトごとに各プロダクトのインスタンスを配置します。ログイン時、$ gcloud config set project PROJECT_ID
とカレントプロジェクトが設定されていないよと怒られているので、新たにプロジェクトを作成し、カレントプロジェクトとして設定します。
この記事では新規プロジェクトのProject IDをtest-api-server
として作成します。以降ではtest-api-server
は適宜設定したProject IDに読み替えてください。
%gcloud projects create test-api-server
Create in progress for [https://cloudresourcemanager.googleapis.com/v1/projects/test-api-server].
Waiting for [operations/cp.6857715921976913154] to finish...done.
Enabling service [cloudapis.googleapis.com] on project [test-api-server]...
Operation "operations/acf.d16dec56-cb67-494e-a03d-02c1911a6bb0" finished successfully.
プロジェクトのリストを表示し、test-api-server
が作成されていることを確認します。NAMEはGUI(Webのコンソール画面)で表示される際に使っているようです。
%gcloud projects list
PROJECT_ID NAME PROJECT_NUMBER
...
test-api-server test-api-server 630796980740
...
カレントプロジェクトをtest-api-server
に設定します。gcloud config set {キー} {値}
で設定値を変更します。 gcloud config get-value {セクション}/{キー}
で設定値を確認できます。
全ての設定値はgcloud config list
で確認できます。またgcloud projects describe {Project ID}
でプロジェクトの詳細を確認できます。
ここではproject
の値をProject IDtest-api-server
にセットします。セット後、設定が正しいか確認します。
%gcloud config set project test-api-server
Updated property [core/project].
%gcloud config get-value core/project
test-api-server
%gcloud projects describe test-api-server
createTime: '2020-11-19T15:45:58.946Z'
lifecycleState: ACTIVE
name: test-api-server
projectId: test-api-server
projectNumber: '{12桁の数字}'
以上でGCPのプロジェクトを作成できました。
2. GAEインスタンス作成
GCP CLIを使用する際は毎回アップデートするようにしておきましょう。GCPは1日10数回のペースで更新がかかっているので必須です。
%gcloud components update
All components are up to date.
GAEを配置するリージョンを選択します。今回は東京リージョンasia-northease1
を選択します。ターゲットユーザーから物理的に遠いリージョンを選んでしまうと当然ですがGAEの応答が遅くなるので注意です。
数字の入力を求められるので2をタイプしエンターします。
%gcloud app create
You are creating an app for project [test-api-server].
WARNING: Creating an App Engine application for a project is irreversible and the region
cannot be changed. More information about regions is at
<https://cloud.google.com/appengine/docs/locations>.
Please choose the region where you want your App Engine application
located:
...
[2] asia-northeast1
...
Please enter your numeric choice: 2
入力後、数秒から数分でGAEの作成が完了します。
Creating App Engine application in project [test-api-server] and region [asia
-northeast1]....done.
Success! The app is now created. Please use `gcloud app deploy` to deploy your first app.
とりあえず指示通りデプロイしてみます。当然ですがまだ何もデプロイするものがないので怒られます。
%gcloud app deploy
ERROR: An app.yaml (or appengine-web.xml) file is required to deploy this directory as an App Engine application. Create an app.yaml file using the directions at https://cloud.google.com/appengine/docs/flexible/python/configuring-your-app-with-app-yaml (App Engine flexible environment) or https://cloud.google.com/appengine/docs/standard/python/config/appref (App Engine standard environment) under the tab for your language.
ERROR: (gcloud.app.deploy) [{現在のわーキンディレクトリまでのパス}] could not be identified as a valid source directory or file.
デプロイに失敗しているのでもちろんインスタンスもありません。gcloud app instances list
で確認します。
%gcloud app instances list
Listed 0 items.
続いて中身のアプリを作っていきます。
2. GAEにアップロードするファイルの作成
GAEに最低限必要なファイルはGAEの設定を記述したapp.yamlと処理を記述したスクリプトファイル(ここではmain.go
とします)の2つです。この記事ではapp.yaml
とmain.go
のみ作成します。
他にも3つの構成ファイルがあります。ただし必須ではありません。
- cron.yaml: 定期的に実行するタスクを設定できます。(e.g. 毎日0時にメールを送るなど)
- dispatch.yaml: ルーティングを制御します。アクセスするエンドポイントによって実行する処理を変更できます。
- index.yaml: App Engineから直接呼び出せるDatastore(Firestore, NoSQL)の構成ファイルだそうです。(使ったことない)
index.yamlにより使用できるDatastoreには上限があるようですが、通常の利用には十分なサイズだそうです。詳しくは「インデックス | Cloud Datastore ドキュメント | Google Cloud」を見てください。
app.yaml
app.yaml
に必須な要素はruntime
のみです。ここでは利用可能なGoのバージョンのうち最新の1.14を使用します。他の要素を学ぶ際はここが参考になります。
runtime: go114
main.go
この記事ではとりあえずGoで書いた処理をGAEで動くことを確認したいため、最小限のコードでHello, World!が表示されるようにコードします。
以下のコードでは、
- 最低限のパッケージをインポートし、
- 即時関数でHello, World!と表示させる関数を定義、
- httpにハンドラ関数として渡した後に
- 8080ポートを開きます。
Vimなど、適当なエディタを開き、以下のファイルを作成して保存します。
package main
import (
"fmt"
"net/http"
)
func main() {
handler := func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello, World!")
}
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
上記の処理を実行し、HTTPレスポンスが返ってくるかを確認します。
go run main.go &
で処理をバックグラウンドで実行した後、curl
でHTTPレスポンスを確認します。
Hello, World!が返ってきたら無事GoでWeb Serverを立ち上げられています。確認が終わった後kill
コマンドでバックグラウンドで実行していたGoを停止します。
%go run main.go &
[1] 41608
%curl localhost:8080
Hello, World!%
%kill 41608
[1] + terminated go run main.go
これでデプロイの準備が整いました。
4. デプロイ
GAEへのデプロイは基本的に以下のワンライナーで行えます。
%gcloud app deploy
ですが、初回デプロイ時はGAEに必要な追加コンポーネントのダウンロードが必要なため以下のようなメッセージが表示されます。Y
をタイプしインストールします。
application.
Your current Cloud SDK version is: 319.0.0
Installing components from version: 319.0.0
┌──────────────────────────────────────────────┐
│ These components will be installed. │
├──────────────────────────┬─────────┬─────────┤
│ Name │ Version │ Size │
├──────────────────────────┼─────────┼─────────┤
│ App Engine Go Extensions │ 1.9.71 │ │
│ App Engine Go Extensions │ 1.9.71 │ 4.8 MiB │
└──────────────────────────┴─────────┴─────────┘
For the latest full release notes, please visit:
https://cloud.google.com/sdk/release_notes
Do you want to continue (Y/n)? Y
...
必要なコンポーネントがダウンロードできると、続いてGAEへのアップロードが始まります。
descriptor: [/{カレントディレクトリへのパス}/app.yaml]
source: [/{カレントディレクトリへのパス}]
target project: [test-api-server]
target service: [default]
target version: [20201120t025037]
target url: [https://test-api-server.an.r.appspot.com]
Do you want to continue (Y/n)? Y
Please enter 'y' or 'n': y
Beginning deployment of service [default]...
Created .gcloudignore file. See `gcloud topic gcloudignore` for details.
╔════════════════════════════════════════════════════════════╗
╠═ Uploading 2 files to Google Cloud Storage ═╣
╚════════════════════════════════════════════════════════════╝
File upload done.
Updating service [default]...failed.
うーん失敗してしまいました、、、初回ビルド時はWebコンソールからCloud Build APIを有効化しないといけないようです。
ERROR: (gcloud.app.deploy) Error Response: [7] Access Not Configured. Cloud Build has not been used in project test-api-server before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudbuild.googleapis.com/overview?project=test-api-server then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
https://console.developers.google.com/apis/api/cloudbuild.googleapis.com/overview?project=test-api-server にアクセスします。(URL中のtest-api-serverは適宜Project IDに書き換えてください)
下記の画面が表示されるのでEnableをクリックし有効化してください。GCPの請求先を求められるので請求先のアカウントを選択しクリックします。
GCP上でビルドができるようになりました。これでGAEにコードをデプロイできるはず...
再度gcloud app deploy
を実行します。
%gcloud app deploy
Services to deploy:
descriptor: [/{カレントディレクトリへのパス}/app.yaml]
source: [/{カレントディレクトリへのパス}]
target project: [test-api-server]
target service: [default]
target version: [20201120t030334]
target url: [https://test-api-server.an.r.appspot.com]
Do you want to continue (Y/n)? Y
Beginning deployment of service [default]...
╔════════════════════════════════════════════════════════════╗
╠═ Uploading 0 files to Google Cloud Storage ═╣
╚════════════════════════════════════════════════════════════╝
File upload done.
Updating service [default]...⠛
Setting traffic split for service [default]...done.
Deployed service [default] to [https://test-api-server.an.r.appspot.com]
You can stream logs from the command line by running:
$ gcloud app logs tail -s default
To view your application in the web browser run:
$ gcloud app browse
gcloud app browse
を実行するとブラウザが立ち上がり、main.goによるHTTPレスポンスを確認できます。
またgcloud app instances list
によりインスタンスが立ち上がっていることを確認できます。
%gcloud app instances list
SERVICE VERSION ID VM_STATUS DEBUG_MODE
default 20201120t030334 XXX N/A
ここまででGAE上でGoを実行できるようになりました。
次回以降ではmain.goの中身を更新してAPIサーバーのように作り替えていきたいと思います。