Go言語のバージョンアップ方法まとめ
はじめに
サービスのバックエンドにGoを使用しています。
最近、Goのバージョンが古くなってきたため、システムの安定性やセキュリティ、パフォーマンスを向上させるためにバージョンアップを行うことにしました。
本記事では、その手順と注意点について詳しく解説します。
結論から
Goは静的型付け言語であり、後方互換性を維持することを明言しています。
基本的な方針としては、まずバージョンを上げてみて、コンパイルエラーや実行時エラーが発生しないかを確認するのが最も効率的な方法です。
バージョンアップのコマンド
-
コンテナ、開発環境のgoバージョンアップ
DockerfileのFROM
を変更し、docker compose build --no-cache
-
go.modのバージョン変更
go mod edit -go=1.22.5
- 依存関係のバージョン更新
go get -u ./...
バージョンアップによる影響確認
- コンパイルエラーが無いかを確認
- リリースノートを確認し、変更内容の中で挙動が変わりそうな実装がないかを確認
- 実行時エラーが潜んでいるかもしれないため、念入りに動作確認しましょう
バージョンアップの詳細
バージョンアップの全体的な流れ
ローカル環境にて、アプリ用のDockerコンテナを起動し、その中で実行するアプリケーションのバージョンアップする想定で解説します。
- 現サービスのGoバージョンの確認
- goの最新リリース状況の確認
- ローカルのコンテナ内をバージョンアップ
- アプリケーションのバージョンアップ
- ローカル環境アップグレード
1. 現サービスのGoバージョンの確認
開発環境や実行環境にインストールされているGoのバージョンを確認します。
go version
go version go1.19.1 darwin/arm64
環境がDockerコンテナなどコンテナ化されている場合、DockerfileのFROM
にバージョンが指定されているかと思います。
FROM golang:1.19.1 As builder
・・・
次にgo.modファイルに記載されているgoのバージョンを確認します。
3行目のgo
で始まる部分がバージョンです。
module xxxxxxx/xxxxx/xxxxx
go 1.19.1
require (
・・・
}
2. goの最新リリース状況の確認
以下のページにはリリースされたバージョンが一覧で載っています。
リリースヒストリー
このページから、各メジャーバージョン毎にそれぞれ個別のページに飛べるので、それぞれのバージョンでの変更点を確認しておきましょう。
例:go1.22のリリースノート
メジャーバージョンにおける変更点は、パッケージ毎に変更された内容が記載されているので、アプリ内で使用しているパッケージについては特に変更点に注意しましょう。
また、各バージョンのマイナーリビジョンでの変更点については、最初に示したリリースヒストリーで確認が可能です。
例:go1.22のマイナーリビジョンの変更点
アップするバージョンの決定
Goは後方互換性を重視しているため、基本的には最新バージョンを選んで問題ないでしょう。
これまでの各バージョンのリリースノートの冒頭には、互換性がある旨が記載されています。
例えばv1.22であれば、以下のとおり
As always, the release maintains the Go 1 promise of compatibility. We expect almost all Go programs to continue to compile and run as before.
日本語訳:これまでどおり、このリリースでは Go 1の互換性が維持されています。ほぼすべての Go プログラムが、これまでどおりコンパイルおよび実行され続けることが期待されます。
ただし、goの不具合の修正などにより互換性を保てない修正も実際にあったりします。
このような場合の措置として新しいgoバージョンで古いバージョンのgoをコンパイルできる機能が組み込まれています。(go 1.21より正式採用されたGODEBUG機能)
3. ローカルコンテナのバージョンアップ
コンテナ定義の修正
localで起動するコンテナで使用
1行目のFROM
を適切なバージョンのイメージに変更
FROM golang:1.22.5 As builder
コンテナのビルド、再起動
コンテナを再ビルドします。
通常のビルドではキャッシュが効いてしまうので、--no-cache
を付けて明示的にキャッシュを使用せずにビルドをします。
# コンテナビルド
docker compose build --no-cache
# コンテナ起動
docker compose up -d
4. アプリケーションのバージョンアップ
実行環境のGoのバージョンを上げたので、アプリケーションのバージョンを上げます。
以前はgo.modファイルのバージョンを書き換え、requireを全消ししてgo mod tidy
していましたが、
バージョンの更新や依存関係の更新用のコマンドがちゃんと用意されています。
go.mod
-
Goバージョンの更新
go mod edit -go=1.22.5
go.modに記載されているバージョン部分が変更されます。
-
依存関係の更新
go get -u ./...
go get -u
でgo.mod内のすべてのアップグレードができます。
個別に特定のパッケージのみアップグレードしたい場合は、
go get {パッケージ}
とすることで1つずつアップグレードできます。 -
コンパイルエラーの確認
go build ./...
vscode等のエディタであればエラー箇所がわかるので事前に確認できるでしょう。
コマンドで確認する場合はビルドでエラーが出てくれるでしょう。
5. ローカル環境アップグレード(Mac)
ローカルマシン上で開発する場合の環境のアップグレード方法について解説します。
-
homebrewの場合
brew upgrade brew upgrade go
-
goコマンドの場合
go install golang.org/dl/go1.22.5@latest ~/go/bin/go1.22.5 download
通常のgoコマンドでは従来からインストールされているバージョンのgoが動作します。[1]
go install
でインストールしたgoを実行するためには以下のようにバージョン付きのコマンドで実行します。
~/go/bin/go version → 1.19.5が出力 ~/go/bin/go1.22.5 version → 1.22.5が出力
コマンドが長くなるため、ちょっと手間です。
以下のようにGOROOTを差し替えると通常のgoコマンドで実行できそうexport GOROOT=`~/go/bin/go1.22.5 env GOROOT` export PATH=$GOROOT/bin:$PATH go version go version go1.22.5 darwin/arm64
参考情報
Goの複数バージョンのインストールについて
go.mod関係
goの互換性について
リリースバージョン情報
-
複数のGoバージョンのインストールの詳細は公式のドキュメントを参考にしてください。
https://go.dev/doc/manage-install#installing-multiple ↩︎
Discussion