概要
本日は、ローカルでGoのファイルを実行した際に立ち上がりに時間がかかっており、
それを効率化する方法を見つけましたので共有したいと思います。
環境
今回もDockerを利用したいと思います。
FROM golang:1.20-alpine3.16
ENV ROOT /app \
TZ Asia/Tokyo
WORKDIR ${ROOT}
RUN apk update && apk add --no-cache git
COPY go.mod go.sum ./
RUN go mod download
COPY . .
EXPOSE 8080
CMD ["go", "run", "main.go"]
version: '3.8'
services:
db:
image: mysql:8.0
container_name: mysql
env_file:
- .env
environment:
MYSQL_ROOT_PASSWORD: $DB_ROOT_PASSWORD
MYSQL_DATABASE: $DB_NAME
MYSQL_USER: $DB_USER
MYSQL_PASSWORD: $DB_PASSWORD
volumes:
- ./mysql:/var/lib/mysql
ports:
- 3306:3306
api:
build: .
container_name: api
working_dir: /app
env_file:
- .env
environment:
APP_ENV: $APP_ENV
TZ: "Asia/Tokyo"
volumes:
- .:/app
ports:
- 8080:8080
depends_on:
- db
問題
ローカルで開発している際に、ファイルをgo run ファイル名で実行することがよくあると思います。
その際に下記にようにソースからパッケージを都度ダウンロードするため、実行に時間がかかっていました。
$ docker compose run --rm api go run main.go
[+] Running 1/0
⠿ Container mysql Running 0.0s
go: downloading github.com/sirupsen/logrus v1.9.0
go: downloading gorm.io/driver/mysql v1.4.6
go: downloading gorm.io/gorm v1.24.5
go: downloading github.com/gin-gonic/gin v1.8.2
go: downloading github.com/go-sql-driver/mysql v1.7.0
go: downloading golang.org/x/sys v0.3.0
go: downloading github.com/jinzhu/now v1.1.5
go: downloading github.com/jinzhu/inflection v1.0.0
go: downloading github.com/gin-contrib/sse v0.1.0
go: downloading github.com/mattn/go-isatty v0.0.16
go: downloading golang.org/x/net v0.4.0
go: downloading github.com/go-playground/validator/v10 v10.11.1
go: downloading github.com/pelletier/go-toml/v2 v2.0.6
go: downloading github.com/ugorji/go/codec v1.2.7
go: downloading google.golang.org/protobuf v1.28.1
go: downloading gopkg.in/yaml.v2 v2.4.0
go: downloading github.com/go-playground/universal-translator v0.18.0
go: downloading github.com/leodido/go-urn v1.2.1
go: downloading golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3
go: downloading golang.org/x/text v0.5.0
go: downloading github.com/go-playground/locales v0.14.0
これでは外部パッケージが増えれば増えるほど実行するのに時間がかかってしまいます。
対処法
何か良い方法はないかと模索したところ、go mod vendorというコマンドを見つけました。
公式ドキュメントには上記コマンドについて、下記のように記載されています。
The go mod vendor command constructs a directory named vendor in the main module’s root directory that contains copies of all packages needed to support builds and tests of packages in the main module.
…省略
When vendoring is enabled, the go command will load packages from the vendor directory instead of downloading modules from their sources into the module cache and using packages those downloaded copies.
日本語訳
go mod vendorコマンドは、メインモジュールのルートディレクトリにvendorというディレクトリを作成し、そこにメインモジュール内のパッケージのビルドとテストをサポートするために必要なすべてのパッケージのコピーを格納します。
…省略
vendoring が有効な場合、goコマンドはモジュールをソースからモジュールキャッシュにダウンロードし、それらのダウンロードしたコピーを使用する代わりに、ベンダディレクトリからパッケージをロードします。
つまり実行時にパッケージをソースからダウンロードを行うのではなく、
vendorディレクトリにキャッシュされたパッケージをロードし利用するということです。
よって都度ソースからダウンロードをしなくてよくなるので実行する際の時間がかなり短縮されます!
注意点
vendorディレクトリは必要なパッケージを格納していますが、
新たにパッケージを追加した際はその都度go mod vendorコマンドを実行しないと
追加したパッケージがvendorディレクトリに格納されないので注意です。
まとめ
いかがだったでしょうか。
ローカルで開発する際はgo mod vendorコマンドを利用することで
ファイルの実行時間を短縮することができますので是非皆さんも試してみてください。
最後まで読んでいただきありがとうございました!