
Goプロジェクトのバージョンを上げる3ステップ(go.mod・Dockerfile・ローカル環境)
既存のGoプロジェクトのバージョンを上げる際、自分は最初 go.mod だけ変えれば済むと思っていました。実際には go.mod・Dockerfile・ローカル環境の3か所を合わせて変更しないとビルドやローカル動作がちぐはぐになります。作業を通して整理した手順をまとめます。
Goのサポートポリシーを確認する
どのバージョンに上げるかを決める前に、Goのサポートポリシーを確認します。Go言語は「最新の2メジャーバージョンまでをサポートする」という方針を採っています。
Each major Go release is supported until there are two newer major releases
Release History - The Go Programming Language
つまり現時点でサポートされているのは最新2つのメジャーバージョンのみです。それより古いバージョンにとどまっているプロジェクトは、セキュリティパッチも当たらない状態になります。
もう一点、Go 1系の後方互換性ポリシーも確認しておきます。Go 1の範囲内であれば、古いバージョンで書いたコードは新しいバージョンでも正しくコンパイル・実行され続けることが意図されています。
Go 1 and the Future of Go Programs - The Go Programming Language
このポリシーのおかげで、バージョンを上げても既存コードが動かなくなるリスクは比較的小さいです。念のためリリースノートでその間の変更点は確認するようにしています。
現在サポートされているバージョンは以下で確認できます。
All releases - The Go Programming Language
ステップ1: go.modのバージョンを更新する
go mod edit コマンドで go.mod の go ディレクティブを書き換えます。
go mod edit -go=1.23
コマンド実行後は go.mod の先頭付近にある go 1.xx の行が指定したバージョンに変わります。変更後は必ず go mod tidy を実行してモジュール依存関係を再解決します。
go mod tidy
go mod tidy はバージョン変更後に使われなくなった依存や、新しく必要になった依存を整理してくれます。これをスキップすると go.sum との不整合でビルドが失敗することがあります。
ステップ2: Dockerfileのイメージを更新する
Docker環境でビルドしている場合は、Dockerfile の FROM 行も合わせて変更します。go.modだけ変えてDockerfileをそのままにすると、ローカルとコンテナで異なるバージョンが動く状態になります。
FROM golang:1.23-alpine
-alpine を使っている場合はイメージサイズが小さいのでそのまま維持してよいですが、このタグの存在は Docker Hub で確認してから変更します。
ステップ3: ローカルのGoバージョンを揃える
ローカル環境のGoバージョンが古いままだと、go mod edit で指定したバージョンより古いGoで動かすことになり、新しい言語機能やツールチェーンとの差異が出ます。
mise を使っている場合は以下で更新できます。
mise use go@1.23
asdf を使っている場合は次のようになります。
asdf install golang 1.23
asdf local golang 1.23
バージョンマネージャを使っていない場合は公式サイトからインストールします。
All releases - The Go Programming Language
ビルドと動作確認
3か所の変更が揃ったら、ビルドを通してエラーがないことを確認します。
go build ./...
テストがあれば合わせて実行します。
go test ./...
バージョン変更後に破壊的な変更が入っていないかはリリースノートで確認しておくと安心です。Go 1系の後方互換性ポリシーがあるとはいえ、ツールチェーン周りの挙動が変わることはあります。
よくある落とし穴
go.modとDockerfileのバージョンがずれる
go mod edit でgo.modを更新しても、CIや本番環境がDockerイメージで動いている場合はDockerfileを変えないとコンテナ内のGoバージョンが変わりません。「ローカルでは動くのにCIが失敗する」原因の多くはこのズレです。
go mod tidyで依存が消える
バージョンアップ後に go mod tidy を実行すると、新しいGoバージョンで不要になった依存が go.sum から消えることがあります。これは正常動作ですが、チームで開発している場合は go.sum の変更がコンフリクトしないよう、バージョンアップは1ブランチにまとめてPRを出す運用が無難です。
ツールチェーンディレクティブが追加される
Go 1.21以降、go.mod に toolchain ディレクティブが追加されることがあります。
go 1.23.0
toolchain go1.23.4
これはビルドに使うツールチェーンのバージョンを固定するための記述で、Go 1.21から導入された機能です。go mod edit や go mod tidy を新しいツールチェーンで実行すると自動的に追記されます。チームで使うGoのツールチェーンを固定したい場合は役立ちますが、想定外の記述が増えて混乱することもあります。
リリースノートの確認方法
バージョンアップ前後のリリースノートを確認するのが安全です。
Go 1.23 Release Notes - The Go Programming Language
Go のリリースノートは言語変更・標準ライブラリの変更・ツールチェーンの変更・パフォーマンス改善のセクションに分かれており、どこを重点的に読めばよいかわかりやすく整理されています。GODEBUG 環境変数で旧来の挙動に戻せるケースも記載されているため、動作が変わった場合の調査起点としても使えます。
記事の更新をメールで受け取る
質問・リクエストを送る
記事についての質問や、取り上げてほしいテーマがあればお気軽にどうぞ。いただいた質問はブログ記事として回答し、Q&Aページで公開することがあります。