title: “Reduce Image Footprint with Mulit-Stage”
date: 2020-12-13T20:14:19
slug: reduce-image-footprint-with-mulit-stage
Use multi-stage builds
With multi-stage builds, you use multiple FROM statements in your Dockerfile. Each FROM instruction can use a different base, and each of them begins a new stage of the build. You can selectively copy artifacts from one stage to another, leaving behind everything you don’t want in the final image. To show how this works, let’s adapt the Dockerfile from the previous section to use multi-stage builds.
Dockerfile:
# build container stage 1
FROM ubuntu
ARG DEBIAN\_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y golang-go
COPY app.go .
RUN CGO\_ENABLED=0 go build app.go
# app container stage 2
FROM alpine
COPY --from=0 /app .
CMD ["./app"]
Use specific Versions:
# build container stage 1
FROM ubuntu
ARG DEBIAN\_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y golang-go
COPY app.go .
RUN CGO\_ENABLED=0 go build app.go
# app container stage 2
FROM alpine:3.11.6
COPY --from=0 /app .
CMD ["./app"]
Dont run as root
# build container stage 1
FROM ubuntu:20.04
ARG DEBIAN\_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y golang-go=2:1.13~1ubuntu2
COPY app.go .
RUN pwd
RUN CGO\_ENABLED=0 go build app.go
# app container stage 2
FROM alpine:3.12.0
RUN addgroup -S appgroup && adduser -S appuser -G appgroup -h /home/appuser
COPY --from=0 /app /home/appuser/
USER appuser
CMD ["/home/appuser/app"]
Make File Systems Read only (chmod a-w /etc)
# build container stage 1
FROM ubuntu:20.04
ARG DEBIAN\_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y golang-go=2:1.13~1ubuntu2
COPY app.go .
RUN pwd
RUN CGO\_ENABLED=0 go build app.go
# app container stage 2
FROM alpine:3.12.0
RUN chmod a-r /etc
RUN addgroup -S appgroup && adduser -S appuser -G appgroup -h /home/appuser
COPY --from=0 /app /home/appuser/
USER appuser
CMD ["/home/appuser/app"]
Remove Shell Access
# build container stage 1
FROM ubuntu:20.04
ARG DEBIAN\_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y golang-go=2:1.13~1ubuntu2
COPY app.go .
RUN pwd
RUN CGO\_ENABLED=0 go build app.go
# app container stage 2
FROM alpine:3.12.0
RUN addgroup -S appgroup && adduser -S appuser -G appgroup -h /home/appuser
RUN rm -rf /bin/\*
COPY --from=0 /app /home/appuser/
USER appuser
CMD ["/home/appuser/app"]
