Heroku の Go サポート
最終更新日 2024年12月04日(水)
Table of Contents
このドキュメントでは、Go アプリケーションの認識と実行に関連した Heroku の一般的な動作について説明します。アプリケーションのデプロイ方法の詳細については、Heroku スターターガイド (Go) を参照してください。
サポートされる依存関係/ベンダーマネージャー
Go Modules は、Heroku がサポートする唯一の非推奨ではない依存関係/ベンダーマネージャーです。
非推奨の依存関係/ベンダーマネージャー
Cedar 世代のアプリでは、次の依存関係/ベンダーマネージャーのサポートが非推奨となっています。
自動検出
アプリケーションに go.mod
ファイルがあり、Go Modules により管理されているものとしてアプリケーションを識別する場合には Heroku Go buildpack が使用されます。
Cedar 世代のアプリではクラシック buildpack が使用されますが、アプリケーションに次のいずれかが含まれている場合は、go.mod
ファイルに加えて Go buildpack も使用できます。
- godep により管理されているものとしてアプリケーションを識別する
Godeps/Godeps.json
ファイル - govendor により管理されているものとしてアプリケーションを識別する
vendor/vendor.json
ファイル - サブディレクトリがあり、1 つまたは複数の
.go
ファイルを含み、gb によって管理されているものとしてアプリケーションを識別するsrc
ディレクトリ。
デプロイしたアプリケーションが Go アプリケーションとして認識されると Heroku は次のように -----> Go app detected
と応答します。
$ git push heroku main
...
remote: -----> Go app detected
...
さまざまなメタデータファイル (go.mod
、Godeps.json など) を使用する前に、その基本構造を検証します。エラーがある場合は次のように表示されます。
$ git push heroku main
...
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Go app detected
remote: -----> Checking Godeps/Godeps.json file.
remote: parse error: Expected value before ',' at line 4, column 15
remote: ! Bad Godeps/Godeps.json file
remote:
remote: ! Push rejected, failed to compile Go app
...
Go のバージョン
Heroku では、Go ツールチェーンのさまざまなバージョンを多数使用できます。現在サポートされているバージョンは、ここに一覧表示されています。どのバージョンも使用できますが、サポートは通常、最新の 2 つのメジャーバージョンの最新のマイナーリリースにのみ用意されています。
メジャーリリースの識別子は、そのシリーズの最新のリリースを表すために使用されます。例: go1.22
は、go1.22.4
、go1.22.5
、go1.22.6
など、コードがビルドされた時点で Heroku がサポートする最新の Go 1.2 リリースに拡張します。
特定のマイナーリビジョン(例: go1.21.8
) を選択するには、使用する依存関係マネージャーに応じて、適切なメタデータファイルを手動で編集するか、$GOVERSION
環境変数を設定する必要があります。
- Go Modules
- godep
- govendor
- gb
- dep (コミュニティサポート*)
メジャーバージョンの最初のリリースに固定する必要がある稀なケースでは、バージョン識別子に .0
を追加します。例: go1.23.0
はアプリの go バージョンを go1.23
に固定します。
リンカーへの記号 (およびオプションの文字列) の受け渡し
Heroku は、リンク時に文字列の値を設定する Go リンカーの機能 (-X 記号値) をサポートします。これは、コードをプッシュする前に、アプリケーションの設定で $GO_LINKER_SYMBOL
および $GO_LINKER_VALUE
を設定することにより行えます。$GO_LINKER_SYMBOL
が設定されているが、$GO_LINKER_VALUE
が設定されていない場合は、$GO_LINKER_VALUE
はデフォルトで $SOURCE_VERSION
に設定されます。
これは、コミット SHA や他のビルド固有データを、コンパイル済み実行可能ファイルに直接埋め込むために使用できます。
他のビルド時の動作
複数のアプリケーション環境設定でビルドのさまざまな側面を制御できます。以下に、この文書のどこにも説明されていない変数とそれらの制御対象の一覧を示します。
CGO_CFLAGS
、CGO_CPPFLAGS
、CGO_CXXFLAGS
、およびCGO_LDFLAGS
: これらは、ここに記述されているように標準の CGO フラグです。GOPROXY
、GOPRIVATE
、およびGONOPROXY
: これらはここに記載されているモジュールプロキシの使用を設定する標準の環境変数です。GOVERSION
: 使用する go バージョンへのオーバーライドを提供します。GO_INSTALL_PACKAGE_SPEC
: go install
に渡されたパッケージ仕様をこの値で上書きします。これは、大きなリポジトリがあるが、そのサブセクションだけをコンパイルするときに役立ちます。GO_INSTALL_TOOLS_IN_IMAGE
: true
に設定すると、$HOME/.heroku/go
の slug に go ツールチェーンをインストールし、$GOROOT=$HOME/.heroku/go
を設定し、$GOROOT/bin
を$PATH
に含めます。通常、go ツールは slug にインストールされません。これにより、slug サイズが約 81MB 増えます。GO_SETUP_GOPATH_IN_IMAGE
: true
に設定すると、$GOPATH=$HOME
が設定され、ユーザーコードが$GOPATH
内部の適切な場所に置かれます ($GOPATH/src/github.com/heroku/go-getting-started
など)。dyno を開始すると、作業ディレクトリがユーザーコードのルートに設定されます。通常、buildpack は$HOME
にユーザーコードを保持します。これは、dyno 内部に完全に機能する go ワークスペースおよびツールチェーンが存在するように、GO_INSTALL_TOOLS_IN_IMAGE=true
とともに使用するときに最も役に立ちます。
上記の環境設定のそれぞれは、コードをプッシュする前にアプリケーション上で設定する必要があり、これらの環境設定を有効にするために、環境設定が設定された後でコードをプッシュする必要があります。
ランタイムの動作
go1.5 以降、buildpack は Go ランタイム環境変数を設定しません。アプリケーションの設定上でこれらの環境変数を設定でき、アプリケーションはそれらを配備して再起動します。go1.4 以前では、dyno のサイズに応じてデフォルトの $GOMAXPROCS
が設定されます。これは、heroku config:set
を使用して GOMAXPROCS
の値を設定することによって上書きできます。
buildpack は slug にコピーしないので、ランタイム環境には、go ツールチェーンやコンパイルしたパッケージファイル (*.a
) のコピーがありません。
静的なアセットおよびファイル
git リポジトリに含まれるものはどれも、ランタイムに使用でき、Go の http.FileServer
またはフレームワークの該当するものを使用してローカルファイルシステムから提供できます。go-assets、go-bindata、statik などのツールは、必要ではありません。
デフォルトのプロセスタイプ
以下の条件がすべて満たされた場合にのみ、Heroku によってデフォルトのプロセスタイプが追加されます。
- アプリケーションで Go Modules を使用している
- アプリケーションにまだ Procfile がない
- プロジェクトで 1 つ以上の Go パッケージが検出された
Heroku で Go パッケージが 1 つ検出されると、Heroku ではそのパッケージが web
という名前のプロセスタイプとして追加されます。Heroku で複数の Go パッケージが検出されると、Heroku ではパッケージ名を使用して各パッケージのプロセスタイプが追加されます。
アプリケーションのプロセスタイプを選択または上書きするには、Procfile を使用します。Procfile の設定に関する詳細については、いずれかの Go チュートリアルを参照してください。
アドオン
デフォルトではアドオンはプロビジョニングされていません。アプリの SQL データベースを追加するには:
$ heroku addons:create heroku-postgresql --app example-app
ベンダーディレクトリのサポート
ビルドは、コンパイル時に vendor/
ディレクトリの内容を、$GOPATH
にあるかのように使用します。ベンダーを選択する場合は、パッケージパスを指定するタイミングに注意してください。./...
はすべてのパッケージに一致し、vendor/
内のパッケージも含まれる可能性があります。Heroku では、このブログポストで詳しく述べているように、cmd
ディレクトリのサブディレクトリの内部に、実行可能ファイルの個々のメインパッケージを配置することをお勧めします。
追加のメインパッケージのベンダー化
さまざまなベンダー化ツールが、プロジェクトのベンダーディレクトリに、ローカルプロジェクト内のもの以外の追加パッケージを保存できます。これは、追加のメインパッケージを含め、コンパイルし、インストールするときに役立ちます。一般的な使用法は、データベースの移行を管理する migrate などのパッケージを含めるというものです。
Go Modules
アプリケーションの Go ソースコードにインポートされていない依存関係をインストールするには、go.mod
に Heroku ビルドディレクティブを追加する必要があります。go.mod
Heroku ビルドディレクティブの詳細については、こちらを参照してください。たとえば、次のようになります。
// +heroku install ./cmd/... github.com/golang-migrate/migrate
Godep
godep
サポートは非推奨であり、Cedar 世代のみとなります。
godep で追加パッケージを保存させるには、godep save ./cmd/... github.com/golang-migrate/migrate
のように、godep save
を実行するたびに、これらのパッケージを $GOPATH にインストールし、コマンドラインに含める必要があります。その結果生じる Godeps/Godeps.json
および vendor/
または Godeps/_workspace
に対する変更はコミットする必要があります。
次のプッシュで、Heroku によって ./cmd/...
と github.com/golang-migrate/migrate
の両方がインストールされます。
govendor
govendor
サポートは非推奨であり、Cedar 世代のみとなります。
govendor は、govendor fetch github.com/golang-migrate/migrate
のように、ローカルプロジェクトのパッケージ以外の追加パッケージを取得し、vendor/
ディレクトリに直接保存できます。
さらに、vendor.json
の heroku build configuration セクションは、次のように追加パッケージを heroku.install
配列に加える必要があります。
...
"heroku" : {
...
"install": [
"./cmd/...",
"github.com/golang-migrate/migrate"
]
},
...
vendor/*
に対する変更はコミットする必要があります。次のプッシュで、Heroku によって ./cmd/...
と github.com/golang-migrate/migrate
の両方がインストールされます。
理解を深める
Heroku Go buildpack はオープンソースです。これらの buildpack の動作を技術的に詳しく理解するには、ソースコードを確認してください。
- Go 用の Cedar 世代のクラシック buildpack は github.com/heroku/heroku-buildpack-go にあります。
- Go 用の Fir 世代のCloud Native Buildpack は github.com/heroku/buildpacks-go にあります。