Check out a free preview of the full Complete Intro to Containers (feat. Docker) course

The "Docker Compose" Lesson is part of the full, Complete Intro to Containers (feat. Docker) course featured in this preview video. Here's what you'd learn in this lesson:

Brian explains how to build a docker-compose.yml file which sets up multiple containers without needing to build a development environment for each container.


Transcript from the "Docker Compose" Lesson

>> So the good news for all of you right now, is that we're pretty much done with core Docker functionality, so at this point, you're pretty much I would say like intermediate users of Docker, which is pretty cool, I think. We are gonna get into some more kind of ecosystem type things, so the first thing I am going to talk about was like multi container projects which we talked about in networking, and how to connect like this container to this container.

But can you imagine like trying to get like another developer in your team to kinda do the exact same thing that we just did? It would be like a series of like nine steps and things would go wrong and be a problem, right? It would be better if we could just give it like here, run this one command, and it's gonna set up all the containers that you need.

That's what Docker Compose is gonna do for us and we'll talk about that in a second. And then we're gonna get into Kubernetes which is, deserves three courses unto itself, so, we're going to do the most basic Kubernetes thing so that you can understand what it is and what it does for you.

And then we're not gonna go any further than that, you'll have to look for other courses if you really are interested into getting deep into Kubernetes. Lastly, I wanted to introduce you to some Non-Docker kind of technologies and we'll get there with Buildah and Podman, and then we'll wrap up.

So let's go ahead and get into Docker compose, This actually might be one of the most useful things that many of you will walk away with this classroom. Docker compose is extremely useful for development environments, less so for production environments. And we'll get into reasons why here in momentarily but suffice to say, most projects have one or two servers or at least two, two plus servers running, right?

You have a database, maybe have two services running or something like that. And getting that all set up with Docker, like we saw with the networking stuff, it's possible, it's just annoying. Docker compose allows you to say here's this container, here's this container, here's this container, here's how they talk to each other, now spin them all up for me, and then you do it with one configuration file.

And then you say docker compose up, it'll do all that stuff for you. So, Docker compose says on its documentation, it is suitable for production environments, if you have like basically one host running all of your containers, which for the most part most people don't. We have multiple host running our different containers, right?

And you don't wanna be tied to one host, you wanna be able to say scale this horizontally for me, throw a hundred containers at this problem and you can't do that with Docker Compose so that's just something to keep in mind. If you have a production environment where you have many containers you want multiple hosts, your solution will be Kubernetes and we'll get into that next.

One of the most useful things as well for Docker compose it's very useful and continuous integration, continuous delivery kind of situations. You can say, hey, Azure pipelines or Travis CI or something like that, spin up all of these different containers, make sure that all these unit tests and integration tests pass, and then spin it down.

Docker compose really good at that so let's go ahead and get into it, so let's do it from our same networking project that we had with us, I'm gonna stop my server here, if it'll respond, it might not So let's just go ahead and kill it, I'm gonna kill all of my running containers right now, so I'm gonna say docker kill db and bold rhodes.

So if I look at docker ps I have nothing running right now, great. And what we're gonna do inside of this particular project is we're gonna create a new file inside of the networking, Project, right? So we're gonna use the same one, and we're gonna call this docker-compose.yml, And for me I get this nice little pink little docker container all right, so many of you may not be familiar with what YAML is, if you're not, good for you, I envy you.

[LAUGH] I'm not a big YAML fan, other people swear by it, love it, it's kind of like, I call it the Python of JSON. Cuz everything where there's significant white space, and I don't like significant white space, that's just a personal opinion I hold. So we're going to, and we'll walk through what YAML is but basically it's like JSON without all of the different quotes and stuff like that.

So we're going to code together this Docker compose file it's going to outline how everything connects to each other all the various different containers, right? So it's going to say, here's all these various different containers I care about, here's how they connect to each other. So the first thing you have to identify it to is what version of Docker compose are you going to be using.

So we're going to be using three, I'm told that version two is still fine to use like it that's kind of counter intuitive for people to think I should use three, three is the latest one, but version two, it still works as well and they actually still maintain version two of it as well.

I don't use it, so I can't really tell you what the difference is, but it is out there and still works. And then here we're gonna say services, we're going to identify all the various different services that Docker compose is going to spin up for us, all the various different containers, okay?

So this is what I'm talking about with their significant whitespace, so I hit colon here and I'm just that means that I'm gonna give it multiple things after this and then you have to indented here, if you don't indented YAML is gonna think it's another top level thing.

So we're gonna make one called the web container and we're gonna make one called The db container. The web container is going to be our project that we just quoted together with Mongodb. So, we're gonna tell it, where it's docker file is and where it needs to build it which is here where the docker compose file is, you could also say like ./Dockerfile you'd be pointing to where the Docker file is.

But if you just put it means there's a Docker file in the same directory as this Docker compose file.
>> It's gonna automatically look for it.
>> Exactly and you tell what ports that you care about, and here, you can give it like a bullet of list, right, kinda like mark down.

So we're gonna give it a build to list of what ports will be on and expose where, let's say 3000:3000, that's very much how you would run that with Docker, right? When it exposed Port 3000 on 3000. Here, we're gonna do volumes, just like we were talking about before, of how to connect our code to this.

So the first thing that we're gonna do on this one is we're gonna say our code exists at .: home/node/code. So expose everything inside of our container like our entire code base inside at home node code, so this is going to mount our code into there so that then we can keep writing code, right?

>> And that equals word directory in a Docker file, where-
>> It's like a bind mount, it's a bind mount, is actually what it is. And then we're gonna tell it that home/node/code/node_modules, treat that separately. And basically what we're saying is don't bring over the node_modules, cuz you need to install it inside of there, and then when you tell it, this is linked.

So links, this is linked to db, which means that I know these two containers need to talk to each other. And the other thing is, because it knows links first, it's gonna start db first, because if you try and start the web service first it's gonna look for MongoDB and not find it and it's gonna crash, right?

So it's gonna say, you depend on db, I'm gonna start db first, wait for that to finish starting, then I'll start web so that everything can start in the right order. And then one more thing underneath links where they give it the environment variable of where to go, which is MONGO_CONNECTION_, STRING: mongodb:// Db:27 017.

Now, you would go do this for all your various micro services, or front end services or all the different containers that you are building and starting up, for dB, it's much more simple. We've seen a pointed at which image that we want it to run, which for us is gonna be image: mongo:3.

And that's gonna be smart enough to go get that off a Docker Hub, start running it as RDB containers, this is another kind of deep rabbit hole of, things you can do, Docker-compose can do quite a few things for you. This is pretty much the most basic version of that for this.

All right, so where am I? I am in into the container, so I'm gonna go back into networking, and I'm gonna say docker-compose, that dash is important up. So one more thing before we run this, I forgot a leading slash here, so you need /home/node/code. So dot and just to kind of run through that again, the dot here says that this is going to take everything in the directory of the Docker compose, and you could have done I don't know, the whole path which for me would have been it would have been this right?

So I could have copied all of that And put that right there, I do not suggest doing that, because obviously that's very specific to your computer. What you wanna say is everything inside of this directory where the Docker compose file is, mount that in the container at /home/node/code.

And I had forgotten this leading slash, make sure you have that leading slash there, okay? And here we're gonna say Docker compose up And this should get our entire environment working. Okay, so you ran Docker compose up, and you got a bunch of output and the first thing you'll notice here is all these db_1.

So, the nice thing about Docker compose is you can actually run multiple versions of the same container, I'm not gonna show you how to do that with Mongo cuz then have to worry about sharding and replica sets and primaries and secondaries. But that's what the db_1 means it means it's the first of those various different containers running, and if it looks familiar to it's all the MongoDB output, right?

So you can see here at this point it actually receives a client connection from driver node.js, and it's running the three point three point five, driver which is one that we installed. It's from Linux and it's Node JS version 12, which is right, that's the one that we've made.

And then you can see down here at web_1, this is the output of our server that we wrote. So now in theory I should be able to click on this and open this link, And this looks very familiar to right? This is the other app that we just wrote in networking, so if I go add, and then come back here.

You notice that everything is working, so these are the logs coming from our Node JS application that we wrote right in the previous networking chapter. And if you would come over here and do like /ad everything is working the same expect it right? So like it's working on port 3000, which is what we told it to do in the Docker compose file.

And if we come over here and say go to this, you can see count: 11 everything's working the same way. But instead of having to connect everything manually to a network and say like, okay, this container talks to this one, it does it on this network, blah blah blah, you don't have to do that anymore.

We can do that just by making a Docker post file that says, this container does this, this container does this, and these ones are linked together. And then Docker just handles all of the networking business for you by itself. I'm a big fan, if you can't tell, everything's working with docker compose up.

You just shared your docker compose file with your co-workers, with your teammates and they can just say docker compose up themselves, they don't necessarily have to understand how everything connects together. They don't have to manually interact with docker networking, everything just kinda happens for them behind the scenes.

Just you now need, needs to know how to set it up and then you're done.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now