- [Instructor] When creating an image from a file,
you have a number of different options.
You learned how to create a simple docker file,
how to place it in the current directory,
and then do a docker build space dot,
representing the current directory
which would pull in the docker file.
But what other options do you have?
Well, the docker build documentation over at docs.docker.com
covers numerous options where the docker file can,
for example be placed in a different directory
using the minus F or file option here.
That allows you to specify the name of a docker file
which could be totally different
than the word docker file with a capital D,
and it could be in a totally different place
than the current directory.
You can even perform builds
using for example, standard input.
You can perform builds using get repositories.
You can even perform builds using tarballs,
which are compressed tar files, just like that.
You can even do a standard input with a docker file
being redirected to the docker build command.
Let me show you an example of some of these in action.
So in our current directory,
we have the docker file that we created
earlier in this course.
It's a simple docker file.
Let's say that we wanted to specify
the name of a docker file,
other than just this docker file
that starts with a capital D
and is in the current directory,
or the current build context as docker build calls it.
Let's say that we created a directory called docker temp,
in the current directory.
And then we copied our docker file into docker temp
and let's call it dd-docker.
And if we CD into docker temp,
let's do an LS, there's our dd-docker file.
So if I clear the screen,
and if we do a docker build,
and then we use the minus F flag to specify a file,
in this case it's going to be ./dd-docker,
that's the name of our docker file.
And then we still have to provide
what they call a build context.
So the build context could be still .the current directory.
We could also specify another build context.
The importance of the build context
is that any files that are in that directory or that folder,
are going to be added to the docker image file system
that's created when this image is built.
So as you can imagine,
the files that are inside that directory are critical.
If you need them to be added to the docker image
for this containerized application to function,
then they need to be in that folder
or in that current directory.
On the other hand,
if you specify some arbitrary build context,
for example, let's say that I'm in my home directory
and I have a few gigabytes of video files
in my home directory and I perform a docker build,
then those few gigabytes of video files
will be included in the image.
And that image will be humongous,
and unnecessarily humongous,
thanks to these few gigabytes of video files
that I didn't even think about were in my current directory
when I built that image.
So again the build context is very important.
So I pushed enter on that docker build command,
and instantly it came back
and it said that a new image had been built.
How did it build that image so quickly?
Well, it used the build cache.
So docker keeps a cache of images and layers
that have been built in the past.
And it will by default, use that build cache,
as long as you haven't changed anything in the docker file.
But what if we didn't want to use the build cache?
Well we could run the same build again,
but this time let's do dash dash
no-cache
=true.
And this time you can see,
it takes much longer to build the image
because the cache isn't being used,
and whatever is instructed in the docker file
to be pulled down or run,
is going to be pulled down, and then run.
For example in this case, it's an apt-get update,
and then an apt-get install
of a number of different packages.
And we'll talk about the importance of the build cache
and the instructions as you specify them in just a moment.
So that's how you don't use the cache
if you wanna not use the cache for a specific reason.
And there's a number of other best practices
that you need to be aware of.
Thankfully docker has a very nice best practices
for writing docker files document, out in docker docs.
And if you scroll down here, it talks about for example,
the importance of the build context, which we just covered.
It also talks about how you can use the .docker ignore file
if you wanna create a special file
that tells docker build to ignore certain file patterns
or types of files in the current directory,
you can do that with the .docker ignore.
Some other best practices that you need to be aware of,
for example are that each container
should only have one concern as they say.
In other words each container should only run one processor,
one application, that's the point of containers.
Not to be like a virtual machine
with multiple applications inside.
Every container should only initialize
a single application, or a single process.
That's part of the best practices.
Another best practice here is to sort multi-line arguments.
So I'll show you how to do that in our docker file
in just a moment.
Essentially it's using the backslash
to allow you to better organize multiple steps
that are in a run instruction.
And then finally if we scroll down here,
another best practice is to link together
apt-get update and apt-get install
with a double ampersand.
And I'll show you how to do that as well.
The reason to do that,
is because if you have these two different commands
on separate lines,
apt-get update won't be run again
because the contents or the results of apt-get update
will have been cached.
So the second time you run the docker build
using the same docker file,
you won't get the latest packages to be installed
when you run the apt-get install.
So let's go over to the command line
and I'll show you how to perform
some of these best practices on a docker file
to get the most efficient build possible.
Let's do a nano on the dd-docker, docker file.
And if we scroll down here,
notice that the best practice has actually been
applied here already.
This was the docker file that we copied and pasted
in a previous lesson from the web.
You can see here that the double ampersand
has been used to link the apt-get update
and the apt-get install together
so that they're run at the same time sequentially.
Now another best practice that we learned about,
is that you can also use the backslash here
to better organize each of the different packages
that you're installing,
and this allows you to essentially
see what it is that you're installing,
each of the different packages.
Although these are still run as the same command
because of that backslash that we've added
at the end of the line.
So let's actually do a exit on this,
let's save the changes.
And then let's clear the screen.
And then rerun this command
where we did a docker build with the no cache=true,
and we specified the dd-docker docker file
in the current directory,
with the current directory as the build context.
So if we run this again,
we should see essentially the exact same results.
We have linked together the apt-get update
and the apt-get install,
to make sure that apt-get update runs every time,
as well as using the no cache=true.
And then we've separated or broken up
each of the different packages that are installed,
with apt-get install.
We've put those on separate lines
to make it very readable,
and very easy to understand that docker file.
So we got the same results.
If we edit this docker file,
for example let's say that we wanted to
remove one of these lines,
remove one of these packages,
or maybe even add a new package
that we want to install down here.
We could easily do that,
and let's add the backslash there,
so we have a nice lineup here
of all the different packages that we're installing.
And it doesn't have to just be packages,
it can be any sort of lengthy command,
broken up into multiple, much more readable lines.
So that's how you create an image from a docker file,
as well as a number of the more advanced best practices
that you need to know about
to create more efficient docker images,
using docker file and docker build.