Hello to all the readers!

Docker image is built in layers. Each instruction that is written in Dockerfile translates into an image layer by the builder.

When the image is re-built, builder will re-use layers from earlier builds. If any layer is unchanged, then that layer is picked up from the build cache.

However, if a layer has changed since last build, then that layer and all layers that follow it are also rebuilt.

Let us consider an example:

  FROM golang:1.20-alpine
  WORKDIR /src
  COPY . .
  RUN go mod download
  RUN go build -o /bin/client ./cmd/client
  RUN go build -o /bin/server ./cmd/server
  ENTRYPOINT [ "/bin/server" ]

In this Dockerfile, the project repository is copied and then go modules are downloaded. If any file in project changes, then COPY layer will change and thereby go modules will be downloaded again. Although no module has changed but still it spends time downloading them.

Therefore, we should change above Dockerfile instructions to a better form.

  FROM golang:1.20-alpine
  WORKDIR /src
  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" ]

This time, we have copied go.mod and go.sum that track project dependencies. And then downloaded go modules and then copied project repository inside container.

Now if a file is changed in the repo, go modules won’t be downloaded again and that layer will be reused. This saves build time.

Similar Posts

Error: GraphComment couldn't be load because your settings are invalid. Please visit your admin panel and go to the GraphComment section and enter a valid website URL/ID.