Talks

Containerized Ruby Applications with Docker

Docker’s lightweight virtualization may supplant our hypervisor-backed VMs at some point in the future, and change the way that tomorrow's Ruby applications are architected, packaged and deployed. Using Docker, your Ruby applications will sit atop an excellent platform for packing, shipping and running low-overhead, isolated execution environments. You will get a brief intro to the Docker ecosystem, get to know the tools and processes needed to create containerized Ruby applications, and learn best practices for interacting with the Docker API from Ruby.

Ancient City Ruby 2015

00:00:01.399 Thanks, staff! They're so nice. Before I start, I want to say that my name is Laura, and I am on the internet.
00:00:07.020 My Twitter handle and GitHub are similar, except for an underscore. I decided at one point that Twitter was dumb, so I deleted my account.
00:00:14.820 Foolishly, it turns out you can't get the same username back, so I had to add the underscore.
00:00:21.240 I'm here to talk to you about Docker, specifically about using Ruby with Docker. Over the course of the next 45 minutes or so, I hope to answer three questions for you. First, what is containerization? Next, how can I use Docker with Ruby?
00:00:35.280 And finally, how do I use Docker within my applications? Docker is very popular, and you've probably heard that name thrown around.
00:00:41.160 Companies like Google, Spotify, Twitter, Gilt, Groupon, and Netflix are all using Docker and blogging about it, tweeting about it. It really seems like some people are going a little crazy about it.
00:01:02.219 This is kind of how I feel about it sometimes. Ernie brought this up at the speaker dinner last night, and it is, in fact, in my presentation. Sometimes, it seems like people think, 'Well, let's just put it in a container.'
00:01:13.260 The reason for that is Docker is really easy to use, and people are experimenting with it a lot. I want to make one thing very clear before we get started: Docker is not a container; Docker is a tool for managing containers.
00:01:20.280 Docker itself is not a container. They're totally different things. What Docker does is it gives you the management side of containers; it not only executes the code inside but also manages the images and other resources needed to create and run containers.
00:01:44.460 Since containers are the object of manipulation in this containerized virtualization Docker world, first off, we're going to talk about containers and containerization and what they even are.
00:01:50.820 Once we learn about that, we can graduate to more in-depth concepts. Containers are a self-contained execution environment. Doesn't that sound easy and nice? The truth is that containers are not very difficult technically to understand, but the wisdom around when and how to use them can get a little muddy.
00:02:20.259 They share the kernel of the host system, they're isolated from other containers, and they typically have very fast boot times and low overhead. This is quite different from a virtual machine, which has a lot in common with containers but also some significant differences that we'll discuss.
00:02:44.519 A little insight into the technology that makes containerization possible includes four main categories. The first one is the container format. There are several, like Linux containers, libcontainer (which is what Docker uses), Rocket, and other container formats.
00:03:04.140 The other three categories include namespaces, which isolate processes on the kernel, cgroups (which stands for control groups) that allow your container to be a good multi-tenant citizen on your host, and the file system.
00:03:37.920 Docker uses a Union file system, which is essentially a write-on-copy structure. It's super fast and operates in layers, similar to a GitHub repository. If something goes wrong at the top layers, you can revert to an earlier layer and reconstruct from there without having to rebuild everything from scratch.
00:04:12.360 As we build our containers and images to run, I'll be doing some live coding toward the end of the talk, so bear with me. Containers can work in conjunction with virtual machines or completely in place of them; it's not an either/or situation. Most people use both together.
00:05:05.100 Many might have one virtual machine running ten containers—that’s a common workflow. Containers do have slightly more complexity, but the big benefit of using them is that they reduce the time and resources needed to run your application.
00:05:52.020 If you make a mistake and have to restart your virtual machine, it can take three to five minutes, whereas containers can take seconds or less. This can significantly reduce frustration in your work process.
00:07:14.700 Using containers results in reduced costs because they require fewer resources. You might wonder why everyone doesn't just use containerization. The truth is, many people want to put their services in containers to take advantage of these benefits.
00:08:12.840 When people start using containers, they often choose Docker because it is the most popular and accessible option. Docker is a tool for managing containers, not a container itself.
00:08:39.720 We have discussed execution, but there's also a management side to Docker. Docker clearly splits itself into two capacities: the engine for executing code and Docker Hub, which serves as the community resource.
00:09:29.400 The Docker Hub is the place for ideas, use cases, news from companies, and importantly, images. Each container starts with an image, and you can think of an image as a class while the container is an instance of that class.
00:10:09.360 Images live in a registry that is very similar to GitHub. If you're lazy like me, you'll appreciate the official repositories that contain images maintained by others. If you want to create an application using Docker containers, this is a good place to start.
00:10:47.160 For example, if you want to start a WordPress site, you can download WordPress and the database of your choice, link them up, and run everything smoothly without writing any code.
00:11:04.620 Before we get into images and containers with Ruby, we need to install Docker first. Some people complain that Docker has too many layers of abstraction and is too difficult.
00:11:51.660 If you're on Linux, installation is straightforward, but for most of us using Macs, you'll need to install a virtual machine that allows Docker to run. My weapon of choice is Boot2Docker, which sets up a lightweight Linux VM on your machine, syncing your folders.
00:12:36.600 I'm demoing with Boot2Docker today to make it appear as if I'm using Docker natively on my Mac, even though I'm not. If you have questions about how Docker interacts with virtual machines, don't hesitate to ask.
00:13:12.720 Docker also has a REST API for custom tooling within larger projects. Both the CLI and API have excellent documentation available at docs.docker.com.
00:13:45.000 Once we've installed Docker, our goal is to interact with the Docker daemon, which allows us to run containers. Everything starts with an image; the image is the first thing you'll configure when working with Docker.
00:14:33.920 As mentioned before, each container is an instance of the image you create, and an image is controlled by a Docker file. You can build your image with the CLI command docker build -t followed by your GitHub username and the image name.
00:15:31.560 This is important because it allows proper naming and tagging when storing images. Additionally, the 'docker pull' command allows you to interact with registries to download images for services you need.
00:16:05.880 Before proceeding, I want to highlight the importance of understanding the types of images on the Hub. There are static images, which are born ready for deployment, and dynamic images, which are not ready to run without added files.
00:16:54.260 When starting out, static images are recommended for dependencies, while dynamic ones are more suited for development. Beware that dynamic images might not function correctly without the appropriate files.
00:17:20.920 Now, let's build images. I will show you an example Docker file, going through it line-by-line to explain its functions. Docker files can take a while to build, so I will start building one as we talk.
00:17:58.660 I'm currently in a hello world application that consists of a lightweight Sinatra app that prints out 'Hello, world!' in the browser. We can reference the Docker file to see how it operates.
00:18:51.680 The Docker build command includes the tag hello-world to identify the image, and we specify the directory we're in as the build context. The build process is quick, demonstrating the power of Docker's layered file system.
00:19:49.308 Let’s review what happens during the build process. The docker file first starts with a base image—everything depends on it. The maintainer field indicates who to contact if issues arise.
00:20:30.220 Important commands also include 'EXPOSE' for advertising the ports the service will run on, along with commands for adding files, running installations, and starting the application.
00:21:09.780 By setting a working directory and executing commands within it, we build the app and install necessary dependencies before running the application with the Ruby command.
00:21:58.080 Also note that when specifying environment variables, the keys need to be in all caps. To dynamically mount your local file system inside the container, you can specify volumes, allowing for real-time changes to be reflected.
00:22:39.960 This is useful for development since you won't need to rebuild or reinstall everything in cases of code changes. Container management without gem management complexities makes Docker especially appealing.
00:23:11.160 Let’s check what Docker images are available. Typing 'docker images' displays the list of built images, with multiple instances of the same image linked together due to Docker's understanding of layered file systems.
00:23:57.180 In a live demo for error-reduction, I sometimes create a backup image called sad times in case something goes wrong. The resulting images can run easily without heavy configuration.
00:24:43.680 Executing a container is simple with the 'docker run' command, mapping the necessary ports to access our application externally. We'll ensure proper port binding rules are established to connect Docker containers to our operating system.
00:25:29.520 Once the container is running, my Sinatra app should be accessible, confirming the speed and efficiency of the deployment process. It’s evident how quickly containers can help in rolling out services.
00:26:19.920 However, the design is important in development environments to ensure smoother iterations without unnecessary deployment friction. The ease of re-linking dependencies is advantageous when working with Docker.
00:27:17.520 For setting a dynamic environment, I can run a base image, use volumes for mounting my project files, and use interactive runs for an efficient development cycle.
00:28:10.320 The good practice of updating local files in your development setup allows you to see changes reflected immediately, greatly enhancing your workflow.
00:28:59.520 With further changes, the light yet efficient processes in Docker environment allow for quick iterations and testing, confirming its efficiency in development.
00:29:43.560 Working with Docker images for Ruby is straightforward; there are official Ruby images on Docker Hub catering to various patch levels. The repositories offer comprehensive instructions on integration.
00:30:38.880 Using Docker API gems like those from Swipely can help you integrate Docker more easily into your Ruby applications. With over 30 related gems available, the ecosystem continues to expand.
00:31:39.060 Debugging within containers can be less enjoyable. Tools like Pry can help, enabling the use of interactive debugging sessions, although these are easier in a dynamic setup than in packaged services.
00:32:36.360 To summarize, we have learned to build Docker files, create images, run containers, and manage code using Docker. The key to efficient application architecture with Docker revolves around microservices.
00:33:51.600 Prioritizing small, nimble services rather than imposing monolithic designs helps you achieve the main advantages of Docker, allowing modifications and failover easily.
00:34:45.720 Each service should operate within its container, and communication happens through linking. Docker links allow containers to communicate, where one service waits for another before starting.
00:35:38.280 Configuration happens during the Docker run phase, enabling flexibility and portability. Avoid hardcoding credentials or environment variables in Dockerfiles to maintain security.
00:36:40.920 Instead, manage sensitive information at runtime. Using Docker comfortably means understanding its flexibility, such as defining unique identifiers for each service to maintain organization.
00:37:38.300 Remember, multiple containers can stem from the same image, allowing greater scalability in your applications. As you develop, balance configurations between Docker files and runtime to maintain flexibility.
00:38:27.900 Application templating is a revolutionary way to streamline your workflow when working with Docker, relieving tedious efforts in building and managing containers.
00:39:21.840 With tools like Docker Compose, it’s easy to manage configurations and streamline your interactions with containers, making your process smoother and more productive.
00:40:29.700 An even more user-friendly option is Panamax, which integrates with Docker, offering a GUI that simplifies the movement between templates.
00:41:15.460 In this application, comprehensive support for tracking links, variables, and images correlates with the commands you'll use regularly when building applications.
00:42:01.580 Docker should not appear intimidating; instead, it's designed to improve your development process. The proper tools have the power to optimize your coding efficiency.
00:42:54.500 Keep in mind that packages, configurations, and environments should be specified through Docker runs for best practice. With experience, you'll find Docker genuinely elevates your productivity.
00:43:47.500 Together, let’s continue exploring Docker and its growing ecosystem. Thank you all for your attention, and I hope you've learned something valuable about utilizing Docker today.
00:44:45.540 Please feel free to come up to me with any questions or clarifications you might have!