- [Instructor] When we build Docker files
that go beyond the very simplest projects,
it often runs into two competing desires.
On the one hand, we want the Docker file
to be totally complete, have everything required
to build this project from scratch,
so years from now, we will be absolutely certain
that we can rebuild it, and that it will have everything.
and on the other hand, we want them to be super small,
minimal, and really quick to deploy.
So people often do things like make two Docker files,
one for their daily life, and one for production.
These get out of sync and stress ensues.
So recently, a new feature was added to Docker files
called multi-stage builds.
To explain how this works, let's start by making
a small Docker file.
From Ubantu:16.04,
and a run apt-get update to get the latest package lists.
Then RUN apt-get -y for yes, install curl
for downloading things during the installation process.
Now we're going to run an example project
that just calls curl https://google.com
and pipe the output to word count, wc.
It just counts words.
- C to count the number of characters
and we're going to save that into a build artifact
called google-size.
So this just pre-calculates at build time
how big is the Google homepage in characters.
Then, when this project runs, I want it to display
that information, so I'm going to add an entry point
using the Shell syntax, echo google
is this big,
google-size.
So when this runs, it's just going to output
its computed build object, which in this case,
is a very tiny text file.
Let's go ahead and run this and see it in action.
I save, head on over to the same directory in my terminal.
There I am.
I see the Docker file.
Docker build -t, and I'll call this one tooo-big.
It's downloaded Ubuntu.
It's updating the packages.
It's going to install curl.
Still building.
Okay, we have successfully built tooo-big, the Docker image.
Docker run tooo-big.
Ah, Google is this big, 220 characters,
but how big is that image?
Docker images, amongst my other images here,
I see that tooo-big is 171 megabytes,
and all it points out is about a dozen or so characters.
Let's see if we can improve that.
Back in my editor, I'm going to split this Docker file
into two parts.
We're going to have the first part
which will run largely unchanged,
and I'm just going to give it a name.
So I'm going to say as builder.
So from Ubuntu 16.04, using the name builder,
do these steps.
Then down here, I'm going to add another from, from alpine.
I'm going to call copy --from=builder,
which is just the name I assigned above,
/google-size, and I want to copy it to the same path
in this new image, google-size, okay?
Save, now let's run that again.
I'm going to rebuild it.
This time I'll call it google-size.
Okay, Docker run google-size,
google is this big, 220 bytes.
But how big are these images?
All right, we see while tooo-big clocked in
at 171 megabytes, google-size, the one we just built,
clocked in at 4.41 megabytes,
drastically smaller for the same functionality.
Yet, all of the ability to have a reproducible build
is completely preserved.