【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を導入する際の公式ドキュメントです。
ローカルテストにプロキシを使用する場合のクイックスタート
最後に
次はセッションをやろうかなと思ってます。