【Go+Gin+Gorm】初心者だから超簡単webサービス作ってみる
【go + gin + gorm】webアプリにログイン機能を追加してみる
続きです。
今回は、劣化版ツイッターアプリをGCPを使ってデプロイしてみるという内容です。
GCPで使うのは、GAE standard環境と、Cloud SQL for MySQLです。
コードはgithubに上げています。
go modulesを使う
今回、GAEにデプロイするにあたって、$GOPATH周りでエラーが起こったので、go modulesを使うことにしました。
go modulesは依存モジュール管理ツールです。
Go ではGOPATHという概念があって、Go のコードは外部ライブラリも含めてすべて$GOPATH/src 以下に置くことになっています。
つまり、外部ライブラリと自分のコードが同列の場所にあるということになります。
でもそれだとプロジェクトごとに違うバージョンのライブラリを使いたい時などは困る。開発する度にいちいち外部ライブラリを消して入れ直したりをしなくてはならない。
詳しくは以下のリンク先を読むといいかもしれません。
Go Modules
Go言語の依存モジュール管理ツール Modules の使い方
以下のコマンドを実行していきましょう。
$ cd <このプロジェクト名>
// 依存モジュールの情報は `go.mod` と `go.sum` という名前のファイルに記載される。
$ go mod init
// 依存モジュールの自動インストール
$ go build
ちなみに、自作パッケージをimport文に記載するときは、
<プロジェクトのディレクトリ名>/<自作パッケージディレクトリ名>
にしないとgo buildのときにエラーになりました。
// 今回の場合はこんな感じ
mytweet-deploy/crypto
GAEへのデプロイ
goで作られたプログラムがデプロイされる際にGAE上で行われていることは、アプリケーションのビルドに必要なソースコードを $GOPATH 含めて探索し、すべてアップロードした上でリモートでコンパイルするという流れ。
手元でコンパイルしたアプリケーションのバイナリをアップロードするのではないし、主要なソースコードだけをアップロードしてリモートで go get するわけでもないようです。
この辺りは以下のブログで言及されていました。
Google App EngineでGoを動かすときに知っておくべきこと(ソースコード・ビルド編)
ここからはgcloudコマンドがローカルで使えるようになっていることを前提に話を進めます。
GCP上でプロジェクトを作成してください。
app.yamlファイルがある階層にcdして以下を実行。
$ gcloud app deploy
GAEに他のインスタンスがない場合は、GAEのインスタンス名はdefaultでいいですか?
GAEにdefaultという名前のインスタンスがある場合は、GAEのインスタンス名は何にしますか?
などを聞かれると思うので、入力してください。
何を入力したか忘れてもあとでブラウザ上で確認できます。
そのあとY/nという究極の選択を迫られるので、すかさずY。
数分かかるので、コーヒーでも飲んで休憩してください。
特にエラーが出なければ、ターミナルで以下を実行。
$ gcloud app browse
ブラウザが現れてお馴染みのハローワールドが出てればOK。
嘘です。
エラーが出てたらOKです。
GCPコンソールのApp Engine上にさっき作ったインスタンス名が存在していればOKです。
エラーが出ているのは、データベースに接続できないからです。
これからCloud SQLにインスタンスを作って、アプリ側からデータベースに接続できるように設定していきます。
つまり、ここまででアプリのデプロイは完了したってことですね。
どんなエラーが出てるか見たいねんって方は、以下を実行。
$ gcloud app logs tail -s <インスタンス名>
おそらくデータベース接続の部分でエラーが出ているはず。。
本番環境とローカル環境との共存
本番環境のMySQLにつなぐ部分と、ローカル環境のMySQLにつなぐ処理は以下のように記述しました。
appengineライブラリのIsAppEngine()関数で、App EngineアプリがApp Engineで実行されているかどうかをbool型で取得することができます。
これでローカルでもGAE上でも動かすことができます。
if appengine.IsAppEngine() {
db, err = gorm.Open("mysql", cloudSQLConnection)
} else {
db, err = gorm.Open("mysql", localConnection)
}
if err != nil {
panic(err.Error())
}
appengineライブラリの公式リファレンス
Cloud SQLにデータベースを作成する。
先ほど言ったように、ただ単にGAEにプログラムをデプロイしてもデータベースがないと今回のプログラムは動きません。
まずは以下のリンクからGoogle Cloud SQL APIを有効にして下さい。
https://cloud.google.com/sql/docs/mysql/admin-api/?hl=ja
ブラウザでGCPのコンソールを開いてください。
左上のハンバーガーメニューからSQLをクリック。
インスタンスを作成をクリック。
MySQLをクリック。
項目を適当に埋めていきます。
作成をクリック。
作成されたインスタンスをクリックすると概要というページに飛びます。
左メニューから接続をクリック。
プライベートIPにチェックを入れて、関連付けられたネットワーキングには、先ほどGAEで作ったインスタンス名を選択して下さい。その後保存をクリック。
次は左メニューからユーザーをクリック。ここではデータベースにアクセスできるユーザーを作成します。
ユーザーアカウントを作成をクリック。ユーザー名、パスワードを入力して下さい。保存しましょう。どこかにメモして下さい。
最後に、左メニューからデータベースをクリック。ここではデータベースを作っておきます。
データベースを作成をクリックして、名前を付けて保存。文字コードはutf8です。
設定は以上です。
概要ページに戻って、このインスタンスに接続という欄のインスタンス接続名をどこかにメモして下さい。
設定を.envに記入していきます。
// インスタンス接続名
mytweet_CONNECTIONNAME=project-id:region-name:instance-name
// 作成したユーザー名とパスワード
mytweet_USER=username
mytweet_PASS=12345678
// 作成したデータベースの名前
mytweet_DBNAME=test
保存をしたら、先ほどのようにGAEにデプロイして下さい。
$ gcloud app deploy
$ gcloud app browse
エラーなく画面が表示されたらデプロイ完了です。
お疲れ様でした。
ユーザー登録してみたり、ログインしてみたりして下さい。
Cloud SQLの中身をローカルで確認する
Cloud SQL Proxy を使用して、ローカルからCloud SQLに接続します。
以下MacOS 64ビットの方用です。それ以外の方はローカルマシンに Cloud SQL Proxy クライアントをインストールするを参照ください。
// プロキシをダウンロードします。
$ curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64
// プロキシを実行できるようにします。
$ chmod +x cloud_sql_proxy
// さっきメモしたインスタンス接続名が必要です。
$ ./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:3306
// MySQLを起動します。さっき作ったユーザー名が必要です。
$ mysql -u <USERNAME> -p --host 127.0.0.1 --port 3306
これでCloud SQL上のMySQLを確認することができます。
select文でテーブルの中身を確認したりしてみて下さい。
こちらがCloud SQL Proxyを導入する際の公式ドキュメントです。
ローカルテストにプロキシを使用する場合のクイックスタート
最後に
次はセッションをやろうかなと思ってます。