Benefits:

– Smaller footprints of exposed containers
– Less attack surfaces leads to minimum vulnerabilities
– Job security, heheh. Nope, this convoluted build process really is part of best-practices
– Less storage requirements when pruned

Illustration:
  Linux Host Staging
Container
Production
Container

Mount points

/go/src/project/

/app

/bin/project/ /app
Comments Persistent directories to survive containers regeneration Container and dependencies are to be destroyed after artifacts are produced Copy only artifacts needed into the final image. Exposed at port 80
Sample App:
# Intermediary container section
FROM golang:1.11-alpine AS staging #Name this compiling container as 'staging'

# Add certs
RUN apk --update add ca-certificates

# Install tools required for project
# Run `docker build --no-cache .` to update dependencies
RUN apk add --no-cache git
RUN go get github.com/golang/dep/cmd/dep

# List project dependencies with Gopkg.toml and Gopkg.lock
COPY Gopkg.lock Gopkg.toml /go/src/project/ #This layer will trigger a rebuild when Gopkg files are updated

# Set working directory as a directory on the host for persistency
WORKDIR /go/src/project/

# Install library dependencies
RUN dep ensure -vendor-only

# Copy all files from current directory into project folder
COPY . /go/src/project/ #This layer will trigger a rebuild if any file is changed in the project directory

# Execute the build (compile) command
RUN go build -o /bin/project

# Final container section: pull a minimalistic 'Alpine' image
FROM alpine

# Update without keeping cache files to save space
RUN apk --no-cache update

# The default Alpine image doesn't have certs - add them
# Alternative: RUN apk add ca-certificates && rm -rf /var/cache/apk/*
COPY --from=staging /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt

# Set new working directory
WORKDIR /app

# Copy files from staging folder to this Production /app directory
COPY --from=staging /bin/project /app

EXPOSE 80
ENTRYPOINT ./goapp