初めに
筆者はDocker初心者であんまりDockerについて理解してません。ご了承ください
結論
必要なファイルは実行用コンテナにもコピーしよう
COPY --from=builder /app/config ./config
経緯
- あるプロジェクトでgoの環境を作る必要があった
- 容量が1GB近くとかなり大きいイメージだった
- CI/CDを意識すると容量を削減したいと考えていました
マルチステージビルド
調べていく中でマルチステージビルドというものがあるのを発見
これを使おうとしました
existed(0)の症状
- マルチステージビルドを使わない環境だと立ち上がる
FROM golang:1.20-alpine
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o /main ./cmd
- マルチステージビルド環境で立ち上がらない
FROM golang:1.20-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o /main ./cmd
FROM gcr.io/distroless/base-debian12
WORKDIR /app
COPY --from=builder /main .
EXPOSE 8080
CMD [ "./main" ]
マルチステージビルド環境って実行ファイルしかないやんけ!!
そうです
ビルドステージ環境ではCOPY行で全てをコピーしてきてるので自分のpcのディレクトリ構造とまんま同じです
しかし、マルチステージ環境は言わばまっさらなのでコピーしてこないと存在しません
問題の箇所
- main.go内部でenvを読み込んでいた
main.go
package main
func main() {
err := godotenv.Load(fmt.Sprintf("config/%s.env", env))
if err != nil {
return
}
}
最終的なDockerファイル
FROM golang:1.20-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o /main ./cmd
FROM gcr.io/distroless/base-debian12
WORKDIR /app
COPY --from=builder /main .
COPY --from=builder /app/config ./config
EXPOSE 8080
CMD [ "./main" ]
所感
誰もenvを読み取り開発用と本番用で分けることをしていなかったのかなかなか真実にたどりつきませんでした