What you'll learn
- Explain how Dockerfiles, images, and containers relate as the stages of running an isolated application with Docker
- Create and run a simple Dockerized app using a pre-built image pulled from Docker Hub
- Build a custom image from scratch with a Dockerfile using RUN and ENV instructions and the docker build -t command
- Manage containers and images by naming, starting, stopping, attaching with exec -it bash, and removing them
- Configure a host folder mount so a running container serves external, persistent data that changes in real time
- Set up a data-only container that lets separate containers share input and output independently
Free 126-minute video lesson with a full transcript and knowledge checks. No account needed to watch.
Overview
Docker is a container management system that virtualizes application environments, allowing for higher density server usage without the need for additional hardware virtualization.
Intro
Docker is an incredible and flexible tool that will likely benefit any server infrastructure. In this course we learn what Docker is, what it does, and how we can take advantage of its features!
Knowledge Check
Docker will have the ability to completely isolate applications from each other. True or false?
Containers vs Virtual Machines
Docker containers are a form of virtualization, but they're different than the traditional virtual machine concept. In this Nugget, we learn the differences, along with the advantages and disadvantages of both.
Knowledge Check
A Container deployment requires a Hypervisor just like a Virtualized Hardware deployment. True or false?
Knowledge Check
Containers offer which of the following benefits over Virtualized Hardware? (Choose two)
Select all that apply.
Knowledge Check
Docker containers are very comparable to Linux "Jails". True or false?
How Docker Works
Conceptually, Docker containers are great. In this Nugget, we learn what Docker actually does, and how it creates, manages, and maintains images and containers.
Knowledge Check
Before a Container can be built, the Dockerfile must be:
Knowledge Check
The Docker community source for pre-built Images is known as the ______ Hub.
This interactive assessment is available in the full learning experience.
Docker Installer (Deconstructed!)
Docker runs on Windows, OSX, and Linux. It's most common implementation is on Linux, and in this Nugget, we learn to install it. Because Docker containers aren't dependent on a specific host operating system, you can use whatever distribution you like (for the most part)!
Knowledge Check
Which of the following methods should be used to get the most up-to-date version of Docker?
Knowledge Check
The command to verify the version of Docker installed is ____________ version?
This interactive assessment is available in the full learning experience.
Create a Simple Dockerized App
The easiest way to start with Docker is to download a pre-made image from the Docker Hub. Using the community-driven repository enables you to get common apps downloaded and running in minutes.
Knowledge Check
Docker is limited to running in the same Linux distribution environment that your host machine is running in. True or false?
Knowledge Check
You can reference your containers via which of the following? (Choose two)
Select all that apply.
Knowledge Check
You can view the output of your container by using the Docker _____.
This interactive assessment is available in the full learning experience.
Managing Containers and Images
Once you start creating Dockerized applications, it's easy to fill your system with old images, stopped containers, and a plethora of outdated versions of your application sitting around on your system. In this Nugget, we learn to identify how images and containers should be treated, and the commands to manage them.
Knowledge Check
Which of the following describes one way in which Containers differ from Images?
Knowledge Check
You can pull images locally before creating containers from them. True or false?
Knowledge Check
To delete a local image use the command: HINT: sudo docker ________
This interactive assessment is available in the full learning experience.
Knowledge Check
Which of the following commands will list the containers on your system? (Choose two)
Select all that apply.
Networking
Most applications in a Docker environment need to have network connectivity. In this Nugget, we learn how Docker handles the IP addressing for containers and how we can access them from the local network.
Knowledge Check
Docker Containers piggy-back onto the host's default (eth0) network interface. True or false?
Knowledge Check
Which of the following commands would you use to learn the Container's assigned IP address?
Knowledge Check
You should use the Virtual Bridge Network IP Address to access a website in a Docker Container. True or false?
Advanced Networking
Docker's default bridged networking is robust and elegant, but does have a few shortcomings. In this Nugget, we learn to map ports to the host IP address, and also how to circumvent the entire bridged networking system to share the host IP with our containers.
Knowledge Check
The default Docker network setup allows computers on the host network to communicate directly with the docker container. True or false?
Knowledge Check
Expose or "Publish" a port in the container to the host network with this switch:
Knowledge Check
If needed, you can specify the port on the host network to forward to your Docker Container port. True or false?
Knowledge Check
The command to expose your container directly on the host IP address is _____.
This interactive assessment is available in the full learning experience.
Shared and Persistent Data
Docker containers are designed to be ephemeral, so it's not ideal to store important data inside the running instance. In this Nugget, we learn to mount external volumes from the host system, so that our data is stored safely outside the running containers.
Knowledge Check
It's generally considered best practice to store your data locally in a Docker Container so it can be transferred as your Container moves. True or false?
Knowledge Check
Which of the following commands would you use to mount a local directory in a Container?
Knowledge Check
If you modify a file in the local system that's mounted to a Container, those changes will be automatically visible to the Container. True or false?
Modifying Containers and Images
Occasionally, an image is almost exactly what we need, but not quite. It's possible to connect to a container, make internal changes, and then save that container as an image. In this Nugget, we learn the nuances of working with custom images created on the fly.
Knowledge Check
You have to use the random Container name that Docker provides when you run an Image. True or false?
Knowledge Check
Which of the following commands can be used to connect, or attach, to a running Container? (Choose two)
Select all that apply.
Knowledge Check
The command to save a customized Container to a new Image is _____.
This interactive assessment is available in the full learning experience.
Creating Images from Scratch
In this Nugget, we learn to create our own custom image, but rather than basing it off an existing image, we start from scratch with a Dockerfile. Building images from scratch is a perfect way to make sure you have only what components you want in your running containers.
Knowledge Check
Which of the following is the "recipe" used to describe a Docker image?
Knowledge Check
You include the FROM command at the top of a Dockerfile to specify a Base Image
Knowledge Check
Which of the following commands would you use in your Dockerfile to specify any commands to execute when the Image becomes a Container?
Knowledge Check
Which of the following commands can be used in your Dockerfile to include an external file? (Choose two)
Select all that apply.
Containers Working Together
In this Nugget, we combine the skills we've learned throughout the course to create containers that work together in order to provide a complete service. We also learn to use "data only containers," which makes shared storage portable.
Knowledge Check
Which of the following is an advantage to use a Data Volume Container?
Knowledge Check
The command to mount the Data Volume Container in a new running Container is:
Knowledge Check
Your Data Volume Container needs to be running in order to be used from other Containers. True or false?
GUI Tools for Docker
We've learned to do all the heavy lifting with Docker on the command line, but there are some GUI options available as well. One in particular enables Windows and OSX users to take advantage of Docker!
Knowledge Check
DockerUI is stored in, and accessible as, a public Image on the Docker Hub. True or false?
Knowledge Check
This element of DockerUI provides charting and graphing of all of your Docker Containers and Images:
Knowledge Check
Which of the following does Shawn recommend if you'd prefer to use a GUI interface? (Choose two)
Select all that apply.
Conclusion
I hope this has been informative for you and I would like to thank you for consuming.
View Transcript
Intro
0:00I am so glad you decided to start this Docker course. My name is Shawn Powers. I'm the guy in the picture right there with the cool little beak. No, of course not, but that's me in the picture. And I don't know about you, but I've been hearing about Docker so much, and if I'm completely honest, I didn't understand what Docker was. When somebody would say, oh, isn't Docker awesome? I would usually fluff it off with a joke. I would say something like, yeah, it's really great. I'm really happy to see that the Twitter fail whale got a new job after Twitter is now so stable. It doesn't have a job anymore being the Twitter fail whale, so now it's over here and it's the Docker mascot or whatever.
0:36And then, ha, ha, ha, everybody would laugh and then we'd go away, and I wouldn't have to talk about Docker. I didn't know, and maybe you're in that situation as well. Maybe it's around a water cooler you're standing and talking about all sorts of nerdy things that people talk about. And then the topic of Docker comes up and somebody's like, oh, man. Docker has just saved my life. I virtualized the data container and now my two subsequent containers are communicating with that in a virtual volume. It's so great! And your eyes start to glaze over and you slowly start to step away from the people.
1:08And they're like, hey, Sean, what about you, man? Don't you love Docker's ability to just completely isolate applications from each other. And I'm like, oh, yeah, it's awesome. In fact, I got to go Dockerize some stuff right now, and turn around and run away. If that's you, or if maybe you just want to learn more about how Docker works on the command line. You want to be able to utilize it. You know what it is, but you don't know how to use it. This course is for you. We're going to dig into Docker. We're going to use it, set up applications, create our own applications, Dockerize those applications.
1:40Learn all those fun buzzwords so that you can sound really nerdy at the water cooler. And at the end, you're going to understand what Docker, know why Docker is important, and why you should be utilizing it in your environment. I hope this has been informative for you, and I'd like to thank you for viewing.
Containers vs Virtual Machines
0:00In this Docker Nugget we're going to learn the difference between containers and virtual machines. Because they're very, very different although they kind of do the same thing-- one, like I said, in a little bit different way than the other. We're going to learn about virtualized hardware, which is what we're probably most familiar with. It's been around for a long time. And then I'm going to introduce the ideas of instead of a virtualized hardware, we're going to just have a virtualized environment which leads to great, great efficiency. And that's really what Docker provides: speed and efficiency over traditional virtualized hardware.
0:34So basically what is it, what's the difference? If you have virtualized hardware and you have Docker containers, what's the difference? What do they look like in practice? I've drawn out two different systems. So this outside black box here, this represents like the bare hardware, like the hard cold metal, what it means to be a server. Or I guess it could be a cloud, but that kind of ruins my whole bare metal example. Just imagine here that we're talking about a traditional virtualization system versus a traditional server running containers.
1:06So outside we have this outside layer, and this is the hardware. Inside there we have to have this blue layer, which is the operating system. So this is going to be like your Linux operating system. Or if you're doing like a one stop shop virtualization-only system like VMware, this operating system could be ESX or ESXi, and this is running on the system. On top of that is a software program or process or processes called the hypervisor. And what the hypervisor does is make teeny tiny little fake metal boxes, if you will.
1:40So notice there's black boxes inside of here. And what the hypervisor does, is it creates a virtualized hardware environment. So inside each one of these virtualized hardware environments, you have to have another operating system just like on the main system itself. So there's an operating system running inside of a computer that's running an operating system. But the hypervisor kind of carves up the resources into all of these pretend servers. As far as the operating system here knows, this is bare metal that it's installed on, because that's what it sees.
2:14It sees a complete set of hardware. And then you can run your applications inside that virtualized environment, that virtualized hardware environment, and run it separate from every other app that's running on this big machine all together. Now how containers work. They conceptually work the same, in that the applications run separately from each other. So over here they do this by creating virtual hardware machines. Over here they do it by creating containers.
2:45And it's a little bit more difficult to explain, but it's not that bad. You start out the same. You have this box, this metal box hardware, running an operating system. Now this operating system is going to be like Linux. There's not like an operating system like ESXi. This is just an operating system like Linux, Ubuntu, or CentOS, or whatever your favorite Linux operating system. Or actually it can run in Windows and OS X, too, but more about that later. But this is your underlying operating system. And inside of there it creates these tiny little isolated containers.
3:16They're called containers, and they're isolated away from the other parts of the computer. So while it doesn't create an actual virtual hardware where you have to install an operating system, it kind of separates these apps so that they don't see each other. They're in their own little world. Kind of like if you ever saw the movie The Matrix, you know, where all the people are kind of plugged into this big horrible machine that sucks their energy out. Well they're all in there, but they don't really see each other. As far as they know, they're alone in there.
3:47And maybe my Matrix example kind runs out because they don't know that they're in the horrible machine all. Nonetheless, they're isolated from each other. And while you don't have to have a complete operating system in each one of these little containers, you do have to have dependencies. So I kind of drew a little tiny blue line because you have your application and all of the dependencies. So what do I mean by dependencies? Well, let's say this is a web application. Well, this web application is going to need like PHP.
4:18Let's say PHP 5. So you're going to put PHP 5 into this thin little bunch of dependencies and anything that it needs like that. Now the nice thing is since they're separated, let's say this app here needs PHP 4. Well, that's not a problem. Because this little bunch of dependencies can be added to just this tiny little container, this tiny little isolated environment. And all of the dependencies that app needs are there. Now they don't run on a separate OS like they do over here in the virtual machines.
4:49They're all running on this single operating system. So there's nothing to boot up to run this app. You're just running the app in an isolated way. The operating system it functions on is the same for every app. Like every app knows that it's running on Ubuntu, and it's running on this same Ubuntu. But it doesn't see anything else. Everything else is isolated and separated. If that's confusing, just realize the advantages of doing this. One, it's very efficient because we've eliminated this virtualized hardware and the virtualized operating system.
5:24We've eliminated all that. There's less OS maintenance because you only have one operating system to keep updated and secured and patched and firewalls and all that sort of stuff. Whereas over here you have not only the host operating system like ESX, but you also have this operating system and this operating system and this operating system, and you have to keep them all updated. The other advantage is fast deployment. When you run one of these apps over here in the virtual machine, you have to boot up the virtual machine, wait for it to do all of the things that a computer does when it boots up, and then launch the app.
5:59Over in this environment, the computer is already running. The operating system is going. All you need to do is start the app. I mean, literally it's just like, OK, I'm going to start an app like you would start any other app. Except with containers, they're completely contained in their own little world, in their own little environment. Now there are some advantages to the traditional virtual machines, as well. You can mix operating systems. Here I could have Linux installed here, Windows installed here. If I hack things right, I could install OS X over here, and they can all be running on the same host operating system because it creates a hardware virtualization.
6:36You have to install an operating system, so it can be any operating system. Whereas over here there's only the single operating system. So everything has to be designed for that platform. So while you can use containers in Windows and OS X and Linux, all of the applications on a single device have to be running on the underlying operating system. So that is a limitation. It's more flexible. And what do I mean by that? Well, I mean with virtual machines because-- the next bullet point here that they're so mature-- because of that maturity, you can like migrate live running machines over to another host machine.
7:12And you can do live migrations. You can do failover stuff. The whole world of containers and Docker and all that stuff isn't quite that developed, that mature, and that robust yet. If you have an app running here, you can migrate it to another server, but it's not like a "hot" moving like it would be with one of these virtual machines. Now I think we're going to see more and more and more of that stuff as we continue to abstract the idea of what the operating system is, but I'm getting a little philosophical right now.
7:42So for the point of Docker, you have to know that it's not quite as mature or as flexible as virtual machines, but the advantages make it so awesome and so worth it. One last little tidbit that I want to mention because I get this question a lot from Linux users. Like if you're a Linux user, you're probably thinking, isn't that just the same as a jail, where you log in, and you're isolated, and you can only see whatever your jailed environment is? Well, how a jail works is, let's say I have an FTP running on this server.
8:12So this is a representation of the file system on a server. So if I have an FTP server running, when I log in-- if we have the FTP server set up in a jailed environment-- when I log in, the only thing I'm going to be able to see is my personal folder. So if I were to type something like ls -l /, it's going to give me the directory contents of spowers, because that becomes my root directory when I'm jailed into spowers. So really what this does, it's a little bit like Docker in concept, but only when it comes to the file system itself.
8:48Everything else of the rest of the system-- all of the dependencies like PHP and everything-- it's all going to be the same version. The only thing that jail does is isolate the user who's logged in from seeing any other files on the system. So it's like a teeny tiny baby version of a container, and it's obviously a security thing. We don't want people who are logging in via FTP as spowers to be able to see tsmith stuff or stuff in the boot directory or anything like that. So that's what a jail is. It is like one step towards the idea of containers, but it's not all the way.
9:22It just restricts users from seeing other files on the system. If your interest is piqued, I'm excited. Because it's a really awesome technology to learn when it comes to containers versus virtual machines. Unfortunately, the world of containers is kind of confusing at first. So I want to dispel all of that and reassure you that it's not complicated. It's just really cool and a new way of thinking. I hope this has been informative for you, and I'd like to thank you for viewing.
How Docker Works
0:00Well, it's great to understand how Docker works. It's important to know that Docker, itself, is not the technology that allows us to do things like use containers. So in this Nugget, we're going to learn exactly what Docker's role is in this whole containerized version of applications. We're going to learn about what Docker files are, what they do, images, and then containers, which are kind of, like, buzz words in the Docker world. But they'll make sense because it's kind of like three different stages to utilizing the Docker technology in order to best use containers, which again, like we've learned before, is a way to isolate applications so that they can work, regardless of the kind of a server they're hosted on.
0:41Now, before we talk about how Docker itself works and what its role is, let's talk about the three different steps, or stages, for containers working in a Dockerized system. First, we start with a Docker file. And it's called Docker file. And it's basically like a recipe for how to create an environment that the application is going to run in. So, you know, you have things in the Docker file like dependencies that are needed, like I need PHP, I need EngineX installed, and I'm going to need a Java environment.
1:11And we're going to do that on top of all of the, oh, let's say, Debian system dependencies. Now, again, it doesn't mean that the host has to be running Debian. It's just saying, in this particular container, that's the system that we need. These are all the dependencies and applications that we need in order to have our container work. And then this Docker file is then compiled into an image. Now, an image is not something that is run directly. Think of an image as kind of like an ISO file for installing an operating system-- everything you need to run is in there but you don't usually run it off the CD, not unless it's a bootable CD, but just pretend those don't exist.
1:50Images don't actually run the application. It just contains everything that is specified in the Docker file. So you follow the Docker file, which is like a recipe, and this is what you get. This is your end result. This is the baked cake that is everything you need in order to function, OK? From this image, we make containers. And basically, what it does is it clones this. So it makes a copy of everything in the image and it turns it into a container, which is what actually executes.
2:20So the image is just like a baked cake that we take slices off of to make containers. Now, the cake and slices thing doesn't work well because it's actually-- containers are an exact copy of the entire image. So it's not like we really take pieces off of it. It's actually a complete copy of the image. But we make a copy and that's what actually executes. So we can make multiple copies of the image, the same exact image, and we can have containers that do the same thing, which really makes it scalable and kind of awesome.
2:54But these three steps are vital to understand because Docker's role is to manage every different step. So what Docker is? Docker is not the container technology. Docker is the arrows in my illustration here, right? Docker does everything in here. It, actually, is the tool we use to create an image from a Docker file. Docker, you know, our cool little whale guy over here, he says, OK, I see your Docker file. I will create an image. And then the Docker program creates this image. And then when you want to spawn off a container, the Docker engine is running, and it says, OK, I'm going to take the image that you created from a Docker file and I'm going to clone it into a container and execute that container.
3:38So Docker, the whale, the Docker program, the daemon, however you want to think of Docker, its job is to facilitate all of these different steps. And that's what makes automation so much easier with Docker than if you're trying to create containers on your own. Because again, the Docker program is not the technology that allows containers to execute. That uses existing container technology that has existed for years. Docker is just kind of the shipyard manager here that makes all of this possible and easy and simple to replicate, simple to scale.
4:13So Docker makes a process that used to be difficult simplified, easy, and organized. You know, the whole concept of a Docker file alone is awesome. That's how we create the images. Now, one more cool thing that Docker has a built into it, is the ability to get rid of some of these steps. Because if you want to create a web server-- like here, I have things here that look like they're creating a web server-- PHP, EngineX, Java. That's the kind of thing-- we'll say that this container is a web server, OK? If you want to create that image, you can go ahead and you know, write a doctor file on your own.
4:48Or you can go online where people have already created a bunch of images. So this could be a web server-- this thing. And on your computer, whether you're in a home environment, in a school, or office environment, you say, you know what? I want to run a container that is a web server. Well, what you can do is download from Docker Hub a premade image. It's premade, it's updated by the person over here who wrote the original Docker file. They make their images public.
5:20You download an image that's somebody has made professionally, and you don't have to worry about getting all the dependencies right. This image is already all set. You download it and you execute it. So Docker is not only this daemon that allows you to manage all the steps of the containerization process-- is that a word? I don't know. But it's also a community of people that work together to make it simpler for everybody. It's truly, truly awesome. And if you're still struggling with the idea of what does it mean to containerize an application?
5:53I just don't get it. Well, I urge you to look at the Nugget we did on virtual machines versus containers. But also, if you were around when the portable apps phenomenon was really popular-- and a lot of people still use portable apps real like download a program and run off a USB drive and take it anywhere and it all the dependencies are stored on that USB drive in a folder so you don't have to install anything on your system. That's kind of what containers do, but they scale it up to a server world where everything in here is self-contained. You don't have to worry about if you have, you know, the proper versions of PHP and that sort of thing installed.
6:28This whole Docker process depends on you already understanding how containers work and why they're awesome. Because Docker just allows you to do something awesome in an easier, more efficient way. And truly, that's the goal of this Nugget. I want you to understand what Docker is and almost more importantly, what Docker isn't, right? Docker is not the technology of containerized applications. Docker is just the system that allows us to do something that's been around for a while and make it flexible, awesome, scalable, community-driven, just really, really cool.
7:04I hope this has been informative for you. And I'd like to thank you for viewing.
Docker Installer (Deconstructed!)
0:00Now I know we really just want to get in there and get Docker installed so that we can get creating and doing all sorts of Dockery things. But I want to talk a little bit about the installation process itself. Because while it's super simple, the installation process seems too simple. Like really, it's an evil whale that's trying to take over our system by letting us do some scripts that just magically happen. I don't like magic when it comes to computers. So I want to show you what not to do but I also want to show you what the installer actually does on your system. And what can make things super, super confusing is that if you do apt-cache search for docker, you're going to see that in your repositories you have Docker already there, ready to install.
0:40Here's the problem. It's a super old version and it is not updated regularly, so you're definitely going to want to get the latest version directly from Docker. Now how do we go about doing that? Thankfully, it's super simple. This is the part that's so easy it's creepy. All right, if you go to get.docker.com, which we've done in this web browser right here, and you can see there's just a couple simple instructions. What we're going to do is we're going to use curl to download the script that you actually see on this page. It's a little meta here. This is the actual script that starts here. And if you'll scroll down the whole page, you'll see the whole web page here is just one batch script.
1:14And this command will allow us to download it and save it as a file called get-docker.sh. So let's do this really quickly. So I'm just going to Paste. And if we do an ls, then we're going to say, sure enough. There is get-docker.sh. Now I'm going to change it so we can execute it. So chmod + x get-docker.sh. And now if we look over here, see it says just sh get-docker.sh. So we can do that. sh get-docker.sh and it's going to walk us through the process of actually installing the latest version of Docker right from docker.com.
1:50And that's what we want because we want to have all the latest features and the most updated version. Now the really cool thing is, while this is all automatic and I don't necessarily like executing random scripts on my computer with root access, here's the deal. This is going to not only install Docker and like put it in a binary place, it's actually going to download the repository information so that we can keep it updated using apt-get. And I'll show you where that goes as soon as it's done downloading and installing. And just like that, it's done. Now it does say that we can make some changes to our system if we want to make it so that we can run Docker as an end user.
2:24We're just going to be running Docker with root privileges, but you can do this if you want to set up a system that's going to be permanently using and you got to make sure that it's as secure as possible. But Docker is installed. If we go over to the etc/apt folder and go into sources.list.d, we can see it's created an app list file. And if we look at that, we can see so now it's going to download the latest stuff when we do something simple like apt-get update. And when we do an apt-get update, it's going to pull information from the Docker site as well, not just one that is in our existing Ubuntu repository, because again that one is really, really old.
3:01And you can tell we have the new version because if we type docker version, boom, it's going to show us. We have Version 18.06 here. And it's OK if this isn't the version you have. The point is, we want to make sure that we're using the sources list from Docker so that we get the very latest version from docker.com. I hope this has been informative for you and I'd like to thank you for viewing.
Create a Simple Dockerized App
0:00It's great to understand conceptually how Docker works and how containers work in a system. But for me, until I actually see it in action, it just doesn't make a whole lot of sense. So in this Nugget, we're going to create a simple Dockerized app and actually run it in the real Docker environment. Now, it's going to do a couple things. We're actually going to get to look at Docker Hub, which is an online repository for pre-built images that we don't have to build from scratch, we can download. We're going to learn what images actually are, how they work, and where they're storing all that sort of stuff. And then we're going to see how logs work, because when we do a Dockerized app, if we want to see what it's doing, we need to look at the logs, because it kind of just goes in the background and runs as its own background application.
0:41So let's just do it. Let's just create an app, put it in the Docker environment, and see how it goes. And then we'll explain and learn about what it does along the way. So first of all, what apps are we going to Dockerize? Well, I like simplicity, so we're going to do a very simple app. Let's see it right now. Now, we could use any application and Dockerize it. Usually, people use Apache, because it's easy to see the end result, or a web page is being served. But I want to do something even simpler, so that we're focusing on the process rather than the application itself. So let's say bash. It's going to be a little bash script.
1:12So we do bash - c. And then we put the script in single quotes here. It's actually going to run it. So let's do a while loop-- while true, do X=, X, sleep 1, done, in single quotes. Now if this looks a little bit confusing, in other courses we've actually covered bash scripting. You don't really have to know all of the intricacies of what's going on here. Basically when I hit Enter, this is what's going to happen, it's going to say one, two, three, four, and it's going to count to all of infinity.
1:47And that is our whole application, right? That's all that we're going to Dockerize, is a computer counting. I know it's kind of lame but there's not much that can go wrong with it. So when we Dockerize it, what we do is, we have to use a Docker app. So we're going to say, sudo docker, and we're going to say, Run. Now, Run will do a couple things. Run is going to execute the command we tell it to, in whatever environment we tell it to. But the cool part is that it will look in our local image repository for an environment to run our application in, and if it doesn't exist, it will download it from Docker Hub.
2:21So we're going to say, docker run. I'm going to say, -d, so that goes in daemon mode and runs in the background. And the first thing we say is, what environment do we want it to run in? Now, the computer that we're on right here, this is actually Ubuntu. So just to mix things up, let's say we're going to run it in the CentOS environment, or on a CentOS image that is downloaded from Docker Hub. And then we simply say, OK, so what is it that we want to run in that image, or in that container that we create from the CentOS image? And that's where we say, /bin/bash. Actually, let's just copy and paste this whole thing, because that was kind of a pain to write.
2:57So we will copy and we'll paste all of that. So to do that, we hit Enter. It asks for a password, because it's sudo, and we have to have root access to run Docker. Press Enter. It says, hey, look man. I can't find that image called CentOS. I don't have an image like that. So what it does, it goes on the internet, and it will download the CentOS image for us from Docker Hub. See, it goes through. It's going to download it. It will take a little bit. I'll probably fast forward here. But it's going to download the entire CentOS environment.
3:28Notice it's not a CentOS virtual machine, it's just all over the dependencies and stuff that is required inside of a container. So I actually don't even have to fast forward, because we're already done. Boom. OK, so it downloads all that. It extracts it, and now we have the CentOS image locally on our computer. It uses that image to create a container, and inside that container, it runs the application we told it to. Now our application is just this simple script. So right now we have a container that is counting, one, two, three, ha, ha, ha.
3:59It's counting all the way up to infinity, right? Unfortunately, we can't see anything. We're like, um, it just gave us this really ridiculously long string that's actually the container ID number. But other than that, we have our computer back. What the heck? Well, we can type, sudo docker ps, and it's going to show us what containers are running on our system. So here, now-- it word wraps a little bit weird, so bear with me. This is the container ID. Notice this is actually the same thing up here, just kind of truncated.
4:29They do show you the first little bit of it. So this is the container ID. This is the name of the image that it's running. So this is the environment that we have. It's running in a CentOS environment, even though we're on Ubuntu. The command it's running-- it actually truncates this, but it's our bash script that we entered in, so it's counting. It was created 35 seconds ago. It's been up for 34 seconds. And then, while it word wraps weird, it says the name. And then, the name that they gave it is hungry_hopper. Now, that's bizarre. And if you're doing this at home, it's going to be different.
4:59You're going to have some random name here as well. What they do is, rather than referring to your containers by these long, ridiculously complicated, randomized strings, it will give it a name. Like, it could be hungry_hopper. It could be lovely_luminaire. It could be all sorts of things, and it's going to make it random. It's going to be, probably, silly. I've never seen one that isn't a little silly. And you can reference this container by this name that it randomly assigned it. Now, it's running as a daemon in the background, so we don't see any output, right?
5:30Well, that can be kind of a problem, because we want to see our application is running. If it was a web server, we could open up a browser and check it out. But it's not. It's just counting on the command line. So in order to see that, we need to look at the logs this is creating. Because what it does is the console output-- like, of the output from our actual command-- is stored in a log. So how do we do that? Well, Docker has a fancy command for looking at the logs. It's not even a very difficult command to remember. If we were to type, sudo docker logs, and then we can tell it what log we want to look at.
6:03Now the cool thing is, like I said, we have this fancy hungry_hopper nickname, so we can say, sudo docker logs hungry_hopper. Or we could take the first few characters or the entire string. Whatever you want to refer to. You just need to have a couple or the whole thing. We can actually just say like, sudo docker logs fd5c44, and that's probably enough. Hit Enter, and it's going to show us what it's been doing in the background. Now it just gave us a snapshot log, right? It counted up to 197 in the time that we were sitting here talking.
6:34So if we go back and type, ps, again-- OK, hungry_hopper is there. What if we were to type, sudo docker logs hungry_hopper. It's the same thing that it referenced, and in the time between when we type the container ID and hungry_hopper, it actually counted from 197 all the way up to 218. So it's running in the background, right? Type, ps, again. So we can see, this is still running in the background. It's been up for three minutes, and to be honest, that's all there is to running a containerized app. We could log out of the system, we could go home, reconnect with Docker, and it would be counting for all of infinity in the background.
7:09Now, if we want to stop it, we can simply type, sudo docker stop hungry_hopper, and it's going to stop hungry_hopper, meaning this container that is executing-- or this application that's running in this container-- it's going to stop the entire container. And all it will give us is the name hungry_hopper. and basically it's saying, OK, it's stopped. And if we want to see, type, docker ps, again. Nothing is running in the background. If we were to type the logs for hungry_hopper, we would see it counted to 279.
7:40If we do it again, it's not running, right? If I do this over and over, it's just going to only show us 279 because it stopped. It's no longer counting. And that is how you interact or see what the process is doing. We've stopped it. We could also start it. Sudo docker start hungry_hopper. So it started hungry_hopper. Now, if we look at the log file again, look, it started over. And it's now up to six. So it stopped right here, we restarted it, and it started at x equals 1.
8:10So one, two, three, four, five, six, boom. It's working, it started again. So we can start it, stop it at will. Now if we look at the log files, we counted up to 30. If we look again, it is still at 30 because it stopped. Sudo docker ps. It's going to show us nothing is running. Now, don't worry. If you want to learn more about Doctor Hub and images and stuff, we're going to look at other stuff like that later. I just wanted you to be able to say, hey, I have run a Dockerized app. I am a Docker god. You can say that if you want, and as long as nobody quizzes you about your intimate knowledge of Docker, hey, you're in good shape.
8:45But truly, we really did Dockerize an app and run it and have it be executed in a Docker system. At the basic level that's all Docker is doing is running this environment in the background. And we did. We ran that application in the background, so, success. If all you wanted to know is how to Dockerize a simple app, you can stop watching this course, because you are now as educated as you want. I do encourage you to keep going, because it's going to get even more awesome as we go on. I hope this has been informative for you and I'd like to thank you for viewing.
Managing Containers and Images
0:00Hello, everybody. In this Nugget, we are going to learn to manage the images in containers on our Docker system. Now we're going to learn how to update and delete those images. We're going to learn how to start, and stop, and remove containers, because one of the problems with Docker is that it's so darn easy to do stuff, sometimes you end up with containers that just pile up and kind of make a mess of your system. Now, it doesn't do much more than use up storage space, but it really can get confusing if you have like 13 different versions of a container and you're not clear which one you want to start, which one you want to-- so today is like how to clean up.
0:34We're going to clean up. Clean up. Everybody do their part. And we're going to learn how to make our system efficient by dealing with the images and containers. But first of all, we need to learn exactly what images and containers are. I mean, we already know what they are, but how they differ, and how we should think about them, so when we manage them, clean them up, keep them updated, we do it in a way that makes the most sense and is the most efficient and helpful. Now like with most things in life, I like to think of the images and containers in silly little ways that just make sense to me.
1:04So I like to think of images and containers as like the image pasture in the container arena. And what I mean by this is here in the pasture, we have things like images that will host Java applications, or images that will host PHP applications, usually contain Apache. Often, Apache and PHP are installed together. And these images are kind of like a pure version of the environment that's required to run those applications. What we do is we take a copy of these images and we kind of put them into the arena with the application on top of it.
1:41So these are the environments that we have. The images are the environments. And then, once they are containered, or containerized, or copied over and put into live action, they are live apps where they battle each other to the death. No, where things happen to them, right? This is where the application is actually running, getting accessed by the outside back and forth. If you're on your computer here, you're going to be accessing the applications that are running. These get messy, right? These can get big long log files, errors.
2:12If something's going to go wrong, it's going to happen in this container arena. It's not going to happen in the image pasture because images don't directly get influenced or connected to by the outside world. They don't actually do anything except sit here in the cozy pen and wait to be copied off into the container arena. So what that means is that if we are going to update a container or an application, we actually just get rid of it. We just, boom, get rid of the application, start with a fresh copy of this image, and then add any changes to the application.
2:50So generally, you think of the applications and the containers that are inside our container arena here, inside our container spot on our system, as expendable. These are the applications that you've prepared and you've sent off to war, but when it comes time to updating or making significant changes, you want to do that at the image stage or at the deployment stage so that your images stay pure and you're not just building on top of something that's been running.
3:21So these are expendable. We want to get rid of all the containers that aren't being used and start from scratch by creating a new container from our pristine images, if possible. So again, containers-- expendable, images-- fresh, pure. That's where we want to start from. So on the system, they're not chickens, and ducks, and horses, and pigs, they're actually environments. Like I said, Java environments, Apache environments, et cetera. And then when we deploy them, they have apps built on top of them. Now I should say, sometimes, the actual images will have the app built-in, but the same process still happens.
3:57If there's an update to the app, we actually make the update here and then deploy it. We never update the one that's actually running. That's just not how we do things. So let's go to our system and see how we keep our images updated and our container area cleaned up. Now some of this might be review, but to see the various images that are pulled onto our system and exist in our image pasture, so to speak, we type sudo docker images, and it will show us all those that we've downloaded. So here you see I have the CentOS latest image.
4:28We could do some more. We can actually pull-- now when we created a Docker containerized app before, it actually downloaded the base image for us automatically during the run process. But we can actually pull an image and have it local. Anyway, we could say sudo docker-- let's search for PHP. So we'll search for PHP. This actually looks on Docker Hub. And I know there's a whole bunch of them here, but what I like to do is scroll to the top because the most popular ones are always at the top. Like 278 stars means people have said, this one works really well.
5:01And it's just called PHP. So if we were to say sudo docker pull php, it's going to pull that image from the Docker Hub repository, and it's going to download it. And then I want to show you something that's actually kind of cool. It's pulling the PHP image so we can use PHP as our base image when we're creating Dockerized apps. But it also does something else that's kind of cool. See, so it's pulled and downloaded all of the information so we have the PHP image.
5:34But if we do sudo docker images, we'll see that even though there were multiple parts that it downloaded, it just downloads into this single image that contains all of the dependencies required. Now, we could also sudo docker pull ubuntu, and it will pull the Ubuntu image, if there's something you need Ubuntu for specifically. And basically, what we're doing is building up our image pasture. We're putting images in here so that we can build on them when we create application containers that will require those in order to function.
6:11So if we here go docker images again, we're going to see that it has pulled all that. Now, you may look right here and say, well, this already exists. Well, that's because these images are built on dependencies of other things. It's going to actually only download the specific parts that it needs in order to function. So these images may have dependencies on each other, but Docker does a great job of just taking care of all of that in the background. So you don't have to worry. As long as you say, I want the PHP image, it's going to download all the parts that it needs.
6:43and when we look at Docker files later on, we're going to see what it takes to build an image and we'll see that they can call dependencies of other applications that are required for the environment because for PHP to run, it needs a web server. So you can be sure that part of this 444 megabytes is a web server application. Now, we've abstracted out what that web server might be. We don't even know. What web server is it running? Is it Nginx? Is it Apache? We don't know specifically. We just know that we have the ability to serve PHP.
7:13So Docker does a nice job of abstracting out all of those underlying details of what we would need. So that's actually kind of a cool thing. But so that's images. Now, we can actually pull images. We can also delete images. So if we do sudo docker rmi php-- now why rmi? Well, it's like rm, like the Linux command line rm, and i for image. So rmi is remove image PHP. Now, if we look back and see our images here, we only have Ubuntu and CentOS because we've deleted that PHP image.
7:50Now, if we started or if we run a container that requires PHP, it will automatically download it. But we can just have that there in the first place. Now, what if something here gets out of date? We could actually say sudo docker pull centos. And we already have CentOS. But if there are any updates to the CentOS image up in Docker hub, it will actually go and test and see. And here, we already have all of the updates that have been done. But that's a way we can keep our local images up-to-date, as well.
8:21So that's how we manage images. I do want to look at containers. So if you remember how to look at containers, docker ps will show us all of the running containers on our system. Just like the Linux ps command, the Docker ps command will show us all the running containers. So here we have a container called suspicious_euclid, and it is running this bash while loop. It's just a simple counter loop that we looked at in a different Nugget. And it was created 10 minutes ago. It's been running for 10 minutes. Now, that's good. We could stop it. But I want to show you another command.
8:52If we type sudo docker ps -a, it's going to show us all of the containers, whether they're running or not. And this is where you can start to get a whole big mess of containers just sitting on your system, not running but taking up space, and making it a little bit confusing. If you look here, we still have suspicious_euclid, the one that's running. And it's currently running. Its status is it's been up for 10 minutes. But we also have hungry_hopper, which was created in a different Nugget. And this is the same command, actually, but you'll see here it exited five weeks ago.
9:22So it's exited, it's not currently running, and it doesn't show up when we simply type ps. So up here, we typed ps. We didn't see hungry_hopper show up at all. But when we type ps -a, it shows us all of the containers, running or not. And so if we want to get rid of one-- sudo docker rm hungry_hopper-- so notice now it's not rmi. It's not an image we're trying to remove, just rm because it's that container that we're trying to remove. So now if we type ps -a, we'll see that suspicious_euclid is there.
9:53Now, if we tried to do that, if we try to delete that, we have a problem. It says, whoa. You can't do that. It's actually still running. Now, if we wanted to remove it, we could say -f and it would actually stop it and remove. But that's just a safety feature so you don't accidentally, while you're trying to clean up your system, remove a running system or remove a running container. So we could say sudo docker stop suspicious_euclid and it's going to stop that, and then we could erase it.
10:25So now if we say rm suspicious_euclid, it's going to do that without a problem. If we go back and say ps -a, we have nothing running, but we do still have images. See that? We still have the two images, the one that we just downloaded and the one that's been in our system for a while. So really, the gist of this Nugget is to learn these few commands and understand what they're doing. ps, ps -a is to look at containers, not images. To look at the images on your system, you type images. And there is no images -a. That doesn't exist. That concept doesn't exist because images are never running or stopped.
10:57Images are always just not running. They're just the staging area. They're kind of in your pasture there, waiting to be copied and put into play. So while pa and pa -a do different things-- one will show you running, one will show you all-- with images, you see them all, no matter what. If you type sudo docker images, it's going to show you all the images on your system. To pull an image to your local system from Docker Hub, you use the pull command. And then to remove, you do rm to remove containers, rmi to remove images.
11:27So again, that difference is this "i." rmi is not a Linux command. You type rm to remove things on the Linux command, but rmi is something new. So just think of it as rm for images, and that's how you remove images on your system. Images are usually pretty safe to remove because you can just re-download them, unless it's a custom image and you want to rebuild it. But we'll learn about that later. But remember, the whole concept with Docker is that you want to remember, your containers are kind of the live systems. They're in place and you don't want to spend too much time tweaking them.
12:02You want them to be deployed from the image pretty much how you want them to run so that you can erase the container and spin a new one up without worrying that all of your stuff has been lost. But that's how you manage both images and containers and how you identify them on your system. It may seem like simple concepts that we went over today with images and containers, but understanding how to update them, delete them, start them, stop them, remove them, and know which one you're removing-- it's very important, especially when you start playing with Docker, which is something I urge you to do.
12:35If you just make a whole bunch of containers, it's great practice, but you need to be able to learn how to manage them and delete them so you don't just have 50 containers and you don't know which one is doing what, which one is the most recent one, et cetera, et cetera. So get in the habit of cleaning up after yourself on your Docker system, and it'll make things a lot easier as we move forward making custom images and things like that. I hope this has been informative for you and I'd like to thank you for viewing.
Networking
0:00In this Nugget, we're going to learn about docker networking. Because it's great to set up containers, and it's great to see them do things on the local computer, but in a real world situation, you're going to have to have a network connected to your application in almost 100% of the scenarios. I mean, it's possible that you're going to do a standalone app that doesn't need network activity. But gosh, that's just pretty darn rare. So we're going to learn today about how the docker system handles these virtual network interfaces. By default, it does bridged networking.
0:30I'll explain what we mean by that. And then, kind of a challenging thing that's a little bit tough to figure out at first is, how you can figure out your containers IP address. Now there are some more advanced networking things we'll do in another Nugget. But this will give you the gist of how things work by default when you open up docker and start a new container and get it going. If you've been poking around your docker host around the installation of what you've already done, you may see a few things. There is of course an eth0 on your system. All Linux systems have an eth0. Most of them do.
1:01And that is your host IP address. In my situation, it's 192.168.1. something. I guess it's like 201. It may not be that 201 is the actual IP address, but it looks something like that. When we installed the docker program, it also created a virtual interface called docker0. And that is assigned another private IP space. So this is not routable on the internet. But it gives it an IP address something like 172.16.0.1, or something usually in the 172 range.
1:32And what this is, it's a separate network, but it's an actual IP address assigned to the computer. So if you have another computer on your network that you assign an address in this range, you can ping this docker0 address on the host machine. So when you spin up, or start, a container docker runs it on the local computer. But it actually also gives it a network environment of its own too. So inside of the container, the container itself will see its own the eth0. And that will be assigned an address a lot like that docker0 address-- 172.16.
2:08something dot something-- so that it's part of that network. And here's where it gets a little bit confusing. But hopefully it'll make sense. It also, when this container starts, creates another virtual ethernet adapter on the system. And it starts with v for virtual. So veth, and then it gives it a long string of letters and numbers. It's basically matches that containers Mac address. But it doesn't matter if you know where the numbers come from. But this it creates this virtual ethernet interface on the host machine without any IP address.
2:39It's just a bridge device. And then what it does-- I like to think of it as it ties a rope inside here, throws it over, and anchors it to the host system right there. So this device is a bridge that allows the container's eth0 to access the rest of the network. And what it's a bridge to is this docker address. Notice that this address in here is on the same subnet as this address here. So by creating this virtual ethernet port and this ethernet port inside the container, effectively what happens is your container gets an IP address that is going to be accessible to the rest of the network through that docker0 interface.
3:25So docker0 works with this virtual ethernet card, and it ties in to the inside of this container's ethernet zero, and allows it to bridge through. If you don't understand or don't care how exactly the magic happens with the bridging and stuff like that, it's OK. Just know that the container gets assigned an IP address that is accessible via the rest of the network. And that's how it works by default. Now I wouldn't just tell you this and not show you. So what we're going to do now is go and spin up.
3:56I have a very simple container. It's an awesome container. I found this guy created-- you might want to write this down while I'm talking. So go ahead and write this down on paper so you can use this. What this-- this is an image that we are to bring to download off the docker hub. And it is a completely self-contained web server. And all it does is serve one page on port 8080. It's really small. It doesn't do anything else. But it's a great way to show network connectivity is working. So we're going to install this image, and then spin up a container based on this image.
4:32And then check out the IP address and stuff on the system. So if you haven't written this down, maybe take a screenshot or something, or pause and write down, because we're going to be typing this on our docker host so that we can get this sample container serving something on port 8080. So here we are on the docker system. I'm actually going to type ifconfig just to show you what we just described. So we have eth0 zero. This is 192.168.1.204. Oh, I was actually really close in my guess. I guessed 201. But 204, this is on my local LAN in my office here.
5:05If we scroll up a little bit, we'll see that docker0 is created. Again, this was created when docker was installed. The doctor daemon is running, and so this exists. And its address is 172.17.42.1. that Again, it's close to what I guessed. It starts with 172, and I think I said 16. But anyway, on my system it's 172.17. But this is the range that our docker containers are going to have. Notice there's no veth0.
5:37I mentioned that it creates veth0 on the fly. There's not one there right now, but there will be in just a minute. Because what we're going to do is type sudo docker run. And now we could pull the image. But if we type run, it will pull it and run at the same time. And you remember the name, if you look on your paper where you wrote that down. It's adejonge/helloworld. And actually, I want to back here by run, say -d so goes in the background. That way we can do things on the command line. So I'm going to do that.
6:07Asks for my password. And it didn't actually download it for me because I'd already pulled that image. But it will pull the image for you and give you this long ID string so we can tell it's running sudo doctor ps. You see there it is running. It's called sick_wozniak is the name that it was assigned. But it's there, it's running /helloworld. Now, we could hit the IP address of this container on port 8080 and we should see a web page served up. The problem is, you'll notice, it doesn't tell us what the IP address, Dun dun dun.
6:38Well, there's a really easy way to get that. We type sudo docker inspect sick_wozniak It will give us-- well, I'll just hit Enter. It'll give us this long string of all sorts of information about the container. One of the things that it tells us is its IP address. If we scroll around, we can look. See there its IP address is. That's 172.17.0.12 But what I like to do-- type that all out, do a space, the pipe symbol, and then say grep IP.
7:09And then it will give us a subset of all the lines that contain a capital I and a capital P. One of those happens to be the IP address. And it's really easy to find then. So 172.17.0.12. That is the IP address of eth0 inside our container called sick_wozniak. Now if we type ifconfig on our host system, we're going to see there's a new ethernet port created. It's that veth0 4BB056C.
7:40You'll notice it does not have an IP address. Like up here, this is the IP address. There's no IP address assigned. This is just a bridge port. This ties our container to docker0 up here with the 172.17.42.1. So it ties it to that. Now how can we tell that it's actually running? Well, let's open up a web browser. Go to http://172.17.0.12:8080.
8:10Hit Enter, and sure enough, now we see this. It says, Hello world from go in a minimal docker container. This is all that container or all that image does. It create containers that serve a simple web page on port 8080. But that's all we want it to do. So we can tell now. We know its IP address. And then on port 8080, it's accessible. This will be accessible from the rest of our network as well. Now we know its IP address, we know that it's serving. So if whatever is running on that server, knowing its IP address, it's going to be accessible on the rest of the network on that IP address as well.
8:43So that's, in a nutshell, how it works when you by default just use the bridge networking that docker does by default. That's a way that docker allows you to spin up multiple containers. So we can actually say-- let's just hit the up arrow so I don't have to type it all over again. Say sudo docker run, the same exact thing. We press Enter. Now it's going to create another one, sudo docker ps. Now we have two /helloworld applications running. The second one is called tender_feynman. So if we do sudo docker inspect tender_feynman grep IP.
9:23Now we're going to see this one has an IP address. Of course, it just incremented. But, 172.17.0.13. So if we go over here, we change this to a 13, we also have one running there. So even though the containers are both operating on port 8080, since they've been assigned their own IP address, they can both run on the same host computer without any conflicts about the port. So port 8080 is listening on dot 13, and it's also listening on our original one, dot 12.
9:57Press Enter. See, there it is. Dot 12, it loaded back up. So now we could stop it over here. Sudo docker stop sick_wozniak. So it stopped. We come back over here. Now, sick_wozniak was the one with 0.12 as the IP address. So 0.12. If we press refresh here, see it's trying to load. It's connecting to it. It's not able to connect. You see it's just hangs. 172.17.0.12, and it's just hanging.
10:30It's just not doing anything at all. Hopefully that makes sense. Docker makes it fairly simple to do it automatically. It's important to know what's happening behind the scenes, but as long as you know that when you start up a container, it gets its own IP address on that virtual bridged that network, you are above and beyond in knowing how docker handles networking. And then it's really convenient as well when you know how to find that IP address using the docker inspect command. I hope this has been informative for you, and I'd like to thank you for viewing.
Advanced Networking
0:00Docker's way of dealing with the networking on containers is truly elegant with the whole bridge mode and the way that it creates those IP addresses on the fly. But it does have a few shortcomings in a local network environment. In this Nugget, we're going to learn about port mapping, port redirection, and also a host networking option that is available in Docker. But the problem that we're addressing with these advanced features is this, now this should look familiar, this is how I explained the whole bridge networking default way that Docker handles containers' IP addresses.
0:32So we have this is on our local network, we have a 192.168.1.204 address. So that's our host computers' IP address on the local network. It creates a virtual port called docker0 that has this 172.17 address. And then when you spin up a container, it gets assigned a 172.17 address that gets tied to a virtual ethernet port that is created basically exposing this 172.17.whatever address to the rest of the network.
1:03The problem is that on our local network, computers have this addressing scheme. So this computer over here on my network is 192.168.1.15. It has no way to communicate with an IP address of 172.17.0.15 because it's in a different IP range all together. So the way IP networks work, this computer cannot directly talk to a container with this address. So that's a problem.
1:33Now, we could assign every computer in our network another address, but that is really a super messy way to go about doing it. So the solution that we have is an ability to map ports from this internal container and map it to ports on our hosts' IP address. So we will actually see what's happening inside the container on a port that's exposed to our network on the 192.168.1.204 address. That way these other computers are able to see it.
2:06Hopefully, that makes sense why we have to have some way for the other computers on our network to be able to see our container. And since they don't have this same addressing scheme, by default they just wouldn't be able to see it. It would be like right next to it, it's right there, but I just can't talk to it. Because that's not how IP addressing works. So we're going to show you how to-- first, we can actually do a port mapping. And that's pretty easy to do. We're going to use the same hello world application that we've done before. That same image that just does a simple web server that listens on port 8080.
2:40So let's go to the command line and create an image that maps a port. So the process for doing this is very similar, it's like sudo, docker, run -d, for daemon so it goes in the background. The name of our cool image is adejonge/helloworld. But then I actually want to add this option -p 8080. All right, so what this is going to do is it's going to create the Docker container, based on this hello world image just like before.
3:13But here it's -p actually it's for publish. So it's -p for publish port 8080 on our local host network. So if I press Enter, it's going to do just like you would expect it to do. But if we actually do a docker ps, we're going to see a little more information. And the information is here. So this is the same stuff we had before, but this extra bit of information is right here in the ps command. And what it says is port 8080 is being listened to on port 32769 of our local hosts' IP address, actually by every address on the system.
3:530.0.0.0 means that every port on our Docker host system is listening on port 32769, and it's going to redirect that to the internal containers' IP address on port 8080. So effectively, that means if we go over here to Mozilla, we can say http://192.168.1.204 port, and I forgot the port number already :32769, 32769.
4:29And if I press Enter, boom, it loads up this whole Docker container, hello world from go. So it's loaded it up on port 32769. But the important part to see is that it's on this network, 192.168.1.204, which means computer over here are going to be able to access it as well. So when we were-- before since docker0 had this 172.17 address, if we're on the same host computer we're going be able to connect the containers. But in order for computers outside of our host to be able to connect to it, it has to have an accessible IP address that matches the same IP address range that the rest of our network has.
5:10And that's what publishing that port with that -p flag, that's what that accomplishes. It allows us to expose that IP address, port 8080, using mapping it to another port. Now that's a random port, which isn't as useful as you would think, you have to look it up every time. Thankfully it at least shows us inside here what the port number is. But let's actually kill that off. So sudo, docker, rm -f, evil_kilby. So it stopped it. Now if we come back over here, hit refresh, unable to connect, right.
5:44Because it's no longer running, that container isn't running at all. In fact, if we do a ps command, you're going to see, boom, it's not running at all, Because it was deleted. So let's create a new one. But this time instead of that 32769, we're going to map it to a port that we choose. So sudo, docker, run -d -p. Now we're going to say, we want to map port let's say 8000: to the internal port 8080, on our container.
6:19And then the containers' going to be built on the image adejonge/helloworld. So we do that sudo, docker, ps. We're going to see now it shows us that port forward is specific. Instead of picking a random one, like that 32769, now we've told it specifically, I want you to listen on port 8000 and redirect that to port 8080. So now if we come back over here this 32769, which was randomly generated, has now been replaced with port 8000, where it should be listening.
6:53And sure enough now it's listening to that internal containers' port 8080. Even though it's 8000 on the 192.168 IP address it's being redirected internally to port 8080. So computers on the network will be able to access it. So you can either let it create one by-- on the fly, a randomized number like 32769, or you can specifically tell it which port you want it to do. And you can do this for multiple ports, you can do multiple -p. So you can do -p 8000:8080. In fact, let's give a quick example.
7:25Go up. Port 9000 to 8080 and -p port 9001 to 8080. Now what this is going to do is it's going to redirect to port 9000 to the internal port 8080 and also port 9001 to the internal port 8080. Press Enter so it's done it. Now if we do sudo, docker, ps. We're going to see it gives us a list of several of them.
7:57See it comma separated them. These are the two. And even though we've exposed two different ports on our 192.168 IP range, they both direct to the same 8080 port internally. So this'll be my last example here, but so we've done port 9000 and that will load. Sure enough, we get that. Port 9001, and press Enter. And sure enough that loads there, as well. If we were to try 9002, nope, unable to connect because those are not being forwarded into that containers' port 8080.
8:32All right so that's how you can manage that. Now let's actually sudo, docker, rm -f, cranky_loveless. And sudo, docker, rm -f boring_almeida. OK, so sudo, docker, ps -a, we have no images running. Because the last one I want to show you is what I highlighted in the very first slide, is that host networking. So let's say you don't want to go through the hassle of redirecting ports, you just want to do a shortcut and actually expose it automatically on IP address 192.168.1.204, your hosts' IP address.
9:13That's possible by doing this sudo, docker, run -d - -net=host. So net equals host is a new flag. What this says is, don't use bridge networking, just share the hosts' IP address, adejonge/helloworld. Press Enter. And now sudo, docker, ps, is just going to show us it's running. It's called sharp Alameda. But it doesn't show us any port forwards, because there are no port forwards going on.
9:47If you do network equals host, there is no more v-ethernet. So ifconfig, you'll notice there's no v-eth, there's no virtual ethernet connection at all. And if we do sudo, docker, inspect oh, what was the name of it. Let's scroll up a little bit, sharp_almeida. Grep IP, if we do this we're going to see it's not assigned an IP address. It does not have an IP address assigned, because it's actually sharing the hosts' IP address.
10:21So what that means we can come over here, 192.168.204, and we just go directly to port 8080, because it's sharing the same IP address. So since that hello world app listens on port 8080, it's going to be listening on port 8080 of the hosts' IP address. Now the reason you can't do this for all of your containers is we cannot spin up another container, using the host network, listening on port 8080, because it's already in use. That's the beauty of the virtual bridged network is that it allows you to host multiple programs using the same port numbers, because it spins up individual IP addresses.
10:57But if you use host networking, you're limited. You can only listen-- one container can use port 8080 and that's it. So there's a limitation, but it does simplify how things work as well. And really that covers moderately advanced networking inside Docker. It's important to understand how port mapping and port redirection works. And when I say port redirection, it's actually just port mapping where you specify the port that you want it to map to on your local hosts' IP address. And then also host networking is just a way that you can share that host computers' IP address with your containers.
11:31I hope this has been informative for you, and I'd like to thank you for viewing.
Shared and Persistent Data
0:00Now by now we realize that Docker is really amazing for spinning up and taking down environments and applications really, really quick. But I'm positive that you don't want to have a hello world type application in your real environment. For them we need external data, or your private data, so that you can actually serve out a web page that's not just the default, stock webpage. Now when we're doing that with Docker, we want to make sure that the data that we have to serve out, or to store, is external, and that's because, remember, containers are ephemeral.
0:32Or they're the kind of thing where we spin the container up and then we can destroy it, so you don't have anything actually stored inside of your container that's important, so we want to keep it external. Now we can do that a couple different ways, like mounting a network server. And while it is possible to set up like an fstab file, and set up NFS, or Samba to mount an external shared data point inside the container, that's a really complicated way to do it, and it really is kind of a pain in the butt.
1:02Thankfully, Docker allows us to do that on the host. So you have your host, your server computer, and it can mount whatever hard drives or network shares that you want, and then you can actually share that with the container inside. It's really, really awesome. And why is it important? Well, I like to think of it like a super spy, right. Say you are a super spy-- dun dun dun dun dun-a, dun dun dun dun dun-a -- and you have two things in your apartment that you have to have. If your apartment is compromised and the bad guys are coming in with machine guns, you want to take your briefcase and your burner phone and get out.
1:36Now the really nice part is everything you have important is in that briefcase and that burner phone, so you can take them and then go to your safe house, which is another apartment across town, and work perfectly fine. So the data works just like that in a container, right. You don't want to have anything stored inside the container that is super important or that you have to have. You want to be able to get your stuff and go in a moment's notice. And so that's how the whole idea of Docker works. You don't want your data stored inside your apartment, right.
2:06You want to have it portable so you can get it out really quickly. And so this is like the host operating system, the host file system. This can be network mounted, whatever, like your home directory, for example, I have listed here. Let's say you want to access your home directory from inside of a container. Well, you can actually just point to this directory into a container on launch and it will map this folder to a folder in here. Now you could, like I said, set up an fstab file and mount it directly from inside of the container using network mounting tools, but that is such a complicated thing to do.
2:41And it's silly to do that because you can actually just map the drive from your host operating system into the container. And so that's what we're going to learn how to do today because it's a really powerful way to make your containers that much more disposable, right. Your data is stored outside of it, so as you spin it up or destroy it on the fly, you don't worry about losing any data. You don't want to store anything important inside of your container. And to do that, we mount these volumes inside of a container when they're really stored on the host operating system itself.
3:14And that's really easy to do, too. So we're going to go to the command line and demonstrate how it's done, but it's just a one liner, just like everything else in Docker. It's really awesome. Now to demonstrate this, I'm going to use a different container, a different image than we've used before. So I'm going to say sudo docker run minus d for daemon, and I'm going to run nginx-- N-G-I-N-X. And what that is, it's the nginx web server, so it'll download that. If you already have it on your system like I do, it'll just get it going and instantly create a container and get it served.
3:46Otherwise, it'll download that into your images. And now if we look at our running containers, we can see it's called trusting cori. So let's do a inspect, grep for IP so we can see the IP address, and we see the IP address is 172.17.0.24. So let's go over here and type that in, 172.17.0.24, I think it was. Press enter, and sure enough, here we get the welcome page. So welcome to nginx. So we can see that it's running, this is just its default page.
4:17There's nothing that it's actually serving out except its sample page that comes built in. So I just wanted to show you that's how nginx is working. It runs on port 80 on that IP address that we figured out using the inspect command, but we can also virtually map a folder. So let's see what I have in this folder. I have nothing. Let's create a folder called web, go into the web folder, and we'll create an index.html file. And I'm going to say h1, it worked, close that.
4:47It's just pretty simple HTML. I save this. And now I'm going to spin up another instance, or another container of nginx, but this time I'm going to say pseudo sudo docker run-- I'm going to say minus d for daemon, but then minus v for volume, and I'm going to say, what volume? I want it to be home/spowers/web-- that's the folder that I want to use for my host system-- and then a colon, and I'm going to say where I want it to mount inside of the container.
5:19Now you can read the nginx page on hub.docker.com to see where things are stored. I just happen to know that usr/share/nginx/html is where it serves webpages from inside that container. So I'm mapping home/spowers/web to be mounted inside the container in usr/share/nginx/html. And the nginx image is what I want to spin up, press Enter it does that again. Sudo docker ps, see what we have running. This one's called grave goodall.
5:50So sudo docker inspect grave goodall, grep IP, and we'll see this one is .25, which is not a surprise, just increments. But let's go over here and change this from 24 to 25. And now if we hit Enter, we'll see "IT WORKED!!!" , and it's running inside that container. However, since we are here and our system, and it's mounted the one that's on our host system, if we edit index, and we change it to, let's say, really worked, save that file.
6:23If we come back over here, even though we haven't spun up a new image, it's actually reading this data directly from the host system. So if we hit refresh, it's changed to "IT REALLY WORKED!!!" , which is awesome. Because that means even though the container is running, we can change our files and it will-- in real time-- get that stuff, because it's just a mapped our current folder. Didn't make a copy of it or anything. It actually directly mapped to this web folder into the container. So we can change files here, and it will be reflected in that server. So quickly back to our instance here, what we've done is we've taken the HTML file that we're serving-- and call it the briefcase, or the burner phone, whatever you want-- we've actually stored that over on the host-- or like, in the pocket of the spy-- and we spin up a container and it's there, so it can see it.
7:09However, we can burn this container down, or burn that apartment down, and we don't worry about losing anything important because all the important parts, that are dynamic, have been stored inside that volume on the host. So we can take that to the next container and it'll serve it up just fine. So using shared data from your host to your container is easy. I also said persistent here because if you burn down a container, or you destroy that container, your data is going to stay if it was living on the host file system itself. So, external is obviously ideal because you don't want to store anything in a container.
7:42And you can either mount things inside the container on a network, which is just a horrible way to go about it. I do not recommend you try to install NFS or Samba inside of a container as it spins up. That's just a nightmare. And it's so simple to mount volumes from the host, and it can even be a volume that happens to be a Samba share. So if you have a Samba share that's mounted on your host, you can take that and mount it using the dash v command, and it can be a volume inside of your container. So that's the best way to deal with data when you're dealing with Docker.
8:14I hope this has been informative for you, and I'd like to thank you for viewing.
Modifying Containers and Images
0:00The Docker Hub is full of just about every kind of image that you can possibly imagine. I mean, web servers, file servers, gaming apps, all the different things that you would want to run inside of a container, most of them are already created at Docker Hub. However, there are some times where you get an image that does almost everything you want it to do and so modifying that image is really the way that you can tailor it to yourself. Now there's two different ways to go about modifying an image. The first way we're going to do is kind of a quick hack sort of way to do it, but it's completely legitimate, and it's the easiest way, I think, to go through and modify an image so that it's exactly what you want.
0:39And the way you do it is basically you spin up a container, modify that container, and then create and save that container as an image itself. So to do that, we have to be able to attach to a running container, because to make modifications to a container you have to be able to connect to it. Then we're going to modify that running container and then from that modified container, we actually create a new image based on the changes we've made. It's really cool. So let's go to the Command line. There's going to be a lot of work on the Command line, but it's not difficult to understand, and the result is a custom image that you kind of built based off one that already existed.
1:14Now the first thing we need to do is spin up a container so that we can modify it. So say sudo docker run -d. I'm actually going to teach you a new flag. It's - - name and then the name we want to name the container. So I'm going to say my_nginxtemp, and then the image that we want to base it off of, nginx. Now what I've added here is this - -name my_nginxtemp. You remember when we started container, it gives it a random, silly name? Well, if you use this - - name flag, you can actually set the name that you want it to be.
1:47And that's going to be important, because it'll get confusing if we're trying to remember which container we're modifying and what we want to create it into, et cetera. So hit Enter, and it's going to create that. Now if we do sudo docker ps, we'll see the name of it is my_nginxtemp. OK, that's really awesome. Now we want to connect to that so that we can modify it, but first of all, let's actually do a sudo docker inspect my_nginxtemp grep IP and look for the IP address and it's 17.0.27, so come on over here, 17.0.27.
2:23So we have the Welcome to nginx screen, right? This is running. That's what we would expect. It's just a brand new spun up nginx. Now if we wanted to connect into that container so we can do things inside of the environment on that container, now there's a command called Docker Attach, and what we would do is say, sudo docker attach, and then we would say the name of, like my_nginxtemp. The problem is, this doesn't work unless the container started with like a Bash script, and then we kind of like piggyback onto that Bash script, so even though Attach is still a viable option, it's definitely not the most flexible and not the one you actually want to use.
2:59If you want to connect to a running instance or a running container, we're actually going to say sudo docker exec -i -t and where we want to connect. We want to go to my_nginxtemp, and then we have to say what command we want it to run inside of that terminal session. We're going to say Bash. So if we do that and press Enter, now we are actually inside that image. We are inside that container, that running container called my_nginxtemp. We are inside there.
3:30So if we go to usr/share/nginx/html, we'll see in here this is the default, right. Let's look at that. Cat index.html, and sure enough, so this is the Welcome to nginx page that we actually saw over here on our web browser. So what if we modified that? What if we wanted to make our own image, and we're going to rm index.html, and we're going to cat into a new index.html, and we're going to say h1 customized and then Control-D. Well, actually saying that, so now we see in here we still have the index.html, so if we look at it, we're going to see now it just has that customized h1.
4:13And if we go over here and we hit Refresh, we would expect that now we would see that customized thing, right? But what if we want to create an image that every time we spin up a container, we get the customized version. Well, there's an awesome way to do that. So we have to exit out of the container, so just type Exit and boom, we are back in our Docker Host, right? We're back at our regular prompt here. And we've kind of exited out of that insertion into the container that we created. And now if we want to create an image from the running container, we have to use the Commit command, and it's actually a really, really simple process.
4:49Sudo docker commit my_nginxtemp, which is the current running container, and what image do we want to save it as? I always like to do my custom images with the my underscore prefix so that I know that they're my images that I've created locally. So we'll just say my_nginx, press Enter. It gives us that, and now if we do sudo docker images, we're going to see we have a whole bunch of images here that were downloaded, but we also have a new image called my_nginx.
5:23Now what's cool about that? Well, let's do a sudo docker ps. We'll see that my_nginxtemp is running, so sudo docker rm -f my_nginxtemp, sudo docker ps, so there's nothing running. If we go over here, we'll that this is now completely offline and just hanging. It's not doing anything. Now if we wanted to spin up a brand new image, so let's say sudo docker run -d my_nginx, and that's the whole name of the image is my_nginx.
5:57Now I didn't do the name command. We could name it something, but let's just spin it like the simplest command we can, so docker run -d and then my_nginx, press Enter. It's going to create an image, so sudo docker ps, we'll see it's created a container, I mean, and it's running that container, and it's called high_bardeen. So sudo docker inspect high_bardeen grep for IP. Now we'll see the IP address is 17.0.28, so if we go over here, now this is a freshly spun up container, right, using our base image that we just created.
6:36Do .28 and boom, it's customized even though we didn't like go into the container and change that, we've created a new image that has that customized page automatically, so we can spin up a hundred different instances of my_nginx, and they will all have that customized page that we created by editing the one. So we've actually started with one image, created a container from it, modified that container, and then save those modifications back to our own image. It's actually really cool and a great way to get a specific customized image so you can roll them out with just one liners, right?
7:12So just do my_nginx, and now we have another one running on our system serving out that customized page. Sudo docker ps, and now we have two different containers, and they're based on our custom image. It's really a powerful way to customize your image so your containers are automatically exactly how you want them when they start up. We actually learned a lot of really useful information. We learned how to attach to running containers and, again, I don't recommend you use the Attach command, because that doesn't always work, but if you do that exact IT and you tell it to run Bash, it'll always work.
7:49You can always get into the container. So we learned how to attach to it. We learned, actually added to this, how to name a container so that we don't have to use those funny names that they always come up with. If you want to have your own custom name, you can do that. And we learned how to modify the container and then how to create a brand-new image based on a running container so that we can have it as customized as we want. I hope this has been informative for you, and I'd like to thank you for viewing.
Creating Images from Scratch
0:00OK, I'm not going to lie, this is going to be a fun Nugget because we're going to take all of the stuff we've learned about Docker and we're actually going to create our own images that we can then deploy. And we're going to do it from scratch as opposed to from a running container and creating an image out of that. Well, first we're going to learn what a base image is, but we're going to start with a base image, create our own Dockerfile, which is a recipe, and then we're going to build images from scratch right on our computer so we can then deploy those images as we see fit.
0:31Now, I said Dockerfile, and it's important to realize that a Dockerfile is a lot like a recipe that your Docker system will use to create images-- like fresh images that have never been containers before. We're not going from containers back into images. We're actually starting with this Docker file. And I just wrote on here some silly things like one cup of Debian, two tablespoons of PHP, and two cups of application. Mix well and open the port. Regardless, what this does is this recipe allows you to create an image.
1:01And we started at the very beginning of when we learned about Docker, we created a one-line Docker-ized application. What we did is we started with a base image, and a base image is just that. It's an image that does nothing but set up the environment. So for example, Ubuntu is the name of an image. I think we used CentOS before, so CentOS is a base image. And all that does is create for you the environment that looks like Ubuntu.
1:32So the dependencies and all of the things that an Ubuntu system has, except for a running kernel and all that stuff, but the other dependencies and files that you would expect in a Ubuntu system, that's what a base image is. So there's no application in the base image. This is just setting up your environment. So when you see images that are built from Dockerfiles, which is what we're going to do in this Nugget, almost every one of them starts with a base image of some sort because it gives you that environment to run your application in.
2:06Now, we've been working in the past NGINX, so I want to quickly look at what NGINX Dockerfile looks like. Because we've used the NGINX image, but how is that image built? Well, it's a lot simpler than you would think. So let's look at the NGINX Dockerfile, and then we're going to go and create our own Doctor file so we can create our own fresh, from scratch images. So here, back in our Docker host computer, I'm going to say LS so we can see I copied from hub.docker.com the Dockerfile that exists for NGINX.
2:41So let's just quickly look at that. We're going to look at-- this is the Dockerfile. This is the entire recipe, if you will, for creating a Docker image. And there are some important key words that we're going to look at. It says, basically, this is from what base? And the base they're using is Debian, and then they specify with a colon what version of Debian-- Jessie. That's the name of the version of Debian that they're choosing. Now, if they were to leave off this colon Jessie, it would just pull the latest Debian-based image and that would most likely work fine as well.
3:16But anyway, from is how you tell it what base image you want to start with. What environment, what sort of operating system is the application going to expect? And this one is going to expect a Debian system, so that's the environment we're going to give it. Maintainer is pretty self explanatory. Who maintains this image? We'll put my name in there. And then there are run commands. So it starts with the command for the Dockerfile. And it's all in caps. That's just a convention. But run, and then it will run this command as it's creating the image.
3:48So it'll run that. Then it actually installs an apt key and then we download that apt repository. It sets an environment variable using the ENV command. Down here, it runs some more and it runs apt-get update, apt-get install, these packages, and then it cleans up after itself and removes some files in the apt system just to make it a smaller image. But it's basically just doing command line things. Run tells it to do command line things, and you'll see there's just one command here. It's because they've strung together one long command into three lines.
4:21That's what this backslash means. But you can have a run command-- as many as you want-- in a row and it will run them. And then down here, you see some more run commands. It does symbolic linking. So the standard output and standard error actually gets redirected into a file, and then it does a volume where we can share volumes between containers. Expose opens up ports so those ports can be accessed. And this is an NGINX, so you want port 80 and 443, the web ports, to be open. So that makes sense. Expose opens up that firewall so you can actually get to those from the outside.
4:53And then the last one is a CMD. It stands for command. And this is what it actually runs. It runs the NGINX daemon. And so we're going to create something like this. I wanted to show you the NGINX one because a web server is a fairly complex beast, and this is all it takes to install and create an image that runs a web server. It's fascinating how efficient Docker is in allowing you to do some simple things. So we're going to create a Docker image next. And when we create that image file-- that Docker image-- we're going to call it myapp or mycount or whatever.
5:28And then we can spawn off multiple containers, just like if it was an image that we downloaded from Docker Hub proper. We're going to create a complete image on our system. So we need to start with a build directory. Now, I've already created a directory for us, and I've called my_counter. So let's go into that directory. You can see it up there-- my_counter. And inside here, I have one file. Now, this is the app, if you will. Remember before we created an app that counted 1 to infinity. Well, that's what I did here.
5:59I just created a file that's a script that will do that same thing. So let's look at it really quick. This is all that's in there. It's a bash script, and says while true, increment x, and then echo x to the screen. If we actually execute this, we'll see it just counts forever-- one, two, three, four, et cetera. So that's the application that we're going to create an image around. So we're going to Docker-ize this application and create an image that will auto-start it when that image is turned into a container and started.
6:32Now, I said this is a build directory. And inside this directory, we're going to create a Dockerfile. So I'm going to say VI capital D Dockerfile right here. So that's the convention. We name it Dockerfile. And it's going to be an empty file at first, but we're going to create one just like that NGINX Dockerfile that we saw. So we're going to say from-- I'm actually just going to say from Ubuntu. I really like Ubuntu for a lot of reasons, so that's what I'm going to use as my base image. And again, that base image, it's going to download from Docker Hub.
7:04But that just gives us an environment that is Ubuntu. That's the environment that the container is going to have. And it's going to work like a Ubuntu system, but just inside a Docker container. We'll say the maintainer-- Shawn Powers. Shawn@shawnshouse.com, which is not my real address. So please don't email that poor person if such a person exists. And now, this was not in the NGINX Dockerfile, but it's something that we're going to put in ours. We want to have that file-- that countet.sh file-- we want that inside of our container.
7:39Now, it's in our build directory that we're in right now, and so what we're going to do is we're going to use the copy command. Now, we could also use a command called add and it would work the same way. I'll explain the difference in a moment. But copy counter.sh, which it looks in our local directory-- our build directory. And so that's the source. And then where do wer want it inside the container? Well, I'm going to say user/local/bin/counter.sh. So I want to copy it from our build directory into our image at that location, and then I'm going to run chmod +x user/local/bin/counter.sh.
8:17And that's to make sure that that's an executable file inside of my image. Remember, run just does a command line thing inside of the image that we're creating. And then the CMD. Now, CMD again means command. What command do I want the image to automatically execute when it's turned into a running container? Well, we put it in brackets and then quotations-- user/local/bin/counter.sh. And we know that's going to be there because we just put it inside with that copy command up there.
8:48Now, I said there is a difference between copy and add. We could actually change this to add counter.sh, and this would work just the same. So if you're looking at other people's Dockerfiles, you may see the word add instead of copy. The difference is copy just copies it directly. So whatever we have here in our build directory, it's going to copy it to that image. If you say add, this source could be a file. It could be a TAR zipped file.
9:19So if this is a TAR.gz file, it's going to extract it and put it in the destination. And if you use the add command, this could even be a URL. So if there's a file listed somewhere, like if you're doing WordPress and you want to download the latest WordPress TAR.gz, you could put a URL in this first place and it will download it and then put it in the destination. But if you're just doing a local copy from your build directory, the convention is to actually use the copy command. So I'm going to do it the correct way and that's what it will do.
9:51It'll copy it into my image. And honestly, that's it. We're done. We've done everything required to build a Dockerfile that will work for us. So let's save this file. And now if we do LS, inside of our build directory is this counter.sh file, which we looked at and it works, and this new Dockerfile. So now if we wanted to create an image from this, we do sudo docker build and then dash t for tag and what we want to name it. I'm going to say my_counter.
10:23Remember, I always like to name my own personal images with that my prefix letting them know it's mine. And then what build directory do we want it to use? I'm going to say dot for the current directory that I'm in. So we do that. It does all the things. It downloads anything it needs. I already had that Ubuntu base directory. So it actually did that. But then it created stuff, it copied it, it made sure it is executable, and it created an image. We can make sure it created that image by saying docker images. Let's see what images we have. Well, we did my NGINX that we did in the different Nugget, and now we have this my_counter image.
10:59Now, this is an image on our system. So we could simply create a container from it. Sudo docker run -d my_counter and it's going to run that. Sudo doctor ps, and we'll see it's there. My_counter is running. It's called dreamy_yellow. So if we say pseudo docker logs dreamy_yellow, we'll see that it's counting. It's going away. So if we say that again, we'll see it's counted even higher. So it's actually working, and it automatically started our application upon deployment.
11:32So we actually have created an image from scratch using just those few lines in the Dockerfile, and now we have a fully-functional image that we can create a container from-- as many containers as we want. So while our example was a very, very simple, you don't have to stop with simple. Your recipe or your Dockerfile can be very complicated. If you need to add dependencies or unzipped files or you want to put specific things in specific places on your image, you can do that and then your deployment is as easy as deploying your image using Docker fun from that image that you created.
12:07And it's so simple. I mean, our simple example was just five lines. It was just lines in the Dockerfile, and we created a fully-functional image that we can use to spin up containers running our app, which happens to just count. But I mean, it's an app that does something. Any app you have you could do that same thing with and create your own image. I love when all the things that we've learned come together and we're comfortable doing things. We understand what a base image is. We understand now that a Dockerfile is just a simple recipe for creating that image.
12:40And we learned that building an image from a Dockerfile is a simple one-line executable just like everything else in Docker. It's exciting, and I hope this has been informative for you. I'd like to thank you for watching.
Containers Working Together
0:00In this Nugget, we're going to learn to have containers work together so that they can execute on the same data but still working separately and independently. So independent execution-- they're going to share that input and output, but rather than use the traditional host file system that we've done in other Nuggets for getting data outside of a container, we're actually going to abstract even the idea of data storage. And we're going to have a container that strictly stores data. That's confusing, don't worry. I'll explain why it works in just a second.
0:30See we have two apps that we're going to be working together. We have the counter app that we've been dealing with, slightly modified, but just counts one, two, three. We have an image we're going to create for that. And then our standard Nginx web server. And the idea is we want the counter app to output a number, you know, like a one, two, three, four. And then we want the web server to be able to show us that number. So we want to be able to refresh the web page and have that number show up. Now we could just do -v and get a similar host volume like /home/spowers/web and we can map that to where this output's it's counting.
1:09And then we could mount this same folder inside here into the user share Nginx HTML directory. And that would work just fine. It would work and it would be functional. It would be fine. The problem is what if we wanted to send our setup to another user on another system. Well, they would have to figure out what their own data storage spot on their server is. Unless their name happens to be Steve Powers, they're probably not going to be /home/spowers on their own machine. So if we abstract out the host operating system, like the file system on the host, and we store it inside of a data container that we create, it allows us to say, OK, here are all of my images, you spin them up with containers named like I tell you and it will just work, regardless of what your underlying file system looks like.
2:03So hopefully it makes sense of why we would want to. It kind of seems like a step backwards, right? Like OK, well, we had a common place for the data, why are we now putting that inside of a container when we don't have to. It's kind of like going from a container to the host into another container. But the idea is it abstracts out where the data is stored and gives us a common place that multiple containers can reference. And it's, again, a really simple way to do that. But that's the reason we're doing it. So now let's go ahead to the command line and actually show what that looks like in practice. Because a data only container functions slightly differently than the containers that we're used to that are constantly running an app.
2:40Now, the first thing I want to do is create a container that will store the data for our other two containers to look at. OK? So to do that we're going to say sudo docker. I'm just going to say create, because it doesn't have to run, right? It doesn't-- here's a cool part. A container doesn't even have to be running in order to share its data volumes with other containers. So we're just going to create it and it won't even be running. How cool is that, right? It's just going to be created. So sudo docker create.
3:11We're going to name it my_data. And the reason I'm going to name it that is so that I can reference this container when I start up the other containers that are going to look to it for its data. Now we're going to say -v for volume. And I want to create a volume inside of it, /usr/share/nginx/html. And I want to use the ubuntu image. So that's how it's going to do. Now hopefully this makes sense. We're going to create it, I'm going to name it my_data. Now this -v for volume, you'll notice I didn't map it to anywhere inside the host operating system.
3:47I just wanted to create a volume that it can share out. So this has a folder inside of it that it's going to have /usr/share/nginx/html. This is going to be a volume created in this container-- even though the container's not doing anything other than sitting there-- it's going to be this common storage area for this volume. OK? Now this volume folder name should look familiar. That's where the Nginx thing will eventually look for HTML, but nonetheless, this is going to be a central repository that it's going to have. So we hit Enter, it's created it. Now if we do sudo docker ps, oh, it's not running.
4:19Right. We didn't run it, we just created. So sudo docker ps -a will show us, sure enough, it's there. It's called my_data and it's sitting there, even though it's not running, it has a volume that we will be able to access from other containers. So let's start up an Nginx container. sudo docker run -d --volumes-from my_data nginx So what are we doing here? Well, sudo docker run -d so it runs in daemon mode.
4:50This is the new one. --volumes-from my_data. Now notice we didn't specify any folders on our host operating system. We just said take the volumes from this container and use them, mount them, right? So volumes from my_data, which we know is running right here. Now, what volume is it going to get from my_data? Well, this one right here, right? The /usr/share/nginx/html volume. So it's going to get that. If we press Enter it'll actually start up. sudo docker ps. We're going to see it's called naughty_hoover so sudo docker inspect naughty_hoover | grep IP All right.
5:30So it's 0.39-- let's go over here 172. 17.0. I already forgot what it was. 39. OK. 39 press Enter. Now we should get an error. And sure enough, it says 403 Forbidden. Why is it's saying that? Why is Nginx giving us an error? Well, because it's using the volume from my_data but there's currently nothing in that volume. So it just sees an empty folder. So Nginx-- it's using the volume correctly.
6:01That's like a good way for us to test that it's actually using the volume. So now we have to have an application that's going to actually put something in that data volume so that Nginx will see it. And I've just so created such a thing. So see how I have, let's see, I have a new build folder called my_webcounter. If we go into there, my_webcounter, you'll see I have a script called webcounter.sh. Let's look at that really quick. Now this should look very, very familiar. This is just a one, two, three app that we had before.
6:31However, I've changed it a little bit. So instead of just echoing one, two, three to the console, it actually echoes a little HTML magic here. So this is like a line of HTML. It centers it, it makes it big, and puts the number in the middle there, and rather than just print it to the screen, it redirects it to a file /usr/share/nginx /html/index.html. OK? That's the location that it's going to write this over and over and over. I'll quit. Let's actually build this so sudo docker build -t we're going to call it my_webapp dot.
7:08OK. So it's created that image and now if we spin up a container from this image, so we say sudo docker run -d --volumes-from my_data. So it's going to get that same volume that the Nginx container's looking at from that my_data container that's just sitting there idle. So it's going to get that volume. And we actually want to run from the image my_webapp so I'll press Enter.
7:40It spins it up. We do sudo docker ps. We'll see, sure enough, here it is. This is our web counter that's running an evil_elion. Now if we go over here and I hit Refresh, you should see-- if everything is going right-- that web counter that is a writing over and over that a number to the shared volume on the my_data container. And then this Nginx container is looking at that same shared data container and reading that HTML file from that shared volume.
8:11Let's see. If we hit Refresh Boom. 33. Let's hit Refresh again. 35. Hit Refresh again. 38. So it's actually working. They are working in concert and if we look back at this drawing, what's happening our counter app is doing that little string of HTML that's creating like 35, 36, 37 as an HTML file. And it's writing it directly to this data only container called my_data.
8:41And then this web server has this data only container volume mounted as well. So when it looks to serve out it's HTML, it's actually looking in this shared volume and it sees an HTML file there. So sure enough, it serves it out and they're working in concert without needing any reference to the underlying file system. Which means that we've created a completely portable pool of applications that are working together. Because these can be delivered to anybody.
9:12They can be delivered to your computer and as long as you name it the data only container properly and you point them volumes from that data container, it doesn't matter what your operating system's file system looks like. You don't have to reference the file system at all. You can reference this shared volume and then share your data from inside there. And while it seems like it adds a layer of complexity, what it gives us is this really awesome ability to allow our system to be completely portable. They're still independently executing.
9:44They're sharing that input and output, but rather than sharing it off the host file system, they're sharing it from a data volume container that doesn't even have to be running. It just has to be existing and created so that the running containers, the other ones, can reference it. I hope this has been informative for you and I'd like to thank you for viewing.
GUI Tools for Docker
0:00Today on Dockerise Your World, I'd like to talk about Docker GUIs. Specifically some options that we have for administering the command line Docker program with some GUI front ends. Now, we are going to look at one called Dockerui. And this is one that I recommend that you install, even if you're just a command line nerd and that's all you want to do is the command line stuff, because it's the most efficient. Dockerui will give us a few advantages that makes it worth installing. I'm also going to mention and list a few full GUI interfaces.
0:31We're not going to go through and install them because, truly, I want you to understand how Docker works. I don't want you to shortcut it and just use a GUI, but I want to mention them because some people really prefer GUIs. And, depending on your environment, it might be the only way that you're going to be able to really use Docker. But first of all, I want to install Dockerui and show you what it does for your Docker world. Now you're very familiar with doing all sorts of Docker commands. Like Docker ps, which I'll do right now to show that I have a few containers that are running from a previous Nugget.
1:02They're still sitting here running. Now, Dockerui is easy to install on your system because it's just a container. It's an image that we're going to download from Docker Hub and install. It's really super cool. So sudo docker run minus d. Now we need to set up a port forward, so dash p 9,000 colon 9,000. So that the local host port 9,000 will point to that internal container. If you're running a system that has SELinux, you may need this flag.
1:32And it's not going to hurt even if you don't need it. But privileged. So privileged. That will allow it access to the Docker socket interface. Then we have to set up volume so that /var/rundocker.sock on our main system maps up with /var/rundocker.sock. That's the socket interface on our internal container. And then just the name of the image, which is dockerui/dockerui.
2:05And it's going to say, hey I, don't have that. So it's going to pull it off of Docker Hub. It's going to download it and install it. And then, boom. It's automatically running. If we do a sudo docker ps, we'll see-- sure enough-- it's right there. It's called compassionate_ardinghelli. Boy, this is a perfect example of why naming your containers maybe makes sense. Because what a big, long thing to try to type out. Anyway, it's running and that's fine. What we're going to do now is come on over here. Now, we don't actually need to know the IP address of that container.
2:36Because remember, we set up that port forward. So we can just say http://127.0.0.1 port 9000. Or local host port 9000. And it's going to show us the Dockerui interface. Now there's not-- you can't do everything with this. This isn't where you're going to browse Docker Hub or anything like that. But this will give you a really good image of your currently running systems. Including some statistics and that sort of thing. We can look at the individual containers that are running, the images that we have on our system.
3:11We can actually do things like delete, remove those images if we want. Information about our system in general. But if we go to our running containers-- we can go to this-- let's see, go to nginx. So we go to the nginx container. And this is a lot like doing an inspect command on the Docker interface. But it just shows us some of the information that we actually might want to see. So here's some information about that. If we actually click on the name of it, it'll show us the stuff about the container, including the IP address.
3:48So all that time where we grepped for IP in the inspect command, now we can actually just go in here and quickly have a GUI interface. In fact, this is nginx. Let's see. From a previous Nugget, we were integrating containers. Let's see, if we paste that address in there, if it's still running. And sure enough, it's still running. Our web counter from a previous Nugget has now counted up to 70,901. But the Dockerui is a really neat interface. More for information gathering than anything else. You can do a few things, like I said. Remove images with it.
4:18But truly, its advantage, or its best purpose, is to look at information on your running system. That's really what it shines. Now there are some other GUI options. I'm going to mention them, and you can go check them out for yourself. But since it really isn't going to help you learn Docker anymore, I'm not going to install them or anything like that. But I do want you to be aware of them. Because you may end up needing them if you want to install and run Docker on your Windows or OS X system. I was going to give you URLs for each of these, but that actually has bitten me in the behind a few times.
4:51Because URLs change, and then here this video is. And you're like, that URL isn't right. So what I'm going to urge you to do is check these out, and just Google these names like with the word Docker. And you'll be able to find their current URL and download the software that's there. I want to talk briefly about them. Kit-imatic or Kite-matic. I'm almost positive it's Kit-imatic, but Kite-matic sounds cooler. It's from the folks at Docker. Now they released this. Unfortunately, right now, it's really, really buggy. About half the time I install it on a system, it just doesn't start up right even.
5:25It's just horrible. So you definitely do not want to use this in production. But it has an incredible GUI interface where you can start, stop, download, browse Docker Hub, all that sort of stuff. It is a great GUI interface. But most importantly, it allows you to run Linux containers on Windows and OS X. Because what it does is, along with its GUI software, it actually installs a Linux virtual machine on your Windows or OS X machine. And that way, you can use those Linux containers on it. So Kitematic is a great way to down-- you can download it and start playing with Docker right away.
6:00But I urge you to make sure you know what's going on. That's why I save this to last. I want you understand Docker before you take the shortcut and use a GUI. But if you're using Windows or OS X, this is the way that you want to check out Docker on your system without installing Linux somewhere else. Shipyard, it's a lot like Dockerui with some more features. As far as you can spin up images, or spin up containers from images, and that sort of thing. It also will manage multiple Docker hosts in the same interface. So Shipyard is worth looking at.
6:30Panamax is-- it's interesting. Panamax will manage Docker hosts along with other applications. It has its own marketplace, which is a little odd. But I wanted to mention it because it's a fairly mature and robust application that you can use to have a GUI interface. It's web-based, so is Shipyard. Kitematic is the only one I know of that's not web-based interface. It's actually a GUI tool on OS X and Windows that allows you to interface with Docker. But if you're interested in GUI interfaces, check these out. Even if you're not interested in GUI interfaces for manipulating Docker, I urge you to install Dockerui because it's very simple.
7:07It uses almost no resources, and can be a really nice interface for clicking around your running Docker system. I hope this has been informative for you. And I'd like to thank you for viewing.
Frequently asked questions
What does the Docker (v18.06.3) lesson cover?
The lesson explains how Dockerfiles, images, and containers relate as stages of running an isolated application, then has the learner run a simple app from a pre-built Docker Hub image. It moves on to building a custom image with a Dockerfile using RUN and ENV instructions and docker build -t, managing containers and images, mounting host folders for persistent data, and setting up a data-only container that separate containers share.
How long does the Docker (v18.06.3) lesson take, and how does it fit the full Docker course?
This lesson runs 2 hours 6 minutes. It is one part of the Docker course, which totals about 13 hours per learner and goes on to Docker Compose, Swarm, Kubernetes, and AWS and Azure container deployments. IT Directors can plan it as the hands-on foundation of a multi-week enablement path.
What prior knowledge does a team member need before starting this Docker lesson?
The trainer aims it at people who know what Docker is but have not yet used it on the command line, and it builds on an understanding of how containers isolate applications. The wider course is designed for DevOps professionals with roughly three to five years of experience.
Why does the lesson keep container data on the host instead of inside the container?
Containers are ephemeral, so they can be spun up and destroyed without losing anything important only if data lives outside them. The lesson shows a host folder mapped directly into a running web container, so file edits on the host appear in real time without rebuilding the image.
What can my team do with Docker after completing this lesson?
A team member can name, start, stop, and remove containers and images, get into a running container with exec -it bash, and build reusable images from a Dockerfile. They can also serve persistent external data from a host mount and use a data-only container so separate containers share input and output independently, giving Team Leads a common baseline for container work.
How can a Training Manager track who on the team has completed this Docker lesson?
Team reporting provides per-learner progress and completion, cohort and group views, and completion exports for audit evidence. Training Managers can use it to see who is ready for hands-on container work.
Team training path
Turn this skill into assignable team training
This free skill is a preview of the courses your team can assign, track, and report on with CBT Nuggets.
Free training library
More free lessons from CBT Nuggets
Microsoft Windows Server
Microsoft PowerShell 4 Foundations
Free lesson from PowerShell · 7h 57m
Networking
Border Gateway Protocol (BGP): Basic Operations
Free lesson from Border Gateway Protocol (BGP) · 60m
Networking
Define Wireless Network Architectures
Free lesson from Wireless Design Professional Training · 55m
Python
Introduction to Programming and Python
Free lesson from Certified Associate in Python Programming (PCAP) · 57m
Azure
Understand the Point of the Cloud
Free lesson from Microsoft Certified: Azure Fundamentals (AZ-900) · 1h 4m
Networking
Describe 802.11 HE Information Elements
Free lesson from Wireless Analysis Professional Training · 48m
$59
seat / mo, billed annually
