個人的にAPIを作ったけど、やっぱり作ったらどこかにデプロイしたい。
当初は、 GKE + CloudSQLの構成でやろうと思ったけど、結構料金かかるみたいだから断念。Kubernetes試してみたかったんだけどな。そもそも、CloudSQLが割と料金かかる。
RDBは無料で使えるようなものはほとんどないっぽい・・悲しい・・・
ということで、APIはHerokuに置いてしまうことにした。開発環境はDockerで作ったから、HerokuでもDocker運用する。
herokuでもdocker使える
どうせならDockerで本番環境もやりたくて、調べたらHerokuでもDocker使えるらしい。
Deploying with Docker | Heroku Dev Center
そして、Goにも対応しているということだからこれでいける。コマンド的には以下の2つでデプロイできるらしい。
$ heroku container:push web // Dockerfileをbuildしてコンテナにプッシュする。 $ heroku container:release web // プッシュされたimageをリリースする。
これでherokuでもDockerfileを元に作られたimageを使うことができる。
herokuリポジトリをgitに登録
まずは、herokuのリポジトリをgitで登録する。これやんないと、herokuにpushするときにエラー起きる。
$ heroku git:remote -a go-portfolio-api -r heroku
$ git remote -v
remoteにherokuのリポジトリが登録されていればok。
APIをherokuに対応させる
まあコマンド打ってherokuにデプロイすれば、割と簡単に使えるのかなー・・・とか思っていたけど甘かった。herokuとはいえ、やっぱり環境構築はしんどい。
DBをpostgreSQLにする
開発はMysqlでやっていた(CloudSQL使う想定だった・・・)んだけど、Postgresに変更した。HerokuでもAddonを追加すれば、Mysql使えるんだけど、何してもバージョンが5.5.62
から上がらないという・・・これだと開発で使っていたSQL対応できないじゃん・・せめて・5.7まで対応しておくれ・・・
開発環境のMysqlを5.5.62まで下げるという手段もあったけど、普通に嫌だしPostgreSQL使うことにした。それに伴ってgooseで作ったSQLも変更した(MysqlとPostgresだと型が違ったりするからね・・トリガーなんかも追加したよ・・・)
postgres用のアドオンを入れる
heroku側ではpostgres用のアドオンを入れる。
$ heroku addons:create heroku-postgresql:hobby-dev
追加したらそのDB情報を見ることができるはず。
$ heroku config
ちょっとわかりにくいけど、ここで表示されるDATABASE_URL
の構成はこんな感じ⬇️
postgres://ユーザー名:パスワード@ホスト名:ポート/データベース名
この情報を使えば、heroku上のDB(postgreSQL)に接続できるはず。
GoのコードをPostgresに対応する
mysql用のものをimportして使っていたけど、postgresのものをimportして使うようにした。
_ "github.com/jinzhu/gorm/dialects/postgres"
構造体ちょっと変えたり、あとgorm使っていたんだけど、Open
の引数も変えたわ。
connection := host=db port=5432 user=aaaaa password=aaaaa dbname=aaaaa sslmode=disable db, err := gorm.Open("postgres", connection)
mysqlの時とはちょっと書き方が違うから、herokuで使うDB情報を元に書き換える。 Connecting to database | GORM - The fantastic ORM library for Golang, aims to be developer friendly.
herokuのDBに対応する
上で書いた情報使えば、ローカルからherokuのDBを見に行くのはできるんだけど、herokuにあげたアプリケーションからherokuのDBを見にいこうとするとエラーになる。これ普通に詰まって結構調べたわ・・・
で、ちょっと変えたのがgorm.Open
の部分。
url := os.Getenv("DATABASE_URL") connection, err := pq.ParseURL(url) if err != nil { panic(err.Error()) } connection += " sslmode=require" db, err := gorm.Open("postgres", connection)
herokuから動かす場合にはこれで対応できた。os.Getenv("DATABASE_URL")
はheroku config
で出てくるDATABASE_URL
。
Dockerfile改造する
gin使ってdockerfileにこんな風に書いていたんだけど、このポート番号指定はherokuではダメらしい。
CMD dep ensure -vendor-only && gin -p 9800
herokuでは、勝手にポート番号が割り当てられるようで、それを適用するためには以下のようにする必要がある。
CMD dep ensure -vendor-only && gin -p $PORT
$PORT
でherokuで割り当てられるポート番号を指定できるらしいね。
デプロイする
デプロイはこれ。
$ heroku container:push web // Dockerfileをbuildしてコンテナにプッシュする。 $ heroku container:release web // プッシュされたimageをリリースする。
heroku container:push web
でDockerfileをbuildして、pushしてくれる。で、それをリリースするにはheroku container:release web
。これでheroku open
すれば、herokuでアプリケーションの確認ができるはず。
heroku.yml記述する
なんかheroku.ymlないとファイルないから作れって言われるね。だからbuildするためのheroku.ymlを書いてPush。
build: docker: web: Dockerfile
まあ、これでいった。