- [Instructor] So far, we have made
a couple of Docker images by hand
and run things on them to make containers.
Now, let's explore building images with code.
That's where Dockerfiles come in.
Dockerfiles are small programs designed to describe
how to build a Docker image.
You run these programs with the docker build command.
So it's docker build and dash t stands for tag,
and that just says when you finish building this thing,
tag it with this name, so that it's easy to find afterwards.
The dot at the end of the line is not punctuation.
That specifies the location
where you can find the Dockerfiles.
The dot says in the current directory,
the place where you are running this command.
If your Dockerfile was somewhere else,
you'd replace that dot with the path
to the actual Dockerfile.
When it finishes running your Dockerfile,
the resulting image will be on the your computer
in the local Docker Registry,
ready to be run with docker run.
So each step produces a new image.
It's got a series of steps,
start with one image,
make a container out of it,
run something in it, make a new image.
The previous image is unchanged,
it just says, start from that,
make a new one with some changes in it.
The state is not carried forward from line to line.
If you start a program on one line,
it runs only for the duration of that line.
So as a result, if part
of your build process is download a large file,
do something with it,
and delete it, if you do that all in one line,
then the resulting image will have only the result of that.
If you download it on one line,
it will get saved into an image.
The next line will have that image saved there,
and the space occupied
by your big downloaded file will be carried
all the way through and your Dockerfile can get pretty big.
Be careful about having
operations on large files span lines in Dockerfiles.
Let's take a look at what a Dockerfile looks like.
Dockerfiles generally look like this.
They have lines.
The lines have a command at the front
and then some stuff after it,
run this, start from there, that kind of thing.
And you can learn all about them
at the official Dockerfile reference page
on the Docker website.
So each step of running a Dockerfile is cached.
I mentioned that the later steps
don't modify the previous step.
That means that the next time you run your build,
if nothing changed, it doesn't have to rerun that step.
So Docker can skip lines
that weren't changed since the last time
you built this Dockerfile.
So if the first line in your Dockerfile is,
download this big file,
and save the latest copy,
and then 20 minutes later you run that again,
the file will have already been downloaded,
so it won't run that line,
and it won't spend the time to go download
that huge file again.
This can save huge amounts of time.
You do have to be aware of it though,
because if you wanted it to re-download the latest version
of that large file, you'll have to explicitly make it do so.
Just a little tip, put the parts of your code
that you changed the most at the end of your Dockerfile.
That way, the parts before them don't need
to be redone every time you change that part.
One part I just can't emphasize too much
is that Dockerfiles are not shell scripts.
They were designed with a syntax that
looks like shell scripts,
because that helps them be familiar to people,
and it makes them a little easier to learn.
But Dockerfiles are not shell scripts.
Processes you start on one line
will not be running on the next line.
You run them, they run for the duration of that container,
then that container gets shut down,
saved into an image, and you have a fresh start
on the next line.
So you can't treat it like a shell script and say,
start a program on one line,
then send a message to that program on the next line.
The program won't be running.
If you need to have one program start
and then another program start,
those two operations need to be on the same line,
so that they run in the same container.
Environment variables do persist across lines
if you use the ENV command to set them.
Just remember that each line in a Dockerfile is its own call
to docker run, and then its own call to docker command.
That'll help keep in mind the differences
between Dockerfiles and shell scripts.