Containerized Ruby Applications with Docker
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 65 | |
Author | ||
License | CC Attribution - ShareAlike 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/37597 (DOI) | |
Publisher | ||
Release Date | ||
Language | ||
Producer |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
Ruby Conference 201454 / 65
2
3
4
6
9
11
14
17
18
19
20
25
27
29
30
32
34
35
39
40
46
47
50
53
55
56
58
61
63
00:00
Link (knot theory)Software developerTraffic reportingLink (knot theory)Food energyProper mapInternetworkingCartesian coordinate system2 (number)Graph coloringTerm (mathematics)Pay televisionPole (complex analysis)Computer animation
01:47
Run time (program lifecycle phase)Component-based software engineeringKernel (computing)Integrated development environmentPhysical systemOverhead (computing)BootingEquivalence relationOverhead (computing)Connectivity (graph theory)Core dumpService (economics)Physical systemDifferent (Kate Ryan album)Virtual machineVirtualizationKernel (computing)Multiplication signShared memoryGroup actionSmartphoneWorkloadTwitterIntegrated development environmentCuboidBitProcess (computing)GoogolProduct (business)InternetworkingRight angleBootingDebuggerComputer animation
04:12
Computer hardwareLibrary (computing)Computer hardwareVirtual machineRight angleFlow separationService (economics)Instance (computer science)Storage area networkSystem callLaptopIntegrated development environmentWindowComputer animation
05:42
File formatWindows RegistryHacker (term)Installation artCommon Language InfrastructureComputer-generated imageryLink (knot theory)Software maintenanceWindows RegistryCodeSoftware developerMedical imagingTwitterWindowSocial classMereologyDifferent (Kate Ryan album)Bookmark (World Wide Web)Presentation of a groupDirectory serviceWritingKernel (computing)Repository (publishing)Projective planeAbstractionConnectivity (graph theory)Run time (program lifecycle phase)LaptopComputer fileElectronic mailing listDirection (geometry)Library (computing)Radical (chemistry)File formatQuicksortBootingCartesian coordinate systemStructural loadGoodness of fitPrincipal ideal domainSynchronizationProcess (computing)Representational state transferFile systemVirtual machineInstallation artContrast (vision)BuildingNamespaceOrder (biology)Complex (psychology)Product (business)Instance (computer science)BlogComa BerenicesGroup actionPartition (number theory)FrequencyDataflowBridging (networking)Multiplication signBitNormal (geometry)MultiplicationComputer animation
14:27
Installation artFiber bundleRootVirtual machineImage resolutionDemonDirectory serviceComputer fileFile systemData storage deviceCartesian coordinate systemSemiconductor memoryBuildingComputer animation
15:07
Link (knot theory)Software maintenanceInstallation artKey (cryptography)Variable (mathematics)Integrated development environmentVolumeComputer-generated imageryRevision controlMedical imagingAnalogyComputer fileRepository (publishing)Object (grammar)Mobile appService (economics)Directory serviceWebsiteSocial classDemo (music)Revision controlDataflowVolume (thermodynamics)CodePoint (geometry)CASE <Informatik>Set (mathematics)Multiplication signKey (cryptography)Integrated development environmentInstallation artArtificial lifeData managementFiber bundleInheritance (object-oriented programming)Context awarenessVariable (mathematics)Windows RegistryComputer animationXML
18:58
RootImage resolutionFiber bundleVirtual machineDemonEvent horizonRepository (publishing)Computer-generated imageryMereologyMedical imagingService (economics)Keyboard shortcutWeb browserCartesian coordinate systemProcess (computing)Order (biology)Message passingParameter (computer programming)Military baseComputer animation
21:08
Computer virusComputer iconCartesian coordinate systemMultiplication signMotion captureVirtual machineComputer-assisted translationService (economics)Computer animation
21:54
Repository (publishing)Computer-generated imageryBackupLevel (video gaming)Server (computing)ProteinMaxima and minimaFerry CorstenIdentifiabilityVirtualizationMedical imagingCodeCombinational logicComputer fontCASE <Informatik>Right angleCartesian coordinate systemComputer animation
22:38
Computer-generated imageryBootstrap aggregatingCodeKeyboard shortcutLink (knot theory)ArchitectureRemote procedure callBlack boxService (economics)Time travelMedical imagingCodeLink (knot theory)Computer architectureAbstractionMultiplication signFunction (mathematics)Scaling (geometry)Cartesian coordinate systemCASE <Informatik>Projective planeBookmark (World Wide Web)Process (computing)Bootstrap aggregatingSpacetimeString (computer science)1 (number)Control flowDialectComputer fileCuboidComputer animation
26:32
Service (economics)Configuration spaceComputer configurationComputer-generated imageryString (computer science)Service (economics)String (computer science)InformationSocial classDifferent (Kate Ryan album)Variable (mathematics)Integrated development environmentSoftware frameworkComputer fileMedical imagingRule of inferenceWeb 2.0Rational numberFlagComputer configurationConfiguration spaceCartesian coordinate systemMappingCombinational logicObject (grammar)Run time (program lifecycle phase)Link (knot theory)Computer animation
27:53
Installation artSoftware maintenanceComa BerenicesLink (knot theory)String (computer science)Fiber bundlePasswordComputer-generated imageryCommon Language InfrastructureWindows RegistryComputer configurationStandard deviationCore dumpSimilarity (geometry)Multitier architectureAbelian categoryDefault (computer science)DatabaseIntegrated development environmentVolumeSource codeAliasingSoftwareService (economics)WordMedical imagingBitMultiplicationWeb 2.0Proper mapStandard deviationEquivalence relationPasswordLink (knot theory)Form (programming)Cartesian coordinate systemSign (mathematics)Multiplication signString (computer science)Variable (mathematics)Connectivity (graph theory)Computer configurationCASE <Informatik>Template (C++)Windows RegistryMathematicsIntegrated development environmentMappingNeuroinformatikType theoryRule of inferenceCodeComputer fileDescriptive statisticsConfiguration spaceNP-hardAxiom of choiceChemical equationSource codeTerm (mathematics)Independence (probability theory)Multitier architectureRevision controlProjective planeAdditionPoint (geometry)Scheduling (computing)Remote procedure callKeyboard shortcutFigurate numberMereologyFerry CorstenGoogolGroup actionOpen sourceComputer engineeringUniform resource locatorProcess (computing)AliasingSystem callDatabaseSpacetimeRun time (program lifecycle phase)Category of beingComputer animation
34:46
Computer-generated imageryLevel (video gaming)ProteinServer (computing)Maxima and minimaComputer iconService (economics)Web serviceTemplate (C++)Repository (publishing)Directed setSlide ruleSeries (mathematics)Home pageTemplate (C++)Cartesian coordinate systemWindows RegistryIntegrated development environmentString (computer science)Service (economics)Game theoryLocal ringMedical imagingRow (database)Remote procedure callType theoryEquivalence relationVariable (mathematics)Open sourceMusical ensembleReal numberMereologyBitOcean currentLattice (order)Reduction of orderOffice suiteRing (mathematics)Computer animationLecture/Conference
37:14
Projective planeOpen sourceMedical imagingLevel (video gaming)Virtual machineMultiplication signGroup actionDifferent (Kate Ryan album)EvoluteExpert systemForm (programming)Staff (military)Office suiteBlogCartesian coordinate systemFile systemBootingPasswordMereologyComputer animation
Transcript: English(auto-generated)
00:19
My name is Laura Frank. I'm a senior engineer at CenturyLink Labs. We're a pretty small R
00:24
&D offshoot of CenturyLink proper, so we don't really deal with any telephone poles or cable subscriptions. But what we do is a lot of R&D around Docker and the technologies that are kind of tangentially related to Docker like Fleet, CoreOS, Kubernetes, you may have heard some of these.
00:44
We kind of look at how they're serving the development community, how we work with them, and then hopefully try to make them better. I'm on the internet. You can find me. I also share a name with a reporter from a Colorado newspaper. I'm not her.
01:02
So, like I said, I work with Docker a lot. Here I'm going to talk about Docker and Ruby together. Over the course of this talk, I'm going to try to answer three kind of large, ambitious questions for you. The first being, what are Docker containers? The second, how can you use Docker and Ruby together?
01:23
And then finally, how might you architect an application using Docker and Ruby together and actually have it work? I assume that most of you have heard about Docker but maybe know nothing about it, and that's just perfect. I'm going to go over a lot of the pretty basic introduction stuff to Docker. If you are a Docker user already,
01:42
hopefully I'll shed some light on some of the technical underpinnings of Docker. Has anyone actually... I know last night there was a Docker BoF. Did anyone attend that in the audience? A few? Okay. One guy? All right. I sadly did not attend. I was stuffing my face full of fish
02:03
because I live in the Midwest and it was pretty special. So, what is Docker? You've probably heard about Docker because companies like Google, Spotify, Twitter, Gilt Group, countless others have been really talking a lot about how they're using Docker in production
02:22
and all of the fun and complicated problems that it has solved for them. But the truth is that Docker is really not... Or the idea of container-based virtualization is not really anything new. LXC or Linux Containers has been around since 2008. But Docker kind of puts this nice pretty front end on it and it makes it a lot easier for everyone to use it. And also, as more people are using the internet all the time,
02:47
these production workloads can fail at a much more rapid pace than maybe they were before everyone was on their smartphones all the time. So Docker has this really big need that it can fill. So Docker at its core is a packaging tool. It sits on top of existing components of the Linux kernel
03:06
and packages these containers and puts them into isolated execution environments. That's really all that it is. Docker has a very limited scope. It does not schedule jobs for you. There are lots of things that it does not do for you. What it does do for you is package your stuff and put it in a container.
03:25
And a container really is nothing more than just a self-contained execution environment. I'm going to talk about how exactly this is set up in just a little bit. But think about it as something in a box that is isolated from everything else around it.
03:42
It has a benefit of having the shared kernel of the host system that it's on with having isolation. So they're sharing an isolation, those things together, give it a very fast boot time and low overhead and also makes things work very efficiently because you're getting rid of a lot of duplicitous work. And in fact you will see a big performance benefit from a service that's running in a virtual machine
04:04
or a service that's running in a container. And this is due to very, very big differences between how these services actually run on the host. So here's an example of a pretty typical virtual machine setup. Probably have something like this running right now.
04:21
In this example we have two different services. We have app one, which is one service, two instances of that service, and then app two. And they're in virtual machines. On each machine there's the library, there's a guest OS, we have a hypervisor underneath all of those, of course sitting on a host OS and sitting on top of hardware. In the Docker world though we can get rid of the hypervisor, there's really no need for it.
04:45
And we can get rid of the guest OS on every virtual machine. And instead we're going to introduce something called the Docker Engine. This is the actual packaging tool that's sitting on the host putting things into containers and deploying them for you. You'll notice that the libraries now instead of being in the container are actually underneath the container.
05:05
This lets each container that's identical reference back to the same library. There's no need to have duplicitous copies of everything. Maybe an easier way to understand it is at the San Diego Zoo. I was just there on Sunday. The koalas are all in their own little self-contained environments,
05:24
but each koala does not need to have its own health care giver. And they have access to the same food supply. I mean it would be really silly to have a separate veterinarian per koala. You kind of don't want to have a separate library for each of your containers.
05:40
Also koalas are very cute. So how does this work? Containers seems kind of very abstracted and maybe difficult to understand. And they are. I mean we spent the last nine months working on a tool that sits on top of Docker, and we still kind of want to throw our laptops out the window most days.
06:01
But there's really four big things that make Docker run the way that it does and give you all these great performance benefits. The first one is libcontainer. This is the container format. So maybe several months ago, I don't exactly remember when, but Docker launched libcontainer, which is its own equivalent to LXC.
06:23
Previously Docker was just building on top of LXC, which is why it could only run on Linux. But now libcontainer is a different container format that's very, very similar to LXC, but actually has the capability of running anywhere. You can probably, if you pay attention to Docker blogs, you'll see that they're starting to think about running it on Windows.
06:43
Maybe it can run on a Mac natively soon. It's all due to this libcontainer container format. For our purposes and the examples we'll look at today, we're just going to use libcontainer. We could use LXC. It's kind of a layer of complexity that we don't need to spend too much time on. The next thing, now this is like the three really important things, namespaces.
07:03
This is what makes the container isolated from everything else. So this is process and not resource. So this is networking, this is process ID or PID. All of these are happening in its little namespace so that it's not going to conflict with other containers that are on the same host.
07:23
This is what puts it in its little partition. On the other side of that is a thing called cgroups, which is a container group. This is what allows these containers to be good multi-tenant citizens and access shared resources when needed, like the library or the veterinarian if our containers are koalas.
07:42
The last thing is the union file system. This is particularly what makes Docker very fast. The layered file system is the copy on write. Everything that happens when you're building the image to run your container from happens sequentially and everything is stacked and stacked and stacked. Think of it as your git log.
08:02
If you want to go and redo, maybe just rebuild something on your image, you can point it back at maybe like three layers before and rebuild from there. You don't have to go all the way back and get rid of your git directory and clone it again. You can just reference back and then build on top of it.
08:22
So those are the technical things that make Docker this lightweight runtime and packaging tool using components of the Linux kernel. The other great thing about Docker, though, it's more than that. It's a development workflow and an ecosystem, which is why Docker is so attractive to developers working in small teams and developers working for companies that have production loads like Google.
08:44
This is sort of what Docker looks like. On one hand, we have the engine, which is what I just talked about. That's all the technical stuff, the code execution, et cetera. On this other side, we have a hub. This is where people go to collaborate and share things with one another related to Docker.
09:03
The cornerstone of this hub part of Docker is called the registry. You can find it at registry.hub.docker.com, and it looks a little bit like this, or this is what it looked like when I took the screenshot. This is where images go to live. If you work on a Docker image and you would like to share it with people,
09:20
you can push it to this public repository, the public registry. You can use a private registry if you have some proprietary images. It's a whole other talk, though. You'll notice about a third of the way down, there are these things called official repositories. These are companies or communities that have been using Docker
09:41
and say, it would be really great if we would just put an official image up here that people can use so they don't have to do the same work over and over again. For example, if you wanted to use MongoDB in your project, you don't have to build that image. Just use the one that MongoDB has put up there for you to use. Almost all of these, actually all of them, do have great documentation about bootstrapping your own project
10:03
to use these official images. But we have to install Docker before we can use it. This is one of my favorite tweets because Docker does get a lot of flak that it abstracts things a lot, maybe too much for some people's comfort.
10:23
There's many layers usually between the hands that are typing the code and the code that's actually running in a container, whatever that is, somewhere on a host. So I'm not gonna lie, it can be kind of a hurdle to get over when you start using Docker. The good news is there's a lot of tools to help you bridge that huge gap
10:43
that it can feel like you have between you and your code. If you're on Linux, like I said before, Docker was built at first off of Linux containers. You can just install Docker with official packages and you can be ready to go. But if you're on anything else, you will have to run a VM.
11:01
And I realize that sounds maybe in vast contrast to what I just told you about how VMs are evil and bloated. But I guarantee that running one VM where you can run thousands of containers or hundreds of containers, depending on how big that VM is, is not really gonna impact your performance very much. And in fact, Docker has this great tool called Boot to Docker.
11:23
And you can find that on Docker.com when you look in the installation instructions. It's basically a very lightweight tool that will spin up a VM for you in the background, get Docker running on it, make everything work for you. And it will sync all of your folders so that you can interact with Docker on your Mac or Windows machine.
11:42
Just like you're just on your normal terminal. And I'm actually gonna use this in my presentation. It will look like I am just typing and interacting with Docker directly. In fact, I'm using Boot to Docker and there is a layer of abstraction. Everything I'll do in this presentation is running on a Boot to Docker VM. And then when you do have Docker installed, maybe with Boot to Docker,
12:02
maybe your own vagrant file, certainly whatever you prefer will work, you're going to interact with Docker, probably via the CLI. There's also a REST API for interacting with Docker. And both of these have extensive, wonderful, beautifully-written prose documentation at docs.docker.com.
12:22
All right. On to the good part. Using Ruby with Docker. So specifically, how might you use the API and the CLI and an image to make a container that's running Ruby and that can run your Ruby application?
12:40
Before we really get into spinning containers up, we have to take a step back and really acquaint ourselves with what an image is. Think of a Docker image as the class and a container is an instance of that class. You have to have an image in order to start a container. You cannot start a container without an image. The container will have nothing in it.
13:01
Each image is controlled by a Docker file. This is basically a list of instructions. We're going to look at a Docker file in just a few seconds, and we're actually going to build an image together. It'll be really fun. Images are built by saying docker build. Dash T is for tag, and then you give it a name.
13:22
Generally, a convention that's used is like your GitHub name slash name of your image. You can also just call it whatever you want. And then a dot to signify where the Docker file resides. Most often, it'll be in the directory that you're in. Going back to that Docker registry that I mentioned before, whether or not it's a public registry or a private registry that you are running yourself,
13:43
you can Docker pull an image down. Pull it down just by using the name of the image, which again is usually the person's GitHub name and then the name of the image. Optionally, there is a tag for a version, which is a colon tag. We'll see this when we look at the Ruby image, which is right here.
14:01
This is a Docker file. This is a very, very, very, very simple application. You can see that it's based off of 2.1.2. It does some stuff, and then eventually down here, we have a command that we're going to start the container with.
14:21
So why don't we build this? Maybe, hopefully it works. Okay, you guys can all see that? So I'm in this, sorry, here I am. In my directory, I have kind of all the junk I need to run this application. Most notably, I have a Docker file, which is the same Docker file that we just looked at.
14:43
So I am going to Docker build dash T. I'm just going to call this hello world, and then a dot because it's where I am now. And we can see this layered file system already in use. We can see step four, and it's giving us kind of the place in memory where all this stuff is stored.
15:02
So this might take a little while. So while we do that, hopefully that works. Live coding or live demo is always a little nerve-wracking for everyone involved, including the audience.
15:24
So thank you, guys. All right. Again, this Docker file is super simple. The from command is a requirement. You have to have a base image that your image inherits from. So similar to that class object analogy that I used earlier, inheritance also works.
15:43
So anything that the CenturyLink base image has will also be in my image because I am referencing it and pulling in all of its stuff. Notice the colon 2.1.2 because this is Ruby 2.1.2. You can use any version. CenturyLink, we have spent a lot of time optimizing Ruby images.
16:03
If you're interested in using them, you can find them on the hub at the CenturyLink repository. The next thing is maintainer, so that's me. And if it breaks, then you can blame me and know where to find me. The next thing is an expose command. This just kind of advertises that your service is available on a port.
16:24
It will advertise that to other containers that are running on the same host. Next we have a set of run and add. A run command will run the command that is passed to it. So in this case we're going to make a directory, an app directory.
16:40
And then add is basically like a copy command. So we're going to copy everything from the current directory into that new app directory that we just made. And then next we will set that app directory as our workdir, working directory. From this point forward, everything that's passed to the Dockerfile via run happens in context of this workdir.
17:04
So when we run bundle install, it's going to run specifically only the gemfile that is in that directory that we just made. And then last but not least, this is the thing that actually makes the container do something. This is command or CMD. So for this we're just going to enter with very basic Ruby hello world.rb.
17:28
And this is one more that's kind of important. You'll probably see it in a lot of the other Dockerfiles that are available on Docker registry. This is an environment variable. It takes the syntax of key in upcase and then value in downcase.
17:44
And any environment variable that you give it in the Dockerfile will be understood and known and used by any subsequent run command. And then the next one is volume. You can either say give it a path or you can give it an array of paths.
18:00
This just creates a mount point. This is how you would get code into a container by creating a mounted volume of that code. And before we check on our image that's hopefully downloaded, this from thing is actually pretty powerful and really important and can change the... Take your Docker workflow from being like okay to being really super great.
18:24
Basically in a perfect world we'd be using the same version of Ruby in all of our services hopefully. But really you only need one base image. You can reference that base image from other Dockerfiles for other services that you're running. And then also this has Ruby baked into it. You don't need to have a gem set manager or a version manager because there's just one thing.
18:45
There's just one set of gems, there's just one version. It's baked into your base image. If you do want to update Ruby then you can just update the base image and then that again will be shared across everything.
19:04
Okay cool. Successfully built. That's excellent news. I'm just going to clear this for you in the back. That bottom part might be hard to see. Alright so Docker images is the way you look at all the images that are on your host.
19:22
I think I had a partial failed build which is why I have this weird none none. But you can see that here, CenturyLink Ruby base is actually treated as a whole separate image. Remember that's my base image. And then this hello world is, you know, everything from the base image forward is in that hello world.
19:41
And in fact if we delete this hello world, I'm not going to do it right now actually. I think that would be a bad idea. And then rebuild it. We would see that all the work that Docker had to do to get that Ruby base image doesn't happen anymore. We don't need to do it. We've already stored it. We're just going to delete everything from the base image.
20:00
And since the base image would be shared again because I'm running the same thing, it would just do the work, whatever those seven instructions were after building the base image in order to kind of rebuild the same thing that I did before. So again, translate that into maybe having multiple services that share the same base image. It's a lot of work that you can save by just putting all of your kind of inherited dependencies in that base image.
20:26
So why don't we run this thing? That would be a great idea. The way to look for processes that are running on your host is Docker PSA. That will give you all of the processes that are happening. And you can see we have nothing happening right now.
20:44
So let's Docker run. I'm going to pass a port binding because I want you all to see this in a browser. So that's dash P. And I'm just going to bind 4567 kind of to itself. And then the last argument I'll pass is the name of the image.
21:03
And that was it. And now we have a containerized application running before your very eyes. So think about how long it took to run that.
21:24
It was like literally milliseconds. Think about how long it might have taken a virtual machine to spin up and run that same application. Probably many, many milliseconds. Think about how many times you have to restart a service over the course of your daily work when you're developing stuff.
21:43
If you can shave that down from minutes down to milliseconds, you have a lot more time to look at cat pictures or whatever you want to do. So cool. We have this here. It's running. I can see it. And then I'll just shut it down and we can see that container.
22:07
Container is running. It's exited. We get exit codes for Docker containers. And if I wanted to start it again, I can either reference its identifier or its fun name. Which in this case is hi Shockley. It's always like some combination of adjective and like scientist or something.
22:24
Usually this looks a little nicer. I just have the font blown up pretty big on here. All right. So that's it. That was running a Ruby application.
22:41
Cool. So in this case I used our own century link base image. Ruby does have a lot of official images. And they are up on the Docker hub. Pretty much anything 1.9.3 and newer you can grab. And again, just a Docker pull. And really great instructions for bootstrapping.
23:02
And like I said before, the base Ruby images, the official ones, are a little big. Specifically my team has spent a lot of time trying to make them very small. And eventually I think we would love to have our images be the official Ruby images. But we're just not quite there yet. So you're welcome to use either. Depending on what you want to do.
23:23
And lastly you might need some gems. Swipley has done a lot of work with Docker and they have a few really good gems. The one that we use for the projects that we work on is the Docker API gem. So this allows you to interact with the Docker API from inside of your application. If you go to Ruby gems, there's probably 35 other ones.
23:43
Anything from building images to running Docker PSA and having a nice output of all the processes that are running on your host. So just poke around. And some of them are obviously more developed than others. And some of them have more users than others. But you could probably find anything that you need there.
24:03
And also debugging in a container is kind of a pain. Like I said before, Docker has a lot of flack because it has so much abstraction between your code that's running somewhere out in the ether on a container and you actually doing the work.
24:22
What we found on our team is that we use Pry if we need to. We try to run things kind of locally before we put them in a container, but that's not always really that possible. So I hope you're all using Pry already. And if you're not, require the thing and then call the thing and you'll be dropped into a nice debugging session.
24:45
And apparently you can time travel now with Pry. So I'm going to try that as soon as I get back to Chicago. The one piece of advice I have for all of you, if you're using Pry, you may think, oh, it's in a container, it's away from me, I have to use a remote debugging session.
25:02
You really don't need to in most cases. In some cases, you might have a container running in the background and then you might have to set up a remote session. By and large, generally, if you're just kind of tinkering, you don't need a remote session. Alternatively, you can pass in the Pry command directly to that Docker run string
25:20
and be dropped into a debugging session with the Docker run name of the image. And then after the imaging, you can say Pry, that's the equivalent to the command that we saw in the Dockerfile, and you can just be dropped right in. So now that we know how to fix stuff that breaks, we could probably start putting some stuff together.
25:40
So how do I build the thing with Docker? So let's talk about architecture, which is everyone's favorite topic, usually. Docker architecture is service-oriented architecture, plain and simple. Think about how fast it was milliseconds to get that service running.
26:01
That really is beneficial if you have just one service per container. You may look at a container and say, wow, this is really fast, it's taking up a lot less space, I can just dump everything into one container. And then it'll be really fast and great, which is kind of true. But if you have each service in a different container, if any of those fail, you can spin it up very, very quickly.
26:24
Also for scaling, it's much easier to scale individual containers than giant containers that are monolithic black boxes. So here we have a nice illustration of one service in one container. This is a very simple application. It has a web framework and then a database behind it.
26:43
So we might look at this and say, okay, but a container is isolated, so how does container 1 know that container 2 exists? And furthermore, how can I even get them to exchange information with one another? And the answer to that is, there's a few of them. You can link them together using something called a Docker link.
27:03
But more commonly, you'll probably use some kind of combination of port mapping and then environment variables, depending on particularly what requirements your services have. All of this is just configuration. I mean, it's really nothing more than just configuration.
27:22
And this configuration happens in two places. We've seen already that the Dockerfile can handle a lot of these options. That's baking them into actually the base image, like that class that then becomes the object, which is the container. But then also you saw me just before make a port mapping rule in the Docker run string.
27:43
So there's a lot of different flags that you can use in the Docker run string, and most of them kind of have shared work. You can either do it in the Dockerfile or you can do it at runtime. So let's take a look again at this dummy app and look at the Dockerfile. I'm going to try to help you understand maybe some best practices of what should go where
28:03
in terms of making a choice between where you want your configuration options to live. So we have this Dockerfile. More or less, this is just fine. I don't have anything too specific or too particular. So for example, I might be using this for one reason, but if I put it on the Docker Hub and have someone else use it,
28:25
I don't know what they're going to be using it for. So I don't really want to hard code anything, like maybe a port binding rule. I don't want to put that in there. And I really, really don't want to put environment variables in the Dockerfile.
28:40
It sounds funny to think about, but if you don't know maybe what you're doing, you might accidentally put something in a Dockerfile and commit it to GitHub or to the registry, and then everyone has your password. So that is particularly one thing that you want to do just at runtime. Don't put that in the Dockerfile. So let's look at the kind of equivalent of that Dockerfile but with a Dockerrun string.
29:04
So again, Dockerrun, we have dash P here for the port binding rule or port mapping rule, whatever you'd like to call it. And then here is where your environment variables belong. This is dash E. You can put quotes around it or you can not, depending on how you're feeling that day, I guess.
29:22
Always, again, password and up case, equals, and then unless your value is case sensitive, it should be in down case and there should not be a space in between the equals sign. I think keynote just got a little ambitious there. And then finally, that linking thing that I talked about earlier. Docker has a capability for linking.
29:41
You can say that one thing, in this case, the web container that I'm running with a Dockerrun string depends on the database, and you give it a name and an alias. So DB, DB in this case. And then, again, the last thing that you pass if you're not passing a command is the name of the image that you're actually running.
30:00
And again, a word of caution about using a Docker link. When you're using Docker directly on your own host, that's great. You can use a Docker link. But if you're doing any kind of scaling, you might be using Kubernetes. You might be using Marathon and Mesos or Fleet with various service discovery components. That's not Docker and it doesn't know what a Docker link is.
30:22
So if you're going to have some kind of scheduler orchestrating your Docker containers, don't use a link. Use the environment variable and it's kind of like port mapping way instead. It's kind of advanced stuff. If you have any questions, of course, you can talk about it later, but I won't take up any more time talking about it right now.
30:42
So a little bit more about the Dockerrun string is that each container has its own. You can only run one container with one command. Multiple containers can use the same image to run from. It's not like you have to have a different image for each container. You can use the same image to run multiple containers. And again, you want to find the balance between the Dockerrun string and then
31:05
the Dockerfile for configuration so that you're not exposing anything that shouldn't be exposed. But again, you have to do this whole configuration business every time you run a container. And I'm really lazy. That's why I became an engineer.
31:20
And I would rather make a computer do the work for me than do it myself. And the good news is that you can do that with Docker. There's this idea called application templating, and that's what my team and I spend our time working on is kind of the equivalent of form and up but for Docker containers. So if you understand and configure your container or your application once, you can put it into an application template.
31:42
And instead of running each container independently, you run the template that will take care of running all of the containers with the various configuration options that you've already specified. You can use your own images. You can use images from the Docker registry. Specify your options beforehand so you don't need to do them on the fly.
32:01
And then again, you can just run the application as a whole instead of running each container independently. So a popular one is Fig. This is actually a part of Docker proper now. It used to be its own thing, and then Docker acquired them. And that's a great thing because that means that Fig standards are very tightly coupled with Docker standards. How it works is you dump your application requirements into a YAML file called Fig.yaml and then run Fig up.
32:28
And then your application is running for you. It's at Fig.sh. And again, this is a proper Docker project, and it's maintained by the Docker community. It is command line only, though.
32:41
So if you're looking for something that is a little bit more visual as you first get started or maybe you prefer to work that way, the software that I work on with my team is called Panamax, and we have t-shirts if you'd like one. It's a Docker workflow tool. It itself is a containerized application depending on how you're using it. When you run Panamax, you'll actually be running anywhere from three to five at Ruby services in containers.
33:08
Panamax does use a lot of these Docker adjacent technologies like CoreOS, Fleet, etc. and CD for things like service orchestration and service discovery. And you can find us and all that good stuff at Panamax.io.
33:23
So Panamax on purpose, we made this very similar to Fig. If you start with Fig and you decide you want to try Panamax or the other way around, it is really easy to go back and forth between the two tools. In addition to just having a UI, the other thing that Panamax has is support for remote deployment. So if you do get to a point where you're deploying this to a cluster running on Google Compute Engine,
33:43
you can do that with the click of a button from Panamax. And if you want to download it, you can go to Panamax.io, get Panamax. It is an open source project. It is all in Ruby. We are all Rubyists. So if you want to contribute, that would be super great. This is what an application template looks like with Panamax.
34:02
So this is kind of an abbreviated version because there's a lot of other stuff that's maybe not so pertinent to this example. But we give it a name and a description. There's also support for things like documentation in there. And then you just start listing your images. So in this case, we have our Rails application with Postgres. And the first thing that we have is our web tier category, which is, of course, Rails.
34:24
We have a source image. And then description of it, kind of type. The good stuff is down here in ports. All this configuration you just do once. And it stays with this template. You can, of course, change the template if you'd like to. But every time you run this template, the same exact things are going to happen over and over again.
34:45
So why don't we look at Panamax. This is the home page of Panamax. This is hooked directly to the Docker registry.
35:03
We also have these fancy little buttons. So if you're interested in maybe running a Rails application, you can click on Rails. And all of the pre-existing templates, which there are quite a few. There's probably 30 to 35 public templates that have been vetted by this lovely team of engineers that's sitting in the front row and myself to make sure that they do work.
35:23
And from here, you can just press run template. So you don't have to type anything. You can run locally. Or you can deploy it to your remote target, for example, like your Google compute cluster or whatever kind of cluster you want to run. I'm just going to run it locally. And we'll see Panamax starting the application.
35:43
And this may take a little bit. It has to download the images. So everything that started with the Docker run string, it's just going on kind of in the background here. But great news. It was successfully created. And then I can see both of the services that I have here as well as my journal.
36:00
So let's go in to download the images. And our familiar little friend, the Docker run string, is over here. So what we really try to do with Panamax is make Docker easy but not secret to use. And, you know, to that end, we do keep all of the artifacts around. We do show you the Docker run string.
36:20
For example, if I wanted to add an environment variable in here, we can see the Docker run string auto update itself just as I typed that. So when you use something with Panamax, you'll know exactly the equivalent of what you would be doing in real Docker on the CLI. Except that you don't have to do it. You can just save it, make it a template, and then run it with a click of a button.
36:46
I love application templating. It's kind of the game changer when you go from just tinkering with Docker to actually using it for maybe bootstrapping your development environment. Or managing all of your dependencies. If you have Postgres and Elasticsearch for every service or every application that you work on, just make a template with them and press, like, run.
37:08
And then you have them. You don't have to kind of go through and set up all of your VMs or containers independently. And again, it's a Ruby, open source Ruby project. You can find it on GitHub at CenturyLinkLabs.
37:22
And there's a few issues in the backlog if you want to work on it. Just saying if you don't mind. Okay. So that's it. We talked about what Docker is, what containers are, how to run them, how to run them with Ruby, how we might architect an application, and then finally how to template those applications to save yourself a lot of time.
37:47
A few parting thoughts as you start on your containerized journey. Use Boot to Docker is really great. As you saw when I was hacking away at Docker here, that was actually using Boot to Docker. I wasn't on my own machine. That was on a VM, but it sure didn't feel like it.
38:04
Extract commonalities and put them in a base image. Anywhere you can use inheritance, please do it, because it will save you so much time and resources because of that layered file system. Again, please don't put any passwords in your Dockerfile. And then use templating. It's a really fast way to get started.
38:21
If you're looking for other resources or maybe you want to get started, some pretty good places to start. You want to look at the Docker Hub, see what's already out there and already exists. There's no use in reinventing the wheel, so you can use one of those official images. Go for it. Docker has great documentation. Again, Boot to Docker. And then if you are interested in templating, you can look at Panamax or Fig at fig.sh.
38:43
And then finally, the team of engineers I work with, we all write sometimes long-form blog posts on different Docker images and sometimes do tutorials. And you can find that at centurylinklabs.com. So thank you so much for being a great audience, and I hope you guys learned something about Docker.
39:03
If anyone has any questions, I'll be happy to answer them or pretend like I know the answer.