- [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.
- Installing Docker on Mac, Windows, and Linux
- Understanding the Docker flow
- Running processes in containers
- Managing, networking, and linking containers
- Working with Docker images, volumes, and registries
- Building Dockerfiles
- Managing networking and namespaces with Docker
- Building entire systems with Docker