Skip to content

Secure Dockerfile

Container

FROM alpine:3.3 (1)

ENV VERSION 1.11.2
ENV SHA256 8c2e0c35e3cda11706f54b2d46c2521a6e9026a7b13c7d4b8ae1f3a706fc55e1 (2)

WORKDIR /usr/bin

RUN apk update && \
         apk upgrade && \ (3)
         apk --update add coreutils wget ca-certificates && \
         wget https://get.docker.com/builds/Linux/x86_64/docker-$VERSION.tgz && \
         wget https://get.docker.com/builds/Linux/x86_64/docker-$VERSION.tgz.sha256 && \
         sha256sum -c docker-$VERSION.tgz.sha256 && \ (4)
         echo "$SHA256 docker-$VERSION.tgz" | sha256sum -c - && \ (4)
         tar -xzvf docker-$VERSION.tgz -C /tmp && \
         mv /tmp/docker/docker . && \
         chmod u+x docker* && \
         rm -rf /tmp/docker* && \ (5)
         apk del wget ca-certificates && \ (5)
         rm -rf /var/cache/apk/* docker-$VERSION.tgz docker-$VERSION.tgz.sha256 (5)

COPY ./docker-garby.sh /docker-garby.sh (6)

RUN useradd -d /home/<username> -m -s /bin/bash <username> (7)
USER <username> (7)

ENTRYPOINT ["/bin/sh", "/docker-garby.sh"]
  1. Do we trust the remote repository? Is there any reason we’re not using a homebuilt base image?
  2. Hash to verify downloaded file
  3. Keep the container up-to-date
  4. Verify downloaded files
  5. Remove unused applications and unnecessary directories
  6. COPY local files, ADD remote files
  7. Create an unprivileged USER if possible
  8. GnuPG sign the commit, git -s -S -m '...'

Image

FROM scratch (1)
ADD ./wheezy-1603172157.txz / (2)
ENV SHA 00c3cc1b8968d3b5acf2ac9fc1e36f2aa30dfd4ff44a35d8d3bd1948914d722d (3)

ONBUILD RUN apt-get update && apt-get -y upgrade (4)
  1. Use scratch
  2. Add a compressed, minimal, base
  3. Hash for the above base
  4. Force containers based on this image to keep up-to-date
  5. GnuPG sign the commit, git -s -S -m '...'