レイヤ¶
Dockerfile 命令の順番は重要です。Docker は構築命令の順番に従い、構築を構成します。Dockerfile 内の各命令は、
キャッシュされたレイヤ¶
構築を実行するとき、
前のセクションにある Dockerfile は、全てのプロジェクトファイルをコンテナにコピーします( COPY . . )。それから、続くステップでアプリケーションの依存関係をダウンロードします( RUN go mod download )。プロジェクトのファイルに変更があれば、 COPY レイヤのキャッシュが無効になります。また、以降に続く、全てのレイヤに対するキャッシュも無効になります。
現在の Dockerfile にある命令の順番では、ビルダは Go モジュールをダウンロードする必要があります。前回の構築時からパッケージは何も変わっていないのにもかかわらずです。
命令の順番を変える¶
Dockerfile 内の命令の順番を変えれば、この余計な冗長性を避けられます。ソースコードをコンテナへと渡す前に、ダウンロードと依存関係のインストールをするように命令の順番を変えます。この方法により、ソースコードに変更があったとしても、ビルダがキャッシュから「依存関係」のレイヤを再利用できるようになります。
Go は go.mod と go.sum と呼ばれる2つのファイルを使い、プロジェクトの依存関係を追跡します。これらのファイルは Go にとって、JavaScript における package.json と package-lock.json にあたります。Go がダウンロードすべき依存関係を分かるようにするには、 go.mod と go.sum ファイルをコンテナ内にコピーする必要があります。 RUN go mod download の前に、今回は go.mod と go.sum ファイルのみコピーする別の COPY 命令を追加します。
# syntax=docker/dockerfile:1
FROM golang:{{site.example_go_version}}-alpine
WORKDIR /src
- COPY . .
+ COPY go.mod go.sum .
RUN go mod download
+ COPY . .
RUN go build -o /bin/client ./cmd/client
RUN go build -o /bin/server ./cmd/server
ENTRYPOINT [ "/bin/server" ]
これでアプリケーションのコードを変更したとしても、イメージの構築時に毎回ビルダが依存関係をダウンロードしなくなります。 COPY . . 命令はパッケージ管理命令の後にあるため、ビルダは RUN go mod download レイヤを再利用できます。