Using Containers in Production
The course is part of this learning path
This course is for anyone with a basic understanding of what containers are, and even why you'd want to use them, but who doesn't understand the nitty-gritty of how they work yet. You should have a basic technical literacy, as well as an understanding of cloud app architecture. In this course, you'll learn about the major concepts around containers. You'll learn about different container systems, learn all about orchestration, get a better understanding of how and why to build and run 12-factor apps on containers, container security issues, and you'll even get a quick look at how to get a microservices app up-and-running on your computer in about two minutes with Docker compose.
- Understand the options for running containers
- Understand the common security concerns
- Know why orchestration is important
- Understand what types of applications should be containerized
- Understand how logging and monitoring works with containers
- Project Manager
- Business Manager
A good prerequisite for this course is to take the Introduction to Containers course.
This Course Includes
- 47 minutes of high-definition video
- Console demonstrations
What You'll Learn
- Course Intro: What to expect from this course
- Microservices: Designing Microservices and 12-factor apps.
- Running a Microserve App on Compose: Demo of using Compose.
- Container Orchestration: What is orchestration and how does it work?
- Container Security: Best practices to make containers more secure.
- Container Logging and Monitoring: An overview of tools commonly used for monitoring.
- Container Systems and OSs: Different Linux Containers: LXC, Docker, rkt, OCI, and an overview of Windows Containers.
- Wrap-Up: Course summary
So in this lesson I'm going to show you how to actually get an app up and running using the Docker Compose function. I'll be doing a little bit of a live demo here, and my sound might sound a little bit different. I had to rearrange my microphones so that I could reach my keyboard and hopefully my keyboard's not too loud. We'll see how this goes. So to begin let's talk about Compose a little bit.
So once you've gotten everything containerized that can be containerized then you need some way of defining the whole system. So right now you've, you know, built your Docker files, and you have the different pieces of the system, but you need a way to spin it all up together, and network these parts together. So this is where tools like Docker Compose come in. Compose lets you write a YAML file that defines multiple types of images and how they communicate together, and then spin up the entire system in just a single command which is docker-compose up. So what I'm gonna do is I'm gonna go to my desktop here, and we're gonna take a look at how to actually do this using a example voting app provided by Docker, the company.
So the first thing to do is to go to Docker.com and make sure you have Docker downloaded. If you already have Docker installed on your computer and it's running, great. I do, I just wanted to show to do it you wanna go here to Docker.com, get Docker, and go to Mac or Windows, or if you have a Linux download, do one of the Linux ones. I obviously am running a Mac right now. I'm gonna show you how to do this on a Mac.
All the command line is the same no matter what you do it on, but it will what exactly you download and how that looks on the desktop will look slightly different depending on the version. So go to get Docker. I'm just gonna go to Mac here. Like I said, I already had it downloaded, but you just download this, run the installer. It's very quick. It happens like that. So then next I wanted to show the Docker Docs are very good. If you'd like to learn more about Compose once I'm finished here such as, you know, an overview, or what it actually looks like.
They also have more demos than I'm providing right now. I would highly recommend like looking at the Docker Compose. They both, you know, talk about the Compose file and the command line. So I'd really recommend this. It's Docks.Docker.com/Compose, and you'll get right there. And then finally let's go over here to the Docker example voting app. So this is hosted on GitHub, so I'm going to use Git to download it. If you don't have Git on your computer, you can always just go over here and click download and download the ZIP. I'm gonna actually copy this 'cause I'm gonna need that.
So let's first download this. So over here in the terminal which I already have open, but on a Mac you can open by hitting command space, and then typing terminal in here and hitting Enter. So once you have the terminal open we're going to want to navigate to the folder that you want the files downloaded to, your new voting app code. And so I'm already navigated there, so we're going to do git clone and then that URL that I copy and pasted, that were copied earlier. We're going to paste that here and hit Enter. And so Git does a clone which downloads all of this.
So now I can cd into the example, example voting app, and cd has changed directories. So I'm moving it to this directory. Do a list files and here we go. So we're inside. We've downloaded all the files. You'll see some of the files here are Docker Compose, Docker Compose simple, et cetera.
So these are different Docker Compose files. We're just going to be ending up using the default one. So I'm going back here. I'm just gonna show you kind of like what exists here. So you can both look at what you've downloaded in the directory, as well as look at all of these files here on the web because they're the exact same now. So I wanna just take a quick look at the web and look at this. So first the read me file, and this is really handy. GitHub posts the read me file for you, so pretty much the Getting Started here is download Docker, download this directory, and then inside this directory, which is where we are in the terminal, we're going to run docker-compose up, and you're going to see it like spinning this stuff up.
It'll take a couple of minutes to spin up, but one it is, it'll be running, there's two different places you can go, because there's two different web views for it. They also give you examples on how to run it on Docker Swarm, we'll be talking about Docker Swarm in the next lesson, it's an orchestration software, but don't worry about that right now.
After the next lesson, you'll have an understanding of what that is. And here you can see what the different microservices do, so this is a pretty simple app, in that, each service only talks to one other service, this is a kind of a round about way. So there are these two web interfaces, one written in Node.js, and one written in Python. One, you get to vote on, that's written in Python, and the other one, you see the results of the voting, and from here, once you vote, it gives the vote into a Redis database, which in-memory database, it's cache. Then there's a .NET worker that takes the information from this first in, first out cache, and adds it to the actual database, this is the storage database, and we're using PostgreSQL here, and then from there, the results app reads the results inside of the database to see, you know, what's actually going on.
So those are the pieces, the one other thing it wanted to do is actually look at the Compose file, I'm just going to do that here, because it's simple. I'm not going to go into what every single piece of this does, I recommending going to the Docs to do that. But what you can do here is, so the idea here is that you define the services, first, we're running Version 3 of Compose, there's three versions of Compose, this is the latest version. And what you do is, you define the services, so the first service is the vote service, here there's a build command, so Compose can do two things, one is that it can download images from a registry, whether that's the public registry, or your own private, trusted registry.
We'll talk more about what registries are in the nest lesson, well actually, no, maybe one or two lessons after that. But anyway, it will either download an image from the registry, or it will build an image from a Docker file. So you see here, inside of the vote folder, there is a Docker file, and this Docker file defines what this image looks like. So we're not starting with an image, what we're actually going to do is, inside of this, once we run docker-compose up, it's going to build this image for us. And, you know, it's going to build the image, it's going to run a specific command here, which is going to be the command that starts the Python app. It's then going to mount a volume, and from there, it's going to also open up certain ports, so that we can get to this image, and this opening up a port that says that we can actually get to it from the web,, you know, in this case, it's just going to be on my computer here.
And then it also networks it to different networks and you can see here that the two services that we can get from the web, which are the voting service and the results service, are in the front tier network, and then all the services are on the back tier network, because all the services have to talk to each other. But the services that are only on the back tier network, can't actually speak to each other. We then define the volumes, and the networks, these are just like kind of empty placeholders, because Docker knows what to do with them, you don't have to define anything more to it.
So that's that, let's go over here and run the command, and see what happens here. So, docker-compose up, so there are two main Compose commands that you're going to need to know, it's docker-compose up, and docker-compose down, up, obviously spins up your app, and docker-compose down, turns off the app, pretty much. So let's run docker-compose up here, and see what happens. Great. So you can see here, this is information coming at us from the system itself, it's going to take a little bit to do. Now, one thing to note is that, I've already built, so I've run docker-compose up on my computer already here, so I have these images on my computer, and since there's nothing new in the images, it didn't have to build the images. The first time you run this, it's probably going to take somewhere between five and 10 minutes to build the images, part of this is because building the images requires downloading Python and Node.js, and these other kind of large packages from the web.
So it's going to actually, you know, kind of like, start with a default loop onto image, and then it's going download these different packages into each of those images. So each image will take a couple of minutes to actually download and start up. And then once you have them, it goes really fast, it knows that everything is up. So this should be up and running at this point, it's connected to the database. And from here on out, you won't actually see anything happen.
So what we can do now, is go back to here, and where's it say, so we want to go to local host 5000, and see if we can vote. Whoops, don't usually use Safari. Great, so we can get to it, so it's up and running. And you'll see over here, that, after I did that, we're seeing the logs from vote 1. So this is the first container created from the vote image, if you're running Smore, you might have multiple containers, from each image, we'll talk about that, again, in the next lesson, as we talk about orchestration software.
But you can scale horizontally, which means you'll have multiple of the same container, and it doesn't matter which container you're hitting, you'll get the exact same thing. So again, let's, cats versus dogs, what do we vote? I have a cat, I don't have a dog, so, cats, and then, over here, oops, again, not used to this. 5001, great. And now we see the two votes. It says two votes here, because again, I've actually spun these up before, and it's saved the database to my computer. When you spin it up, you'll see one vote, whichever it is you voted for. So I can change my vote, so over here, I'll go to dog, and now dogs is at 100%, we see all of this happens like, very seamlessly.
The containers are speaking to each other, even though, as you can see here, you know, we have vote is written in Python, it's just one small Python file, which imports a bunch of things, and then, you know, displays this. And then over here, the results are written in a completely different language. And then the other thing you'll see is there's the worker, but there's no registered database, we're using just default, for that, so I'll go back to the docker-compose here.
So you know, I mentioned that we have to build the vote, the result, and the worker apps, we don't have to build the Redis and the database apps. See, these apps are actually downloading from the public registry, so here, you're just downloading the Redis image, and running the default, and we're using completely default settings on it, same with the PostgreSQL database. You'll see the image, the way it works here is, you have the image name, and then the version of it you want. If you just put the image name after image, it will download the latest stable version, I'm 99% sure on.
And, but most of the time, you want to actually say like, you know, it's been built for this version, who knows if something will break in later versions, so you want to say the specific version there. So yeah, so that's that, it's a very simple app right, I mean, it's something that, like I said, we can actually you know, read the voter code here, , all on like, more or less, one page. Same with the results code, it's similarly simple. But what it does show is that you have all of these different services running, each service is running a kind of 12-factor service, where it's, you know, like, it's displaying an API, that the other services can work from, and it's all running on Docker with a single command. Like I said, it's faster on my computer, because I've already build this stuff.
It will, again, take probably about 10 minutes to download, and start everything. Also to note, and this has happened on my computer, it doesn't happen on most computers, which is, the first time you run Docker, or the first time I run docker-compose, if I have to build elements, often times, the docker-compose itself won't work, which is a pain, So it'll build everything, and then it'll hang when trying to connect to Redis, in particular. I don't know why this happens on my computer, if it does happen on your computer, the thing to do is, to hit Ctrl + C, and this is true whether you're on a Mac or a PC, you don't want to hit Cmd + C, you want to hit Ctrl + C. And I'll do that now, and that'll gracefully stop everything, so it'll kill everything, and then when you write docker-compose up again, it'll spin them up and it usually works just fine the second time for me. So I wait for everything to download, for it to actually like, get to this point, where it's trying to spin up, and it'll hang on Redis. I'll kill it, I'll start it again, it'll work just fine. You know, you might have your own things to troubleshoot on your computer, you know,, unfortunately, this stuff doesn't always work perfectly.
But it works pretty good, and again, I've never had a problem on any other computer, except for my own with this. And when I was working with the Docker people, they were confused as to why it was happening on my computer as well. So yeah, that's that, that's a very just quick, I wanted to give you a brief overview, to see what this looks like in contact. So now what we're going to have to do here, so one final thing, once you've run it, you know, I've been saying docker-compose down, docker-compose down, obviously, this doesn't do anything, because it's not listening to, we're not in the command line anymore. We're just watching the logs as they come in. So you have to hit Ctrl + C here, again gracefully stop everything. So once this is stopped, ah, oops, sure, reset it. So it's not running anymore, you'll still want to run docker-compose down, because these are stopped, but they're not fully like, shut down, the images.
So there, so now I've removed the images from the network, instead of just stopping them. So it's no longer using any resources at all, before when it stopped it, it was using a few of the resources. So yeah, that's that, you know, you can run, you can Compose up and Compose down really quickly, this kind of gives you a sense of like, once everything is built the first time, you know, you can test this really easily. So now I'm going to show you how you can use docker-compose to edit test code really quickly.
Sorry about the jump cut there, I had accidentally made a mistake while recording last time, so I'm doing this again, we'll get it right this time. Great, so the, what I have here, we've run docker-compose down, so everything's off, and not running anymore. And then what we're going to do is, cd into the vote directory, let's take a look at everything, great, and I'm going to use a software package called Nano, to edit the app.python page. VIM, Emax, whatever, you know, if you want to use text edit in your GUI, whatever you use will work here. I just use Nano, because it's lightweight, and easy to use for text editing in the command line. So here, I'm going to change this to rabbits, and change this to birds, and so what we'll see here is, the display names should change, because I just changed what the display names are in the Python app. So now I'll hit Ctrl + X to exit, yes, we need to save it, rewrite it to the same app name. So now we need to cd.., which puts us back into the main directory here.
Now we can run docker-compose up again. And so it's recreating these images, but it's not rebuilding the images, which is slightly different. So when we run Compose-down, we delete the images, or we delete the containers, but we still have the images. So this is rebuilding the containers from those original images. However, when we move over here, and go the to the local host, and we hit Enter, you'll see that rabbits and birds have now come up. So we are using the new code, even though we didn't rebuild the image. The reason that that's works, the reason that that is working is, because in the docker-compose file here, you'll see that we mount the volume with the code in it.
So when we restart the container, which is what docker-compose up does, we're adding the new code to the container, without rebuilding the container as a whole. This works because we're running Python, which is a scripting language, so we don't need to recompile anything, it's just whatever the text on the computer is, that's what is going to run. And so because of the way that this is cleverly worked here, and we have a scripting language, we can actually see that language with a simple docker-compose up, without having to rebuild anything. You'll also notice, if I click this, like some stuff happens, I'll leave this an exercise to you guys, I wanted to change something really quickly that we could see, but it's not, I haven't actually changed everything correctly.
So also, it's on me. In the Python, not the Node.js, that everything's changed, you have to go and change in the database as well. But that should give you an idea of how useful this is, I mean, as you see the Docker, or oops, like, let's kills this. And docker-compose down. Removing those containers, even though the images are still built, the container is no longer running, and have been removed entirely from the engine. Yeah, and so that's all took, was, you know, two seconds of me typing out some code and hitting compose-up, and I get to see whether it works or not. And, you know, it kind of works, it doesn't fully, but that's exactly why we want to test it on our system before pushing it out to production.
One final thing here, if you ever do something where you actually need to rebuild your images, you can do that by running docker-compose up --build. Or simply writing docker-compose build, so docker-compose build, will rebuild any of the images that have the build tag, here, like this. And docker-compose up --build, will both, rebuild those images, and start everything up, as if you were running, as if you were running docker-compose up for the very first time.
So for instance, I can hit this, and it's going to go through what would look like the very first time, you run docker-compose build probably. So it rebuilt everything, it, hey, this time it worked, it didn't hang, which is nice, it didn't hang on Redis. So I rebuilt the images, and if I do this, sure, resend it, great, it's working again, so it's still up and running. So that's a little bit on how to use Compose, and how to use all the various tools that Compose offers. One final bit, if you go over here in the docker-compose Docs, I'd really highly recommend looking at these, and looking at all the commands that come with Compose.
Like I said, build, let's you rebuild the services, up and down are kind of the main things you'll run. You'll also be able to list the images, to list all the containers running, and that's the difference between the, you know, the image is like, what the containers are build from, so pretty much anything you could do with an individual container using Docker commands, you can do with a whole system of containers, using Compose commands, which makes it really, really useful, when you're checking on the health of your system overall.
Or when you're testing it on your computer, for instance. So that's that, I hope this was a helpful overview of Docker Compose, and gives you chance to get it up and running on your own computer. I would recommend, you know, you can either move forward now, and continue learning about running Docker in production, or you can also, if you want to take a little bit of a break, go to Github.com/DockerSamples/ExampleVotingApp, and clone or download this code, and try to get it running on your computer.
It's a fun kind of exercise, to actually see it working, and you can, you know, try to hack it yourself, and actually get the code working as well. So that's that, thanks for watching, and we'll see you at the next lesson, in, you know, a couple seconds here.
Adrian M Ryan is an educator and product manager. He was an early employee at General Assembly, has co-founded an education startup and a consultancy, and he loves teaching. He grew up in rural Alaska, and while he now lives in New York City he makes sure to find time to get out in the woods hiking whenever possible.