Table of Contents
Cloud RunにGoで作成したAPIをデプロイしようと思ったところ、うまくいかなかった。
調査してみたところ、データーベースに接続できずに落ちているっぽいとのこと。
ちょっとなんでかわからないけど(今思い返せば、Docker起動していた? という不安がある)、ローカルのDBに接続できないので、いずれ接続する予定だったので、Cloud SQLに接続し、それでCloud Runにデプロイしてみようという風に思い立った。
Cloud SQLに登録する
Cloud Run から Cloud SQL for MySQL に接続するがある。
公式があるので、こちらを参考にする。
なお、今回サーバーはローカル(net/http)で起動することにする。
インスタンスを作成する
- Google Cloud コンソールで Cloud SQL の [インスタンス] (https://console.cloud.google.com/sql?hl=ja&_ga=2.145632700.968950133.1716041931-758618644.1700836939)ページに移動する。
- インスタンスを作成 をクリック。
- [MySQL を選択] をクリック。
インスタンスを作成するには、まず Compute Engine API を有効にする必要があります。
という警告が出るので、APIを有効にする。
インスタンスID、パスワード、を登録。
My SQLのバージョンを8にし、Cloud SQL のエディションはEnterpriseにする。
プリセットをいったん開発環境にして、リレージョンを東京、ゾーンをシングルに設定する。
構成オプションを開き、とりあえず一番小さい1 vCPU、3.75 GBを選択してみる。
で、インスタンスを作成する。
構成オプションはとりあえず、最小で不満があればあげていく方法で問題ないらしい。
DBの作成
インスタンスのデータベースにいき、データーベースの作成をクリックする。
今回インスタンスの作成をし、データーベースの作成をしていなかったので、エラーが出続け、悩まされた。
接続を試みる
まず接続をしてみたところ、
$ go run main.go2024/05/26 00:41:05 cloudsqlconn.NewDialer: failed to create default credentials: google: could not find default credentials. See https://cloud.google.com/docs/authentication/external/set-up-adc for more informationexit status 1というエラーが出た。
どうやら認証情報が見つかりませんとのこと。
対象のディレクトリでgcloud auth application-default loginを実行し、ログインを完了させた。
ソースコードは公式を参考に下記のように。
package db
import ( "context" "database/sql" "fmt" "log" "net" "os"
"cloud.google.com/go/cloudsqlconn" "github.com/go-sql-driver/mysql" gmysql "gorm.io/driver/mysql" "gorm.io/gorm")
var DB *gorm.DB
type Model struct { gorm.Model}
func mustGetenv(k string) string { v := os.Getenv(k) if v == "" { log.Fatalf("Fatal Error in connect_connector.go: %s environment variable not set.", k) } return v}
func InitDB() {
var ( dbUser = mustGetenv("DB_USER") // e.g. 'my-db-user' dbPwd = mustGetenv("DB_PASS") // e.g. 'my-db-password' dbName = mustGetenv("DB_NAME") // e.g. 'my-database' instanceConnectionName = mustGetenv("INSTANCE_CONNECTION_NAME") // e.g. 'project:region:instance' usePrivate = os.Getenv("PRIVATE_IP") ) d, err := cloudsqlconn.NewDialer(context.Background()) if err != nil { fmt.Errorf("cloudsqlconn.NewDialer: %w", err) return } var opts []cloudsqlconn.DialOption if usePrivate != "" { opts = append(opts, cloudsqlconn.WithPrivateIP()) } mysql.RegisterDialContext("cloudsqlconn", func(ctx context.Context, addr string) (net.Conn, error) { return d.Dial(ctx, instanceConnectionName, opts...) })
dbURI := fmt.Sprintf("%s:%s@cloudsqlconn(localhost:3306)/%s?parseTime=true", dbUser, dbPwd, dbName)
sqlDB, err := sql.Open("mysql", dbURI) if err != nil { log.Fatalf("sql.Open: %v", err) }
// Open a connection to the database using the gorm package DB, err = gorm.Open(gmysql.New(gmysql.Config{ Conn: sqlDB, }), &gorm.Config{})
if err != nil { log.Fatalf("gorm.Open: %v", err) }
fmt.Println("データベースに接続しました")}これで実行したところ、
データベースに接続しました2024/05/28 00:26:14 defaulting to port 80802024/05/28 00:26:14 listening on port 8080無事に接続できた。
課金具合が予想を超えている
Cloud SQLの課金体系がいまいち理解できていない。
ただコンソールを見る限り、想像を超える課金が行われている。
使用していない時はインスタンスを停止してその場を凌ぐけど、しっかりと理解をしたい。