LoginSignup
7
2

More than 3 years have passed since last update.

Go言語とginで作ったHTTPサーバをHeroku上で動かしてみる

Posted at

はじめに

Goとginで作ったHTTPサーバをHeroku上で動かすまでの試行錯誤をまとめてみました。
試行錯誤の結果、ゴールへたどり着いていますので、間違いがあると思います。
いまだに深くは理解ができていません。
参考程度にどうぞ。

最低限どういった手順で進めればよいかだけを見たい場合はまとめを見ていただければと思います。

環境

  • OS: windows 10 Home
  • Go: 1.13.6
  • gin: 1.5.0
  • Git: 2.25.0
  • Text Editor: Atom

ローカル環境でのgo run main.goはコマンドプロンプトより行います。
ginは、go get -u github.com/gin-gonic/ginでローカル環境へ導入済みとします。

ローカル環境でのテスト

HTML をレンダリングする』を参考にmain.goとtemplates/index.tmplを用意します。
また、フォルダ構成は以下です。

soitech-go-gin-test/
 ├ templates/
 │ └ index.tmpl
 └ main.go

index.tmpl
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>{{ .title }}</title>
    </head>
    <body>
        <h1>{{ .h1 }}</h1>
    </body>
</html>
main.go
package main

import(
    "net/http"
    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()
    router.LoadHTMLGlob("templates/*")
    router.GET("/", func(c *gin.Context) {
        c.HTML(http.StatusOK, "index.tmpl", gin.H{
            "title": "/",
            "h1": "/",
        })
    })
    router.GET("/hoge", func(c *gin.Context) {
        c.HTML(http.StatusOK, "index.tmpl", gin.H{
            "title": "hoge",
            "h1": "/hoge",
        })
    })
    router.GET("/huga", func(c *gin.Context) {
        c.HTML(http.StatusOK, "index.tmpl", gin.H{
            "title": "huga",
            "h1": "/huga",
        })
    })
    router.Run()
}

コマンドプロンプトよりgo run main.goを実行し、ブラウザからlocalhost:8080localhost:8080/hogeおよびlocalhost:8080/hugaにアクセスし、プログラムが動いていることを確認します。

Herokuへデプロイする

さあ!Herokuへデプロイします!
私はGitHubへファイルをコミットしたら自動的にHeroku上でデプロイされるようにしていますので、GitHubへファイルをコミットします。

-----> App not compatible with buildpack: https://buildpack-registry.s3.amazonaws.com/buildpacks/heroku/go.tgz
       More info: https://devcenter.heroku.com/articles/buildpacks#detection-failure
 !     Push failed

さあ、エラーが出ました!
インターネットの海で色々と調べてみると、Procfilevendor/vendor.jsonいうものが必要らしい...
用意してみます。

procfile
web: soitech-go-gin-test
vendor.json
{
    "rootPath": "github.com/soichiloYoda/soitech-go-gin-test"
}

コミットして、自動デプロイされると、またもやエラーです。

-----> Running: go install -v -tags heroku . 
main.go:5:2: cannot find package "github.com/gin-gonic/gin" in any of:
    /tmp/tmp.9lmb10Wear/.go/src/github.com/soichiloYoda/soitech-go-gin-test/vendor/github.com/gin-gonic/gin (vendor tree)
    /app/tmp/cache/go1.12.12/go/src/github.com/gin-gonic/gin (from $GOROOT)
    /tmp/tmp.9lmb10Wear/.go/src/github.com/gin-gonic/gin (from $GOPATH)
 !     Push rejected, failed to compile Go app.
 !     Push failed

どうやらginのimportがうまくいっていないようです。
またインターネットの海で色々調べてみると、packageの管理にはGo言語1.11より標準で使えるようになったModulesを使うようです。

こちらのページ→『Go言語の依存モジュール管理ツール Modules の使い方』を参考にさせていただきました。
プロジェクトフォルダへ移動し、vendor/vendor/vendor.jsonを削除してgo mod init soitech-go-gin-testをし、go.modを生成します。

go.mod
module soitech-go-gin-test

go 1.13

その後、go buildを実行するとgo.sumが生成され、go.mod内に依存モジュールの情報が記述されます。

go.mod
module soitech-go-gin-test

go 1.13

require github.com/gin-gonic/gin v1.5.0

GitHub上からもvendor/vendor/vendor.jsonを削除してからgo.modをコミットします。
Herokuで自動デプロイされ、ようやくBuild Succeededとなりました。
ブラウザからsoitech-go-gin-test.herokuapp.comへ接続すると、無事HTTPサーバが動作していることが確認できました。
image.png
また、soitech-go-gin-test.herokuapp.com/hogesoitech-go-gin-test.herokuapp.com/hugaへも無事接続することができました。
image.png
image.png

ちなみにですが、Procfileを以下のように記述してデプロイしましたが、Procfileはなくてもデプロイできるようです。

Procfile
web: soitech-go-gin-test // <- おそらく間違い

また、Heroku上のBuild Logを見るに、Procfileは以下のように記述するのが正解なようです。

Build_Log
Created a Procfile with the following entries:
            web: bin/soitech-go-gin-test
Procfile
web: bin/soitech-go-gin-test // <- おそらく正解

Procfileなしでデプロイすることができましたが、Heroku上のBuild Logに以下のように表示されるため、Procfileは自分で作成しておいたほうがよさそうです。

Build_Log
If these entries look incomplete or incorrect please create a Procfile with the required entries.
       See https://devcenter.heroku.com/articles/procfile for more details about Procfiles

まとめ

試行錯誤してみましたが最低限以下の手順を踏めばよさそうです、といったまとめです。

1.プロジェクトディレクトリを作成する

 mkdir PROJECT_NAME

2.プロジェクトディレクトリ内でmodファイルを作成する

 go mod init PROJECT_NAME

3.main.gotemplates/index.tmplを用意してから、一度ビルドしてmodファイルに依存モジュールの情報を記述させる。

 go build

4.以下のファイルをGitHubへコミットして、Heroku上にデプロイする。

  • templates/index.tmpl
  • go.mod
  • main.go

さいごに

とりあえず、Go言語で作成したHTTPサーバをHeroku上で動かすことができました、うれしいです。
これを元に、FormからPOSTできるものを作ってみようと思います。

7
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2