SlideShare a Scribd company logo
1 of 69
Download to read offline
Tibor Vass
Docker, Inc.
Dockerfile Best Practices
Sebastiaan van Stijn
Docker, Inc.
@tiborvass @thaJeztah
Dockerfile
Blueprint to build Docker images
Popular: 1+ million Dockerfiles on GitHub
Concurrency, lazy context upload,
better caching, new Dockerfile features, ...
BuildKit: builder v2
Windows supportcoming soon
Use latest Docker, enable BuildKit today!
Docker client:
export DOCKER_BUILDKIT=1
Or, Docker daemon config:
{
"features": {"buildkit": true}
}
https://docs.docker.com/engine/reference/builder/
Improving Dockerfiles
- (Incremental) build time
- Image size
- Maintainability
- Security
- Consistency/Repeatability
Areas of improvements
-rw-r--r-- 1 656 Dec 4 12:20 Dockerfile
drwxr-xr-x 2 6.1M Dec 4 09:44 docs/
-rw-r--r-- 1 1.7K Dec 3 09:48 pom.xml
-rw-r--r-- 1 1.0K Dec 4 10:12 README.md
drwxr-xr-x 4 44K Dec 3 09:48 src/
drwxr-xr-x 2 17M Dec 4 09:50 target/
Basic Java Spring Hello world web app
Example project
FROM debian
COPY . /app
RUN apt-get update
RUN apt-get -y install openjdk-8-jdk ssh emacs
CMD ["java", "-jar", "/app/target/app.jar"]
Let’s improve this Dockerfile
Let’s improve this Dockerfile
FROM debian
COPY . /app
RUN apt-get update
RUN apt-get -y install openjdk-8-jdk ssh emacs vim
CMD ["java", "-jar", "/app/target/app.jar"]
Make build cache your friend
Incremental build time
Order matters for caching
FROM debian
COPY . /app
RUN apt-get update
RUN apt-get -y install openjdk-8-jdk ssh vim
COPY . /app
CMD ["java", "-jar", "/app/target/app.jar"]
Order from least to most frequently changing content.
More specific COPY to limit cache busts
FROM debian
RUN apt-get update
RUN apt-get -y install openjdk-8-jdk ssh vim
COPY . /app
COPY target/app.jar /app
CMD ["java", "-jar", "/app/target/app.jar"]
Only copy what's needed. Avoid "COPY ." if possible
Line buddies: apt-get update & install
FROM debian
RUN apt-get update
RUN apt-get -y install openjdk-8-jdk ssh vim
RUN apt-get update 
&& apt-get -y install 
openjdk-8-jdk ssh vim
COPY target/app.jar /app
CMD ["java", "-jar", "/app/app.jar"]
Prevents using an outdated package cache
Reduce image size
Faster deploys, smaller attack surface
Remove unnecessary dependencies
FROM debian
RUN apt-get update 
&& apt-get -y install --no-install-recommends 
openjdk-8-jdk ssh vim
COPY target/app.jar /app
CMD ["java", "-jar", "/app/app.jar"]
Remove package manager cache
FROM debian
RUN apt-get update 
&& apt-get -y install --no-install-recommends 
openjdk-8-jdk 
&& rm -rf /var/lib/apt/lists/*
COPY target/app.jar /app
CMD ["java", "-jar", "/app/app.jar"]
Remove package manager cache
FROM debian
RUN apt-get update 
&& apt-get -y install --no-install-recommends 
openjdk-8-jdk 
&& rm -rf /var/lib/apt/lists/*
COPY target/app.jar /app
CMD ["java", "-jar", "/app/app.jar"]
Maintainability
Use official images where possible
- Reduce time spent on maintenance
(frequently updated with fixes)
- Reduce size (shared layers between images)
- Pre-configured for container use
- Built by smart people
Use official images when possible
FROM debian
RUN apt-get update 
&& apt-get -y install --no-install-recommends 
openjdk-8-jdk
&& rm -rf /var/lib/apt/lists/*
FROM openjdk
COPY target/app.jar /app
CMD ["java", "-jar", "/app/app.jar"]
Use more specific tags
FROM openjdk:latest
FROM openjdk:8
COPY target/app.jar /app
CMD ["java", "-jar", "/app/app.jar"]
The "latest" tag is a rolling tag. Be specific, to prevent
unexpected changes in your base image.
Pick your variant
Read the image's documentation on
Docker Hub
https://hub.docker.com/_/openjdk
Look for minimal flavors
REPOSITORY TAG SIZE
openjdk 8 624MB
openjdk 8-jre 443MB
openjdk 8-jre-slim 204MB
openjdk 8-jre-alpine 83MB
Just using a different base image reduced the image
size by 540 MB
The Dockerfile as blueprint,
source code the source of truth
Reproducibility
Build from source in a consistent environment
Make the Dockerfile your blueprint:
- It describes the build environment
- Correct versions of build tools installed
- Prevent inconsistencies between environments
- There may be system dependencies
- The "source of truth" is the source code, not the build artifact
Build from source in a consistent environment
FROM openjdk:8-jre-alpine
FROM maven:3.6-jdk-8-alpine
WORKDIR /app
COPY app.jar /app
COPY pom.xml .
COPY src ./src
RUN mvn -e -B package
CMD ["java", "-jar", "/app/app.jar"]
FROM maven:3.6-jdk-8-alpine
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn -e -B package
CMD ["java", "-jar", "/app/app.jar"]
Build from source in a consistent environment
FROM maven:3.6-jdk-8-alpine
WORKDIR /app
COPY pom.xml .
RUN mvn -e -B dependency:resolve
COPY src ./src
RUN mvn -e -B package
CMD ["java", "-jar", "/app/app.jar"]
Fetch dependencies in a separate step
Identify build dependencies
FROM maven:3.6-jdk-8-alpine
WORKDIR /app
COPY pom.xml .
RUN mvn -e -B dependency:resolve
COPY src ./src
RUN mvn -e -B package
CMD ["java", "-jar", "/app/app.jar"]
FROM maven:3.6-jdk-8-alpine AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn -e -B dependency:resolve
COPY src ./src
RUN mvn -e -B package
CMD ["java", "-jar", "/app/app.jar"]
FROM openjdk:8-jre-alpine
COPY --from=builder /app/target/app.jar /
CMD ["java", "-jar", "/app.jar"]
Multi-stage builds to remove build deps
FROM maven:3.6-jdk-8-alpine AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn -e -B dependency:resolve
COPY src ./src
RUN mvn -e -B package
FROM openjdk:8-jre-alpine
COPY --from=builder /app/target/app.jar /
CMD ["java", "-jar", "/app.jar"]
Multi-stage builds to remove build deps
Not just for reducing image size
Multi-stage Dockerfiles
- Moby: 16 stages
https://github.com/moby/moby/blob/master/Dockerfile
- BuildKit: 44 stages
https://github.com/moby/buildkit/blob/master/hack/d
ockerfiles/test.buildkit.Dockerfile
Projects with many stages
- Separate build from runtime environment
(shrinking image size)
- Slight variations on images (DRY)
- Build/dev/test/lint/... specific environments
- Delinearizing your dependencies (concurrency)
- Platform-specific stages
Multi-stage use cases
FROM image_or_stage AS stage_name
…
$ docker build --target stage_name
Building specific stages with --target
FROM maven:3.6-jdk-8-alpine AS builder
...
FROM openjdk:8-jre-jessie AS release-jessie
COPY --from=builder /app/target/app.jar /
CMD ["java", "-jar", "/app.jar"]
FROM openjdk:8-jre-alpine AS release-alpine
COPY --from=builder /app/target/app.jar /
CMD ["java", "-jar", "/app.jar"]
$ docker build --target release-jessie .
Different image flavors
FROM maven:3.6-jdk-8-alpine AS builder
...
FROM openjdk:8-jre-jessie AS release-jessie
COPY --from=builder /app/target/app.jar /
CMD ["java", "-jar", "/app.jar"]
FROM openjdk:8-jre-alpine AS release-alpine
COPY --from=builder /app/target/app.jar /
CMD ["java", "-jar", "/app.jar"]
$ docker build --target release-jessie .
Different image flavors
FROM maven:3.6-jdk-8-alpine AS builder
...
FROM openjdk:8-jre-jessie AS release-jessie
COPY --from=builder /app/target/app.jar /
CMD ["java", "-jar", "/app.jar"]
FROM openjdk:8-jre-alpine AS release-alpine
COPY --from=builder /app/target/app.jar /
CMD ["java", "-jar", "/app.jar"]
$ docker build --target release-jessie .
Different image flavors
ARG flavor=alpine
FROM maven:3.6-jdk-8-alpine AS builder
...
FROM openjdk:8-jre-$flavor AS release
COPY --from=builder /app/target/app.jar /
CMD ["java", "-jar", "/app.jar"]
$ docker build --target release
--build-arg flavor=jessie .
Different image flavors (DRY / global ARG)
Examples of possible stage layout:
- builder: all build dependencies
- build (or binary): builder + built artifacts
- cross: same as build but for multiple platforms
- dev: build(er) + dev/debug tools
- lint: minimal lint dependencies
- test: all test dependencies + build artifacts to be tested
- release: final minimal image with build artifacts
Various environments: build, dev, test, lint, ...
FROM maven:3.6-jdk-8-alpine AS builder
...
FROM openjdk:8-jre-alpine AS lint
RUN wget https://github.com/checkstyle/checkstyle/releases/download/checkstyle-8.15/checkstyle-8.15-all.jar
COPY checks.xml .
COPY src /src
RUN java -jar checkstyle-8.15-all.jar -c checks.xml /src
Various environments: build, dev, test, lint, ...
FROM maven:3.6-jdk-8-alpine AS builder
...
FROM openjdk:8-jre-alpine AS release
COPY --from=builder /app/target/app.jar /
CMD ["java", "-jar", "/app.jar"]
FROM builder AS dev
RUN apk add --no-cache strace vim tcpdump
ENTRYPOINT ["ash"]
Various environments: build, dev, test, lint, ...
FROM maven:3.6-jdk-8-alpine AS builder
...
RUN mvn -e -B package -DskipTests
FROM builder AS unit-test
RUN mvn -e -B test
FROM release AS integration-test
RUN apk add --no-cache curl
RUN ./test/run.sh
Various environments: build, dev, test, lint, ...
- all stages are executed in sequence
- without BuildKit, unneeded stages
are unnecessarily executed but
discarded
From linear Dockerfile stages ...
… to multi-stage graphs with BuildKit
- BuildKit traverses from bottom
(stage name from --target ) to
top
… to multi-stage graphs with BuildKit
- BuildKit traverses from bottom
(stage name from --target ) to
top
- Unneeded stages are not even
considered
FROM maven:3.6-jdk-8-alpine AS builder
...
FROM tiborvass/whalesay AS assets
RUN whalesay "Hello DockerCon!" > /out/assets.html
FROM openjdk:8-jre-alpine AS release
COPY --from=builder /app/app.jar /
COPY --from=assets /out /assets
CMD ["java", "-jar", "/app.jar"]
Multi-stage: build concurrently
FROM maven:3.6-jdk-8-alpine AS builder-base
…
FROM gcc:8-alpine AS builder-someClib
…
RUN git clone … 
./configure --prefix=/out && make && make install
FROM g++:8-alpine AS builder-someCPPlib
…
RUN git clone … 
cmake …
FROM builder-base AS builder
COPY --from=builder-someClib /out /
COPY --from=builder-someCPPlib /out /
…
Multi-stage: build concurrently
Concurrency pattern:
multiple
COPY --from ...
COPY --from ...
Benchmarks
Based on github.com/moby/moby Dockerfile, master branch. Smaller is better.
Time for full build from empty state
2.0x
faster
Benchmarks
Based on github.com/moby/moby Dockerfile, master branch. Smaller is better.
Repeated build with matching cache
7.2x
faster
Benchmarks
Based on github.com/moby/moby Dockerfile, master branch. Smaller is better.
Repeated build with new source code
2.5x
faster
New Dockerfile features
Enabling new features
Experimental as in, not in
mainline Dockerfile syntax.
The 1.0-experimental image
will not break in the future.
# syntax=docker/dockerfile:1.0-experimental
FROM maven:3.6-jdk-8-alpine AS builder
WORKDIR /app
COPY . /app
RUN mvn -e -B package
FROM openjdk:8-jre-alpine
COPY --from=builder /app/app.jar /
CMD ["java", "-jar", "/app.jar"]
For more details: docs/experimental-syntaxes.md
https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md
Context mounts (v18.09+ w/ BuildKit)
# syntax=docker/dockerfile:1.0-experimental
FROM maven:3.6-jdk-8-alpine AS builder
WORKDIR /app
COPY . /app
RUN --mount=target=. mvn -e -B package -DoutputDirectory=/
FROM openjdk:8-jre-alpine
COPY --from=builder /app/app.jar /
CMD ["java", "-jar", "/app.jar"]
Context mounts (v18.09+ w/ BuildKit)
# syntax=docker/dockerfile:1.0-experimental
FROM maven:3.6-jdk-8-alpine AS builder
WORKDIR /app
RUN --mount=target=. mvn -e -B package -DoutputDirectory=/
FROM openjdk:8-jre-alpine
COPY --from=builder /app.jar /
CMD ["java", "-jar", "/app.jar"]
Cache dependencies (before BuildKit)
FROM maven:3.6-jdk-8-alpine
WORKDIR /app
COPY pom.xml .
RUN mvn -e -B dependency:resolve
COPY src ./src
RUN mvn -e -B package
CMD ["java", "-jar", "/app/app.jar"]
Application cache (v18.09+ w/ BuildKit)
# syntax=docker/dockerfile:1.0-experimental
FROM maven:3.6-jdk-8-alpine AS builder
WORKDIR /app
RUN --mount=target=. --mount=type=cache,target=/root/.m2 
&& mvn package -DoutputDirectory=/
FROM openjdk:8-jre-alpine
COPY --from=builder /app.jar /
CMD ["java", "/app.jar"]
apt: /var/lib/apt/lists
go: ~/.cache/go-build
go-modules: $GOPATH/pkg/mod
npm: ~/.npm
pip: ~/.cache/pip
FROM baseimage
RUN ...
ENV AWS_ACCESS_KEY_ID=...
ENV AWS_SECRET_ACCESS_KEY=...
RUN ./fetch-assets-from-s3.sh
RUN ./build-scripts.sh
Secrets (DON’T DO THIS)
FROM baseimage
RUN ...
ARG AWS_ACCESS_KEY_ID
ARG AWS_SECRET_ACCESS_KEY
RUN ./fetch-assets-from-s3.sh
RUN ./build-scripts.sh
$ docker build --build-arg 
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID … .
Secrets (DON’T DO THIS EITHER)
docker history
# syntax=docker/dockerfile:1-experimental
FROM baseimage
RUN ...
RUN --mount=type=secret,id=aws,target=/root/.aws/credentials
,required ./fetch-assets-from-s3.sh
RUN ./build-scripts.sh
$ docker build --secret id=aws,src=~/.aws/credentials .
Secrets (DO THIS, v18.09+ w/ BuildKit)
FROM baseimage
COPY ./keys/private.pem /root/.ssh/private.pem
ARG REPO_REF=19ba7bcd9976ef8a9bd086187df19ba7bcd997f2
RUN git clone git@github.com:org/repo /work && cd /work 
&& git checkout -b $REPO_REF
Private git repos (DON’T DO THIS)
FROM alpine
RUN apk add --no-cache openssh-client
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >>
~/.ssh/known_hosts
ARG REPO_REF=19ba7bcd9976ef8a9bd086187df19ba7bcd997f2
RUN --mount=type=ssh,required 
git clone git@github.com:org/repo /work && cd /work 
&& git checkout -b $REPO_REF
$ eval $(ssh-agent)
$ ssh-add ~/.ssh/id_rsa
$ docker build --ssh=default .
Private git repos (DO THIS, v18.09+ w/ BuildKit)
We went from:
- inconsistent build/dev/test environments
- bloated image
- slow build and incremental build times (cache busts)
- building insecurely
To:
- consistent build/dev/test environments
- minimal image
- very fast build and incremental build times
- building more securely
Improvements recap
Read more on blog posts
https://medium.com/@tonistiigi/advanced-mult
i-stage-build-patterns-6f741b852fae
https://medium.com/@tonistiigi/build-secrets-and-s
sh-forwarding-in-docker-18-09-ae8161d066
• Multi-stage, multi-stage, multi-stage
• DOCKER_BUILDKIT=1
OSS Summit: Advanced BuildKit
sessions on Thursday, May 2 at 12:30pm
in room 2020
Thank you!
Follow us @tiborvass @thaJeztah

More Related Content

What's hot

Docker Tutorial For Beginners | What Is Docker And How It Works? | Docker Tut...
Docker Tutorial For Beginners | What Is Docker And How It Works? | Docker Tut...Docker Tutorial For Beginners | What Is Docker And How It Works? | Docker Tut...
Docker Tutorial For Beginners | What Is Docker And How It Works? | Docker Tut...
Simplilearn
 
Docker 101: Introduction to Docker
Docker 101: Introduction to DockerDocker 101: Introduction to Docker
Docker 101: Introduction to Docker
Docker, Inc.
 

What's hot (20)

Docker by Example - Basics
Docker by Example - Basics Docker by Example - Basics
Docker by Example - Basics
 
Docker Introduction
Docker IntroductionDocker Introduction
Docker Introduction
 
Introduction to Docker
Introduction to DockerIntroduction to Docker
Introduction to Docker
 
Docker Tutorial For Beginners | What Is Docker And How It Works? | Docker Tut...
Docker Tutorial For Beginners | What Is Docker And How It Works? | Docker Tut...Docker Tutorial For Beginners | What Is Docker And How It Works? | Docker Tut...
Docker Tutorial For Beginners | What Is Docker And How It Works? | Docker Tut...
 
Docker: From Zero to Hero
Docker: From Zero to HeroDocker: From Zero to Hero
Docker: From Zero to Hero
 
Midi technique - présentation docker
Midi technique - présentation dockerMidi technique - présentation docker
Midi technique - présentation docker
 
What is Docker
What is DockerWhat is Docker
What is Docker
 
From Zero to Docker
From Zero to DockerFrom Zero to Docker
From Zero to Docker
 
Docker, Docker Compose and Docker Swarm
Docker, Docker Compose and Docker SwarmDocker, Docker Compose and Docker Swarm
Docker, Docker Compose and Docker Swarm
 
Docker Basics
Docker BasicsDocker Basics
Docker Basics
 
Docker introduction (1)
Docker introduction (1)Docker introduction (1)
Docker introduction (1)
 
Dockers and containers basics
Dockers and containers basicsDockers and containers basics
Dockers and containers basics
 
도커 무작정 따라하기: 도커가 처음인 사람도 60분이면 웹 서버를 올릴 수 있습니다!
도커 무작정 따라하기: 도커가 처음인 사람도 60분이면 웹 서버를 올릴 수 있습니다!도커 무작정 따라하기: 도커가 처음인 사람도 60분이면 웹 서버를 올릴 수 있습니다!
도커 무작정 따라하기: 도커가 처음인 사람도 60분이면 웹 서버를 올릴 수 있습니다!
 
Docker 101: Introduction to Docker
Docker 101: Introduction to DockerDocker 101: Introduction to Docker
Docker 101: Introduction to Docker
 
Docker Introduction
Docker IntroductionDocker Introduction
Docker Introduction
 
Introduction to Docker Compose
Introduction to Docker ComposeIntroduction to Docker Compose
Introduction to Docker Compose
 
Introduction to docker
Introduction to dockerIntroduction to docker
Introduction to docker
 
Docker introduction & benefits
Docker introduction & benefitsDocker introduction & benefits
Docker introduction & benefits
 
Docker 101 - Nov 2016
Docker 101 - Nov 2016Docker 101 - Nov 2016
Docker 101 - Nov 2016
 
Docker 101 : Introduction to Docker and Containers
Docker 101 : Introduction to Docker and ContainersDocker 101 : Introduction to Docker and Containers
Docker 101 : Introduction to Docker and Containers
 

Similar to DCSF19 Dockerfile Best Practices

Similar to DCSF19 Dockerfile Best Practices (20)

DockerCon EU 2018 - Dockerfile Best Practices
DockerCon EU 2018 - Dockerfile Best PracticesDockerCon EU 2018 - Dockerfile Best Practices
DockerCon EU 2018 - Dockerfile Best Practices
 
DCEU 18: Dockerfile Best Practices
DCEU 18: Dockerfile Best PracticesDCEU 18: Dockerfile Best Practices
DCEU 18: Dockerfile Best Practices
 
Pluralsight Webinar: Simplify Your Project Builds with Docker
Pluralsight Webinar: Simplify Your Project Builds with DockerPluralsight Webinar: Simplify Your Project Builds with Docker
Pluralsight Webinar: Simplify Your Project Builds with Docker
 
Gdg cloud taipei ddt meetup #53 buildpack
Gdg cloud taipei ddt meetup #53 buildpackGdg cloud taipei ddt meetup #53 buildpack
Gdg cloud taipei ddt meetup #53 buildpack
 
Running Docker in Development & Production (DevSum 2015)
Running Docker in Development & Production (DevSum 2015)Running Docker in Development & Production (DevSum 2015)
Running Docker in Development & Production (DevSum 2015)
 
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...
 
Challenges of container configuration
Challenges of container configurationChallenges of container configuration
Challenges of container configuration
 
Into to Docker (Central PA Java User Group - 8/14/2017)
Into to Docker (Central PA Java User Group - 8/14/2017)Into to Docker (Central PA Java User Group - 8/14/2017)
Into to Docker (Central PA Java User Group - 8/14/2017)
 
The Dockerfile Explosion and the Need for Higher Level Tools by Gareth Rushgrove
The Dockerfile Explosion and the Need for Higher Level Tools by Gareth RushgroveThe Dockerfile Explosion and the Need for Higher Level Tools by Gareth Rushgrove
The Dockerfile Explosion and the Need for Higher Level Tools by Gareth Rushgrove
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance Toolbox
 
Vagrant or docker for java dev environment
Vagrant or docker for java dev environmentVagrant or docker for java dev environment
Vagrant or docker for java dev environment
 
Streamline your development environment with docker
Streamline your development environment with dockerStreamline your development environment with docker
Streamline your development environment with docker
 
DevOps Workflow: A Tutorial on Linux Containers
DevOps Workflow: A Tutorial on Linux ContainersDevOps Workflow: A Tutorial on Linux Containers
DevOps Workflow: A Tutorial on Linux Containers
 
Docker for developers on mac and windows
Docker for developers on mac and windowsDocker for developers on mac and windows
Docker for developers on mac and windows
 
IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...
IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...
IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...
 
Lightning talk: 12 Factor Containers
Lightning talk: 12 Factor ContainersLightning talk: 12 Factor Containers
Lightning talk: 12 Factor Containers
 
Dockerizing a Symfony2 application
Dockerizing a Symfony2 applicationDockerizing a Symfony2 application
Dockerizing a Symfony2 application
 
Docker
DockerDocker
Docker
 
Docker
DockerDocker
Docker
 
Develop with docker 2014 aug
Develop with docker 2014 augDevelop with docker 2014 aug
Develop with docker 2014 aug
 

More from Docker, Inc.

Build & Deploy Multi-Container Applications to AWS
Build & Deploy Multi-Container Applications to AWSBuild & Deploy Multi-Container Applications to AWS
Build & Deploy Multi-Container Applications to AWS
Docker, Inc.
 
Build & Deploy Multi-Container Applications to AWS
Build & Deploy Multi-Container Applications to AWSBuild & Deploy Multi-Container Applications to AWS
Build & Deploy Multi-Container Applications to AWS
Docker, Inc.
 

More from Docker, Inc. (20)

Containerize Your Game Server for the Best Multiplayer Experience
Containerize Your Game Server for the Best Multiplayer Experience Containerize Your Game Server for the Best Multiplayer Experience
Containerize Your Game Server for the Best Multiplayer Experience
 
How to Improve Your Image Builds Using Advance Docker Build
How to Improve Your Image Builds Using Advance Docker BuildHow to Improve Your Image Builds Using Advance Docker Build
How to Improve Your Image Builds Using Advance Docker Build
 
Build & Deploy Multi-Container Applications to AWS
Build & Deploy Multi-Container Applications to AWSBuild & Deploy Multi-Container Applications to AWS
Build & Deploy Multi-Container Applications to AWS
 
Securing Your Containerized Applications with NGINX
Securing Your Containerized Applications with NGINXSecuring Your Containerized Applications with NGINX
Securing Your Containerized Applications with NGINX
 
How To Build and Run Node Apps with Docker and Compose
How To Build and Run Node Apps with Docker and ComposeHow To Build and Run Node Apps with Docker and Compose
How To Build and Run Node Apps with Docker and Compose
 
Hands-on Helm
Hands-on Helm Hands-on Helm
Hands-on Helm
 
Distributed Deep Learning with Docker at Salesforce
Distributed Deep Learning with Docker at SalesforceDistributed Deep Learning with Docker at Salesforce
Distributed Deep Learning with Docker at Salesforce
 
The First 10M Pulls: Building The Official Curl Image for Docker Hub
The First 10M Pulls: Building The Official Curl Image for Docker HubThe First 10M Pulls: Building The Official Curl Image for Docker Hub
The First 10M Pulls: Building The Official Curl Image for Docker Hub
 
Monitoring in a Microservices World
Monitoring in a Microservices WorldMonitoring in a Microservices World
Monitoring in a Microservices World
 
COVID-19 in Italy: How Docker is Helping the Biggest Italian IT Company Conti...
COVID-19 in Italy: How Docker is Helping the Biggest Italian IT Company Conti...COVID-19 in Italy: How Docker is Helping the Biggest Italian IT Company Conti...
COVID-19 in Italy: How Docker is Helping the Biggest Italian IT Company Conti...
 
Predicting Space Weather with Docker
Predicting Space Weather with DockerPredicting Space Weather with Docker
Predicting Space Weather with Docker
 
Become a Docker Power User With Microsoft Visual Studio Code
Become a Docker Power User With Microsoft Visual Studio CodeBecome a Docker Power User With Microsoft Visual Studio Code
Become a Docker Power User With Microsoft Visual Studio Code
 
How to Use Mirroring and Caching to Optimize your Container Registry
How to Use Mirroring and Caching to Optimize your Container RegistryHow to Use Mirroring and Caching to Optimize your Container Registry
How to Use Mirroring and Caching to Optimize your Container Registry
 
Monolithic to Microservices + Docker = SDLC on Steroids!
Monolithic to Microservices + Docker = SDLC on Steroids!Monolithic to Microservices + Docker = SDLC on Steroids!
Monolithic to Microservices + Docker = SDLC on Steroids!
 
Kubernetes at Datadog Scale
Kubernetes at Datadog ScaleKubernetes at Datadog Scale
Kubernetes at Datadog Scale
 
Labels, Labels, Labels
Labels, Labels, Labels Labels, Labels, Labels
Labels, Labels, Labels
 
Using Docker Hub at Scale to Support Micro Focus' Delivery and Deployment Model
Using Docker Hub at Scale to Support Micro Focus' Delivery and Deployment ModelUsing Docker Hub at Scale to Support Micro Focus' Delivery and Deployment Model
Using Docker Hub at Scale to Support Micro Focus' Delivery and Deployment Model
 
Build & Deploy Multi-Container Applications to AWS
Build & Deploy Multi-Container Applications to AWSBuild & Deploy Multi-Container Applications to AWS
Build & Deploy Multi-Container Applications to AWS
 
From Fortran on the Desktop to Kubernetes in the Cloud: A Windows Migration S...
From Fortran on the Desktop to Kubernetes in the Cloud: A Windows Migration S...From Fortran on the Desktop to Kubernetes in the Cloud: A Windows Migration S...
From Fortran on the Desktop to Kubernetes in the Cloud: A Windows Migration S...
 
Developing with Docker for the Arm Architecture
Developing with Docker for the Arm ArchitectureDeveloping with Docker for the Arm Architecture
Developing with Docker for the Arm Architecture
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Recently uploaded (20)

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 

DCSF19 Dockerfile Best Practices

  • 1. Tibor Vass Docker, Inc. Dockerfile Best Practices Sebastiaan van Stijn Docker, Inc. @tiborvass @thaJeztah
  • 2. Dockerfile Blueprint to build Docker images Popular: 1+ million Dockerfiles on GitHub
  • 3. Concurrency, lazy context upload, better caching, new Dockerfile features, ... BuildKit: builder v2 Windows supportcoming soon
  • 4. Use latest Docker, enable BuildKit today! Docker client: export DOCKER_BUILDKIT=1 Or, Docker daemon config: { "features": {"buildkit": true} }
  • 7. - (Incremental) build time - Image size - Maintainability - Security - Consistency/Repeatability Areas of improvements
  • 8. -rw-r--r-- 1 656 Dec 4 12:20 Dockerfile drwxr-xr-x 2 6.1M Dec 4 09:44 docs/ -rw-r--r-- 1 1.7K Dec 3 09:48 pom.xml -rw-r--r-- 1 1.0K Dec 4 10:12 README.md drwxr-xr-x 4 44K Dec 3 09:48 src/ drwxr-xr-x 2 17M Dec 4 09:50 target/ Basic Java Spring Hello world web app Example project
  • 9. FROM debian COPY . /app RUN apt-get update RUN apt-get -y install openjdk-8-jdk ssh emacs CMD ["java", "-jar", "/app/target/app.jar"] Let’s improve this Dockerfile
  • 10. Let’s improve this Dockerfile FROM debian COPY . /app RUN apt-get update RUN apt-get -y install openjdk-8-jdk ssh emacs vim CMD ["java", "-jar", "/app/target/app.jar"]
  • 11. Make build cache your friend Incremental build time
  • 12. Order matters for caching FROM debian COPY . /app RUN apt-get update RUN apt-get -y install openjdk-8-jdk ssh vim COPY . /app CMD ["java", "-jar", "/app/target/app.jar"] Order from least to most frequently changing content.
  • 13. More specific COPY to limit cache busts FROM debian RUN apt-get update RUN apt-get -y install openjdk-8-jdk ssh vim COPY . /app COPY target/app.jar /app CMD ["java", "-jar", "/app/target/app.jar"] Only copy what's needed. Avoid "COPY ." if possible
  • 14. Line buddies: apt-get update & install FROM debian RUN apt-get update RUN apt-get -y install openjdk-8-jdk ssh vim RUN apt-get update && apt-get -y install openjdk-8-jdk ssh vim COPY target/app.jar /app CMD ["java", "-jar", "/app/app.jar"] Prevents using an outdated package cache
  • 15. Reduce image size Faster deploys, smaller attack surface
  • 16. Remove unnecessary dependencies FROM debian RUN apt-get update && apt-get -y install --no-install-recommends openjdk-8-jdk ssh vim COPY target/app.jar /app CMD ["java", "-jar", "/app/app.jar"]
  • 17. Remove package manager cache FROM debian RUN apt-get update && apt-get -y install --no-install-recommends openjdk-8-jdk && rm -rf /var/lib/apt/lists/* COPY target/app.jar /app CMD ["java", "-jar", "/app/app.jar"]
  • 18. Remove package manager cache FROM debian RUN apt-get update && apt-get -y install --no-install-recommends openjdk-8-jdk && rm -rf /var/lib/apt/lists/* COPY target/app.jar /app CMD ["java", "-jar", "/app/app.jar"]
  • 20. Use official images where possible - Reduce time spent on maintenance (frequently updated with fixes) - Reduce size (shared layers between images) - Pre-configured for container use - Built by smart people
  • 21. Use official images when possible FROM debian RUN apt-get update && apt-get -y install --no-install-recommends openjdk-8-jdk && rm -rf /var/lib/apt/lists/* FROM openjdk COPY target/app.jar /app CMD ["java", "-jar", "/app/app.jar"]
  • 22. Use more specific tags FROM openjdk:latest FROM openjdk:8 COPY target/app.jar /app CMD ["java", "-jar", "/app/app.jar"] The "latest" tag is a rolling tag. Be specific, to prevent unexpected changes in your base image.
  • 23. Pick your variant Read the image's documentation on Docker Hub https://hub.docker.com/_/openjdk
  • 24. Look for minimal flavors REPOSITORY TAG SIZE openjdk 8 624MB openjdk 8-jre 443MB openjdk 8-jre-slim 204MB openjdk 8-jre-alpine 83MB Just using a different base image reduced the image size by 540 MB
  • 25. The Dockerfile as blueprint, source code the source of truth Reproducibility
  • 26. Build from source in a consistent environment Make the Dockerfile your blueprint: - It describes the build environment - Correct versions of build tools installed - Prevent inconsistencies between environments - There may be system dependencies - The "source of truth" is the source code, not the build artifact
  • 27. Build from source in a consistent environment FROM openjdk:8-jre-alpine FROM maven:3.6-jdk-8-alpine WORKDIR /app COPY app.jar /app COPY pom.xml . COPY src ./src RUN mvn -e -B package CMD ["java", "-jar", "/app/app.jar"]
  • 28. FROM maven:3.6-jdk-8-alpine WORKDIR /app COPY pom.xml . COPY src ./src RUN mvn -e -B package CMD ["java", "-jar", "/app/app.jar"] Build from source in a consistent environment
  • 29. FROM maven:3.6-jdk-8-alpine WORKDIR /app COPY pom.xml . RUN mvn -e -B dependency:resolve COPY src ./src RUN mvn -e -B package CMD ["java", "-jar", "/app/app.jar"] Fetch dependencies in a separate step
  • 30. Identify build dependencies FROM maven:3.6-jdk-8-alpine WORKDIR /app COPY pom.xml . RUN mvn -e -B dependency:resolve COPY src ./src RUN mvn -e -B package CMD ["java", "-jar", "/app/app.jar"]
  • 31. FROM maven:3.6-jdk-8-alpine AS builder WORKDIR /app COPY pom.xml . RUN mvn -e -B dependency:resolve COPY src ./src RUN mvn -e -B package CMD ["java", "-jar", "/app/app.jar"] FROM openjdk:8-jre-alpine COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] Multi-stage builds to remove build deps
  • 32. FROM maven:3.6-jdk-8-alpine AS builder WORKDIR /app COPY pom.xml . RUN mvn -e -B dependency:resolve COPY src ./src RUN mvn -e -B package FROM openjdk:8-jre-alpine COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] Multi-stage builds to remove build deps
  • 33. Not just for reducing image size Multi-stage Dockerfiles
  • 34. - Moby: 16 stages https://github.com/moby/moby/blob/master/Dockerfile - BuildKit: 44 stages https://github.com/moby/buildkit/blob/master/hack/d ockerfiles/test.buildkit.Dockerfile Projects with many stages
  • 35. - Separate build from runtime environment (shrinking image size) - Slight variations on images (DRY) - Build/dev/test/lint/... specific environments - Delinearizing your dependencies (concurrency) - Platform-specific stages Multi-stage use cases
  • 36. FROM image_or_stage AS stage_name … $ docker build --target stage_name Building specific stages with --target
  • 37. FROM maven:3.6-jdk-8-alpine AS builder ... FROM openjdk:8-jre-jessie AS release-jessie COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] FROM openjdk:8-jre-alpine AS release-alpine COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] $ docker build --target release-jessie . Different image flavors
  • 38. FROM maven:3.6-jdk-8-alpine AS builder ... FROM openjdk:8-jre-jessie AS release-jessie COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] FROM openjdk:8-jre-alpine AS release-alpine COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] $ docker build --target release-jessie . Different image flavors
  • 39. FROM maven:3.6-jdk-8-alpine AS builder ... FROM openjdk:8-jre-jessie AS release-jessie COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] FROM openjdk:8-jre-alpine AS release-alpine COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] $ docker build --target release-jessie . Different image flavors
  • 40. ARG flavor=alpine FROM maven:3.6-jdk-8-alpine AS builder ... FROM openjdk:8-jre-$flavor AS release COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] $ docker build --target release --build-arg flavor=jessie . Different image flavors (DRY / global ARG)
  • 41. Examples of possible stage layout: - builder: all build dependencies - build (or binary): builder + built artifacts - cross: same as build but for multiple platforms - dev: build(er) + dev/debug tools - lint: minimal lint dependencies - test: all test dependencies + build artifacts to be tested - release: final minimal image with build artifacts Various environments: build, dev, test, lint, ...
  • 42. FROM maven:3.6-jdk-8-alpine AS builder ... FROM openjdk:8-jre-alpine AS lint RUN wget https://github.com/checkstyle/checkstyle/releases/download/checkstyle-8.15/checkstyle-8.15-all.jar COPY checks.xml . COPY src /src RUN java -jar checkstyle-8.15-all.jar -c checks.xml /src Various environments: build, dev, test, lint, ...
  • 43. FROM maven:3.6-jdk-8-alpine AS builder ... FROM openjdk:8-jre-alpine AS release COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] FROM builder AS dev RUN apk add --no-cache strace vim tcpdump ENTRYPOINT ["ash"] Various environments: build, dev, test, lint, ...
  • 44. FROM maven:3.6-jdk-8-alpine AS builder ... RUN mvn -e -B package -DskipTests FROM builder AS unit-test RUN mvn -e -B test FROM release AS integration-test RUN apk add --no-cache curl RUN ./test/run.sh Various environments: build, dev, test, lint, ...
  • 45.
  • 46.
  • 47. - all stages are executed in sequence - without BuildKit, unneeded stages are unnecessarily executed but discarded From linear Dockerfile stages ...
  • 48. … to multi-stage graphs with BuildKit - BuildKit traverses from bottom (stage name from --target ) to top
  • 49. … to multi-stage graphs with BuildKit - BuildKit traverses from bottom (stage name from --target ) to top - Unneeded stages are not even considered
  • 50. FROM maven:3.6-jdk-8-alpine AS builder ... FROM tiborvass/whalesay AS assets RUN whalesay "Hello DockerCon!" > /out/assets.html FROM openjdk:8-jre-alpine AS release COPY --from=builder /app/app.jar / COPY --from=assets /out /assets CMD ["java", "-jar", "/app.jar"] Multi-stage: build concurrently
  • 51. FROM maven:3.6-jdk-8-alpine AS builder-base … FROM gcc:8-alpine AS builder-someClib … RUN git clone … ./configure --prefix=/out && make && make install FROM g++:8-alpine AS builder-someCPPlib … RUN git clone … cmake … FROM builder-base AS builder COPY --from=builder-someClib /out / COPY --from=builder-someCPPlib /out / … Multi-stage: build concurrently Concurrency pattern: multiple COPY --from ... COPY --from ...
  • 52. Benchmarks Based on github.com/moby/moby Dockerfile, master branch. Smaller is better. Time for full build from empty state 2.0x faster
  • 53. Benchmarks Based on github.com/moby/moby Dockerfile, master branch. Smaller is better. Repeated build with matching cache 7.2x faster
  • 54. Benchmarks Based on github.com/moby/moby Dockerfile, master branch. Smaller is better. Repeated build with new source code 2.5x faster
  • 56. Enabling new features Experimental as in, not in mainline Dockerfile syntax. The 1.0-experimental image will not break in the future. # syntax=docker/dockerfile:1.0-experimental FROM maven:3.6-jdk-8-alpine AS builder WORKDIR /app COPY . /app RUN mvn -e -B package FROM openjdk:8-jre-alpine COPY --from=builder /app/app.jar / CMD ["java", "-jar", "/app.jar"]
  • 57. For more details: docs/experimental-syntaxes.md https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md
  • 58. Context mounts (v18.09+ w/ BuildKit) # syntax=docker/dockerfile:1.0-experimental FROM maven:3.6-jdk-8-alpine AS builder WORKDIR /app COPY . /app RUN --mount=target=. mvn -e -B package -DoutputDirectory=/ FROM openjdk:8-jre-alpine COPY --from=builder /app/app.jar / CMD ["java", "-jar", "/app.jar"]
  • 59. Context mounts (v18.09+ w/ BuildKit) # syntax=docker/dockerfile:1.0-experimental FROM maven:3.6-jdk-8-alpine AS builder WORKDIR /app RUN --mount=target=. mvn -e -B package -DoutputDirectory=/ FROM openjdk:8-jre-alpine COPY --from=builder /app.jar / CMD ["java", "-jar", "/app.jar"]
  • 60. Cache dependencies (before BuildKit) FROM maven:3.6-jdk-8-alpine WORKDIR /app COPY pom.xml . RUN mvn -e -B dependency:resolve COPY src ./src RUN mvn -e -B package CMD ["java", "-jar", "/app/app.jar"]
  • 61. Application cache (v18.09+ w/ BuildKit) # syntax=docker/dockerfile:1.0-experimental FROM maven:3.6-jdk-8-alpine AS builder WORKDIR /app RUN --mount=target=. --mount=type=cache,target=/root/.m2 && mvn package -DoutputDirectory=/ FROM openjdk:8-jre-alpine COPY --from=builder /app.jar / CMD ["java", "/app.jar"] apt: /var/lib/apt/lists go: ~/.cache/go-build go-modules: $GOPATH/pkg/mod npm: ~/.npm pip: ~/.cache/pip
  • 62. FROM baseimage RUN ... ENV AWS_ACCESS_KEY_ID=... ENV AWS_SECRET_ACCESS_KEY=... RUN ./fetch-assets-from-s3.sh RUN ./build-scripts.sh Secrets (DON’T DO THIS)
  • 63. FROM baseimage RUN ... ARG AWS_ACCESS_KEY_ID ARG AWS_SECRET_ACCESS_KEY RUN ./fetch-assets-from-s3.sh RUN ./build-scripts.sh $ docker build --build-arg AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID … . Secrets (DON’T DO THIS EITHER) docker history
  • 64. # syntax=docker/dockerfile:1-experimental FROM baseimage RUN ... RUN --mount=type=secret,id=aws,target=/root/.aws/credentials ,required ./fetch-assets-from-s3.sh RUN ./build-scripts.sh $ docker build --secret id=aws,src=~/.aws/credentials . Secrets (DO THIS, v18.09+ w/ BuildKit)
  • 65. FROM baseimage COPY ./keys/private.pem /root/.ssh/private.pem ARG REPO_REF=19ba7bcd9976ef8a9bd086187df19ba7bcd997f2 RUN git clone git@github.com:org/repo /work && cd /work && git checkout -b $REPO_REF Private git repos (DON’T DO THIS)
  • 66. FROM alpine RUN apk add --no-cache openssh-client RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts ARG REPO_REF=19ba7bcd9976ef8a9bd086187df19ba7bcd997f2 RUN --mount=type=ssh,required git clone git@github.com:org/repo /work && cd /work && git checkout -b $REPO_REF $ eval $(ssh-agent) $ ssh-add ~/.ssh/id_rsa $ docker build --ssh=default . Private git repos (DO THIS, v18.09+ w/ BuildKit)
  • 67. We went from: - inconsistent build/dev/test environments - bloated image - slow build and incremental build times (cache busts) - building insecurely To: - consistent build/dev/test environments - minimal image - very fast build and incremental build times - building more securely Improvements recap
  • 68. Read more on blog posts https://medium.com/@tonistiigi/advanced-mult i-stage-build-patterns-6f741b852fae https://medium.com/@tonistiigi/build-secrets-and-s sh-forwarding-in-docker-18-09-ae8161d066
  • 69. • Multi-stage, multi-stage, multi-stage • DOCKER_BUILDKIT=1 OSS Summit: Advanced BuildKit sessions on Thursday, May 2 at 12:30pm in room 2020 Thank you! Follow us @tiborvass @thaJeztah