- [Instructor] The Dockerfile reference over in Docker Docs
is the ultimate reference for all the Docker instructions
but there are a few Docker instructions
that I wanted to go through with you specifically
to make sure that you are aware of what they do
because they're listed on the
Docker DCA study guide exam blueprint.
The first Dockerfile instruction
that you need to know is add.
Add copies a file into the image
but it also supports tar and remote URL's.
So essentially, it's just like the copy command.
The copy command copies files into the image
that you're building and it's preferred over add
really for its simplicity unless
you need the features of add
which include tar and remote URL support,
copy is recommended in the Dockerfile best practices.
And then there's volume.
Volume creates a mount point as defined
when the container is run.
In other words, when the image that you're building
is instantiated into a container,
a mount point will be created using
the URL that's referenced in the volume instruction.
And then there's entrypoint.
Entrypoint is the executable that's run
when the container is run so if you're building an image
and let's say you want that image to become a web server,
the web server might execute the HTTP demon
to start up the web server service
so that every time that container is started,
the web server service is already running.
And you could also include some parameters
for that web server service.
And then there's expose.
Expose, at the surface, appears to open ports
for a specific application but upon further investigation
you'll find that the expose instruction
is really just a comment saying which port
should be published when this image is used as a container.
You'll want to open the ports that are listed in exposed.
Then there's the command or CMD instruction.
This provides arguments for the entrypoint.
Only one command is allowed per Dockerfile
but if you do reference multiple command instructions,
only the last command that you specify will be used.
Another Dockerfile instruction that you need to know is ENV.
ENV or environment is used to define environmental variables
that will be defined in the container
when the container is running.
And then there's the from instruction.
The from instruction defines the base image
that will be used to build this image,
and the from instruction must be the first instruction
in the Dockerfile except any comments
that you might have above.
And then just a few more here.
We have the maintainer instruction,
and this is actually deprecated,
meaning it's not recommended to be used anymore.
Typically this points to the email address
of the person who authored the Dockerfile.
While it's not recommended to be used in future Dockerfiles,
you'll still see the maintainer instruction
in many Dockerfiles out on the internet.
Another instruction is on build
and this is only used as a trigger
which is used to build other images
and it's used to define the commands
that will be run when another image
is built from this image.
And then there's run.
Run specifies a command that you want to run
in a new layer of the image that's being built.
And finally, working directory or workdir.
It defines a working directory of the container.
And as I said, these are just some of
the more popular Dockerfile instructions.
There are many, many more Dockerfile instructions
in the reference for Dockerfile
or the man page for Dockerfile on your Docker host.
In a previous video, we created a Dockerfile.
If we open up this Dockerfile in our text editor Nano,
you can see that there are really only three
different instructions in this Dockerfile.
The first one is the from instruction.
So this one defines the base image
for this image that we'll be creating.
And it's kind of like a circle here where
you're building a new image with a Dockerfile
but it's based on a previous image.
And then once you build your image,
it can be executed or run or instantiated
into a container with the writable layer on top,
you can make changes to that container,
to its file system with the writable layer.
You can then commit those changes
and push them back to an image
and then you can use that image to create
more containers or even build more images.
So you have a lot of flexibility here but if you remember,
Dockerfiles always start with the required instruction
which is from.
What's the base image that this image will be created from?
The next instruction which we actually didn't cover
is called label.
So a label is really just a description here.
It's just about anything that you want to define
for this image that you're creating.
And this one says this image is used to start the foobar
executable and the vendor is ACME Products
and the version is 1.0.
And then we have the run instruction here.
So the run instruction is actually
got a few different commands in it.
First, we're gonna do an apt-get update
to update our packages.
Then we're gonna do an apt-get install -y
to accept any installations.
And we'll install the notify tools, the nginx web server,
apache2, and the openssh-server.
So we're first going to download the Ubuntu image.
If we have it already, it won't need to be downloaded.
We can build this new image from the cached image.
But in this case,
I believe we're going to have to download it.
And then these commands in a sequence will run.
So let's exit out of that.
I'm going to clear the screen.
And then to do a Docker build using a Dockerfile,
it's really very easy.
Docker space build space and then
specify the location of the Dockerfile.
In this case, it's in the current directory which is dot.
So I'll just press enter here
and step one is to pull down the Ubuntu Linux image.
It says the pull is complete.
We used the latest image.
And then we're going to do that apt-get update
so it updated our package archive.
And then we're installing these packages.
So we're installing the nginx web server,
the apache web server, and the openssh server.
And this is all being installed or layered on top of
that Ubuntu-based image that
we specified in the from command.
So it'll take just a moment to complete this
and welp, there we go.
It was that easy.
So we just built our first image using a Dockerfile.
So now let's clear the screen
and let's take a look at what we have.
So if we do the docker image ls command,
you can see we have a brand new image that was built.
In this case, we didn't tag it.
We didn't give it a repository name or anything like that.
It just has an image ID which starts with 883.
So if we do a docker image inspect on image 883,
let's take a look at this.
Actually it scrolled by too fast.
Let's pipe that to more and let's take a look at this
and make sure that this is really the image that we created.
So it starts off in the command section down here.
The most important thing I notice immediately
is here's the exact command sequence that we ran
in the run command in our Dockerfile.
If we scroll on down here,
you can see here are the labels that we defined,
right, the description, the vendor, and the version number.
And if we scroll on down yet again,
we see our description again
and here you can see the different layers
that make up the file system that was created
when the Docker build was executed based on our Dockerfile.
So those are the layers of this container image file system
but they'll all be brought together
with the union file system.
So when you run a container based on this image,
it will just look like one file system.
So that's the Docker image that we created,
and we looked at that using the Docker inspect command
but what if we used the docker history,
docker image history command.
Let's take a look at that.
So the docker image history command
tells us the history of this image.
What do we know about this image,
specifically the layers that were built
when this image was created?
We can first tell that we added a file here
and that file was rather large, 113 megabytes.
And that's actually the Ubuntu-based image that we added.
Then a number of configuration changes were made
and then the labels were applied
and then finally, the apt-get update and apt-get install
were executed there
and you can see the size of the different layers.
Some of them actually take up no space or zero bytes
while others take up quite a bit of space
in the total image size.
But that total image size, again,
is made up of these different layers
that are created up here based on the Dockerfile
that we created, that we used during the build.
So those are the main parts of the Dockerfile
that you need to be aware of,
and the most critical instructions in my opinion.
We also looked at the different layers of the Dockerfile
as it's created and you can inspect those
using the Docker image history command
as well as the Docker image inspect command.
Now that we've created a Dockerfile
and built an image based on that Dockerfile,
let's move on and learn more
about managing images in Docker.