Order by rate of change
From low frequency of change at the top
To high frequency of change at the bottom
OS packages
Language dependencies
Code and other files
–
Create base image
Derive specialized images
Base image with OS packages
Derived image with language dependencies
Derived image with code
–
One image for build environment
Another image for runtime environment
Build environment will be large
Runtime environment should be small
–
Create stages for independent steps
Fan-in
Prepare base image
Install tools in parallel
Merge in final image
–
Use image build for isolation
Write build output to host
https://github.com/chris-crone/containerized-go-dev
–
All developers should use the correct/same build tooling
Add dependency file explicitly
Code changes will not effect download
FROM golang AS base
COPY go.* .
RUN go mod download
FROM base AS build
#...
–
All developers should use the correct/same build tooling
Building an image is a non-goal
Dockerfile
as declarative description of build process
–
All developers should use the correct/same build tooling
No need for duplication
Use the same sources
FROM base AS build
RUN --mount=target=. \
go build .
–
All developers should use the correct/same build tooling
Define targets for…
Build
Test
Lint
etc.
–
All developers should use the correct/same build tooling
Build targets can be used in Makefile (or similar)
bin/example:
@docker build . --target bin --output bin
.PHONY: unit-test
unit-test:
@docker build . --target unit-test
.PHONY: lint
lint:
@docker build . --target lint