-: In this section, there's one last quick thing
that I want to mention about the docker build process.
This is an important thing to understand
because it's what gives Docker so much performance
whenever creating a new image.
All right, so I'm looking at my Dockerfile right here,
we have our three instructions,
and, as you very well know by this point,
out of each one of these instructions
we essentially get a new image.
So from Alpine, we get the Alpine image.
From the RUN instruction,
we get a temporary image that gets fed
into the CMD instruction
which gives us another temporary image.
So at every instruction along the way,
we have a file system snapshot
and a startup command for that image.
Now, I wanna show you something a little bit interesting.
I'm going to go back over to my Dockerfile,
and on the RUN instruction, I'm gonna add a new one.
Right underneath it, I'm gonna say RUN apk add --update gcc.
So we're just installing a very random
second dependency here.
There's nothing important that you need to know about GCC.
We're just installing a second dependency.
So I want you to think about what effect
this is gonna have on our overall flow.
Essentially, what it's gonna do
is add in a new instruction right here
that's gonna look a little something like this.
We're gonna see a new one.
Let's see how quickly I can do this edit.
We're gonna get our new instruction right there.
It's gonna be very similar
to the image from the previous step,
and it's gonna have a new little program or folder,
or something inside of it, of GCC.
So essentially, it is identical to the previous image
but it has this extra little program that has been added in.
Let's now flip over to our terminal.
I want to rebuild our image
and you're gonna notice something kind of interesting.
So back over at my terminal,
I'm still inside of my Redis image directory
and I'm going to build my image a second time
by running docker build..
All right, so we're gonna very quickly see
some installation steps right here
as it adds in that additional package,
but I want to scroll up to the second instruction
and I wanna point out something interesting up there.
So we still see step one of four right here
where we do from Alpine.
You'll notice that we do not see any of that,
like, fetching image stuff that we saw the first time
because we have already fetched the Alpine image,
we've already downloaded it from the Docker Hub,
and so we don't have to go and download it a second time.
Now, the interesting thing that I wanna show you,
and this is where Docker gets so much of its speed
and performance from when building an image,
you'll notice that during step number two right here,
we do not see any of that stuff around,
running in blah blah, blah,
we don't see any fetch,
we don't see any installation of dependencies.
Instead, we see a single message that says, "Using cache."
So what this means is that Docker has realized
that from the previous step to step number two,
nothing has changed from the last time
that we ran docker build.
In other words, it knows, without a doubt,
that it's gonna get the same image from the previous step
because it's the exact same instruction that it was before.
And then for step number two,
Docker knows that it has already executed the command
APK add update Redis,
It's already generated an image out of that step,
this image right here.
And this image has been cached
and stored on your local machine.
So rather than going through the process
of creating another container out of the Alpine image
and running APK add update Redis
inside that container a second time,
it says, "You know what, I've already done this work.
I'm just gonna use the image that I generated
during the previous step again."
But then after that, Docker correctly sees
that there is a new command in play
and this is not add update Redis, it's add update GCC,
it sees that there's a new command right here
or a new instruction in play,
and so from this point on, it decides,
"Well, you know what?
Something has changed during the build process.
We probably can't use our cache anymore,
and, from here on out, we have to go through that process
of generating a container
and running a command inside the container
and taking the snapshot
and going through all that stuff again."
Now, the interesting thing about this
is that it has now executed run APK add GCC,
and it has generated an image
out of that instruction right there.
So if we now run docker build. a third time
without making any changes to our Dockerfile,
Docker is gonna correctly see
we have made no changes to the Dockerfile,
none of these steps have changed whatsoever,
and so it's going to use the cached or saved versions
of each of these images
in building this new one.
Let's do that right now, and you're gonna see it in action.
So we're gonna do docker build. a third time,
and you'll notice that build process went extremely quickly.
So Docker correctly realized
that it's already downloaded Alpine,
it's realized that it already ran the run command
on top of Alpine,
so it's using the cache version of that image.
It knows it's already done the GCC
so it's using the cache version of that,
and it knows that it's already executed command Redis server
on top of the output of the GCC step,
and so it's using the cache there again.
So the lesson to learn here
is that any time that we make a change to our Dockerfile,
we're going to have to only rerun the series of steps
from the changed line on down.
As a quick example of that,
let's try taking this GCC line right here
and I'm gonna cut it and put it right above Redis.
So even though we're still taking the Alpine image
and adding GCC to it, and adding Redis to it,
the series of steps have changed.
And so Docker's gonna say,
"Okay, well, this time we're taking Alpine
and first adding in GCC."
So it will use the cache version of Alpine
but it's not going to have a cached version
of the GCC add to use,
because the last time that it ran that,
it added GCC only after installing Redis.
So essentially, the order of operations is different
so the cache cannot be used.
So I'm gonna save this file after moving GCC around
and we'll try rebuilding our image for a fourth time.
So I'll do docker build., I'll run that,
and now you're gonna see, yep,
it has to go through that installation process
all over again
because the order of operations have changed.
However, it only needs to rerun the steps
from the change line on down.
And so we have to rerun the entire add GCC,
we rerun the entire add Redis,
and we have to rerun the command Redis server.
All right, so, again,
if you are not changing your Dockerfile, that's great,
because it means that we can use cache versions
for building the image.
But the real lesson to learn here
is that if you ever expect to have
to change your Dockerfile,
you always want to put those changes, like,
as far down as possible.
Now, right now, that might sound really confusing
but we're gonna very quickly go through another example
in a couple of videos
where you'll see that by changing the order of operations
inside of our Dockerfile
can dramatically change how long it takes
to rebuild our image.
All right, so quick pause right here
and I'll catch you in the next section.