‫This section is going to focus exclusively on Docker Compose, which is a combination of a command line
‫tool and a configuration file. Requirements for this section are that you really need to know a lot of the fundamentals
‫from the last few sections around images and containers.
‫As we're going through this course, you're probably going to start to hear me get more and more excited
‫because things just keep getting better.
‫Right?
‫As you learn one component, you're thinking, 'man, bind mounts and volumes are really cool. That's going
‫to save me some time. I can imagine how I'm going to use that. Blah blah blah blah.
‫Then, I'm going to come with the next thing that's going to be even better than what you just learned.
‫In this case, it couldn't be more true.
‫Docker Compose. So, what is it? And why do we care? So few software services are truly standalone.
‫When you think about your containers, they're a single process solution, and we're rarely going to use just
‫a single container to solve a problem or provide a service to our customers.
‫Our containers will often require other containers such as SQL or a key value. And other applications
‫that we'll need to run in containers, like proxies or web frontends or backend workers, and so on.
‫What if we had a way to connect all those pieces of our solution together, where we didn't need to
‫remember all of our docker run options, and then get them into discreet, virtual networks with relationships
‫between them, and only expose the public ports, and then spin them all up and tear them down with one
‫command.
‫Well, that's Docker Compose.
‫Before we dive in, we need to clear up that there's two parts to
‫Docker Compose. The first part is the YAML file and it's super simple to understand.
‫It's written in YAML, and if you've never dealt with YAML, that is a very easy configuration language.
‫It's almost as easy as an INI file would be.
‫I actually think it's easier because it shows hierarchy.
‫We'll dive into that. That file is where you would specify all the containers you need to run, the
‫networks you need, any volumes you might need, environment variables, images, and all sorts of other configuration
‫options.
‫Then the second part of Docker Compose is a CLI tool, which is docker -compose, that we use normally
‫for just local dev and test, using that YAML file we created to simplify our Docker commands.
‫Let's talk about that Docker Compose file.
‫There's actually versions to the things that you can put in the compose file. So when Docker Compose
‫was created years ago, it was actually called "Fig" and it was just assumed version 1. It didn't actually
‫even list a version in the file. As it's matured and added new features to what the file can have in
‫it, such as networks and volumes, they have created the version statement, which is actually the first
‫line in the file. This file can actually be used with a Docker Compose CLI, which we'll talk about
‫in a minute.
‫This is, again, mainly for local development management and just making it easier to get around in
‫your environments on your local machine.
‫Now, starting with the beginning of 2017, we have version 1.13 and anything beyond that, these files
‫can now be used directly with the docker command line in production with swarm. Of course, there's
‫great help at the command line with the --help.
‫As we look at some of the examples, know that the Docker Compose file is a default name, but you
‫can actually use any file name you want, as long as it's proper YAML and that you use the -f to specify
‫which file you're trying to use.
‫If I open up my editor and look at the template here, I just wanted to show some of the outline of what this
‫is supposed to look like.
‫We have the version value in the beginning.
‫The newest version in the first quarter of 2017 is 3.1.
‫But I always make it at least version 2. If you don't add that line there, it's always assumed to be version
‫1.
‫But I don't recommend that because you lose a lot of the features.
‫So I typically start with version 2. Then if I need specific features out of version 3 and 3.1,
‫I end up typing the version number in there. You'll see the other three main sections are services,
‫volumes and networks, right?
‫So, this is hierarchial.
‫Under services, everything can be two or four spaces, but it does need to be consistent.
‫If you just look up YAML on the internet, you'll find some sites that guide you with the specifics of
‫how to format this file.
‫If you're using a modern editor, it's going to actually speak the YAML language and know how to deal
‫with these files and their formatting.
‫Usually, here, you have, at a minimum, services, which is really just containers.
‫The reason they actually call them services is because each container that you create in here, you could
‫actually have multiple ones of those containers for redundancy. So they needed to come up with a different
‫word.
‫I think services is great because that's basically what you're doing. Right?
‫Each container, or containers, that are identical, that you're using are usually providing a service to
‫something.
‫Underneath the service name, and again you can call it whatever you want.
‫It doesn't have to be the name of the image or it doesn't have to be anything related at all.
‫It could be Barney for the service name, but it will be the DNS name, that we'll find out later, is used
‫inside of your Docker networks.
‫Similar to when you give the --name to a docker run command.
‫Here, I've shown that we can optionally specify the image. We can specify the alternate command to
‫run. If we wanted to overwrite the actual command that was specified in the image when we run it,
‫we can do that here.
‫Basically, all the things we do from the docker run command, we can save them here. Because that's
‫what really this is about, is taking all of the work out of remembering all the different things in
‫docker run command for those things you're running constantly.
‫If you have your own development environments, or your own tools, you probably don't want to type those
‫commands over and over. And shell scripts can only do so much.
‫Right?
‫So, this file would actually replace a shell script that would automate your docker run commands.
‫This is a much better way to do it.
‫It's easier to read and it's better documented.
‫You'll notice that spaces in here are allowed.
‫You can have spaces in comments wherever you want.
‫If you had multiple services, you just need to make sure they're unique names.
‫Then, the other parts that we specify are volumes and networks. And again, these are optional as well.
‫It's basically the same rules as when you're running from the command line.
‫If you were to ever need to use the docker volume create or the docker network create commands, and
‫again, you don't always have to.
‫It just depends on your situation.
‫You can put them here as well.
‫Let's look at a real world, simple example.
‫You remember in the last section, we had a lecture where we used Jekyll really quick to just do a bind
‫mount example.
‫So this is what the compose file would look like for that docker run command, and you'll see that I have
‫specified the image here.
‫I've named it Jekyll.
‫I've given it a volume. You'll notice instead of using the pwd, Compose actually understands the dot,
‫meaning this is the current working directory I'm in.
‫Just use this directory that I'm running the compose file from. Then the ports or the -p option.
‫You'll notice some little things about YAML, where when something only has one option, like if there's only
‫going to be one image for each service, it would usually be a key and value format like this.
‫If it's going to be a list of items, like volumes and ports where you can have multiple ones, you'll notice
‫that the compose file usually has a plural. Instead of volume, it's volumes. And instead of port, it's ports.
‫And then there'll be a list format with a -.
‫If we jump into another example real quick.
‫You'll see that in this one,
‫this is actually a sample WordPress setup where you have the database service down here that's running
‫a database container.
‫And then the WordPress web server container up top.
‫You'll notice a little thing that's different about this one is that we're using the environment
‫variables, which would be the same as a -e at the command line. But instead of a list format where
‫we have a -,
‫this is, again, another key and value statement.
‫In this format, we don't use the -, we just list the key and the value.
‫If I needed to add another one, I would just do that here. All of these would be passed into the
‫container, when it runs, using the compose command line.
‫Then lastly, we have one more example. This one is a little more complicated. It's actually one I
‫was working on recently to set up a three-database server cluster behind a Ghost web server.
‫Ghost is actually a blog system similar to WordPress. You'll see that I have multiple environment
‫variables for each one of these containers.
‫So I've got my Ghost container up top. Then I actually have this thing known as a SQL Proxy, which
‫it sits in front of MySQL servers and acts as a load balancer and failover solution.
‫Then I have each of my two, MySQL servers. You'll notice another option down here that says,
‫'depends on,' and depends on is a pretty common one.
‫It basically helps Compose understand the relationship between these services. It knows that if I
‫need to start my Ghost one, then I also need to start other ones as well.
‫You can see up here that my Ghost one actually depends on these. We'll get into the details of how
‫this works in later lectures.
‫But for now, this is probably a lot to digest, and all these different commands and whatnot, but trust
‫that Docker has some really great documentation on their website. If you just look for Docker Compose
‫file on Google, you'll probably find this with the first couple of hits.
‫It's going to be under the docs.docker.com website, as usual, and it's going to be documentation
‫about every single little key and value option you have.
‫You'll see the depends on I just mentioned. You'll see environment here where it shows different ways
‫to put in environment variables. What's great about this documentation is it gives you plenty of
‫examples.
‫Personally, I'm on this site every day, just like I'm on the docker run command options page or the compose
‫command options page.
‫I'm constantly referencing these because there's just frankly so many features nowadays that I can't
‫remember them all.
‫So I keep them close in my bookmarks.
‫Now that we have a general idea of what the compose file format might look like, let's jump over to
‫the command line and learn about the Docker Compose CLI tool.