00:00:08.030
I'm here to talk about building Rails applications with Docker. This talk will cover general applications, and anything I discuss today can be applied to whatever kind of application you're building. I like to provide practical examples that you can go home and implement from your couch or wherever you feel comfortable. I will use Rails as a basis for that discussion. I work at CodeShip as an engineer, focusing on Docker. We also work extensively with Rails and Ruby at CodeShip. During this talk, I won't dive deeply into what CodeShip does, but we do have a booth in the lounge area if you'd like to chat with myself or Kurt, who is also here. Look for the big anchor that says 'Always Keep Shipping.'
00:00:37.469
Today, I'm going to cover a few key topics. First, I will introduce containers: what they are, how they differ from virtual machines, and how they work together. I'll then touch on the Docker ecosystem. Docker started as a small project and has since grown into a vast ecosystem with many tools, which can be quite confusing. I'm here to demystify that a bit for you. Finally, we'll work through some examples of using Docker with a Rails project. I'll fire up a couple of Rails applications and run them in Docker, demonstrating some advanced migration techniques. I plan to conduct many live demonstrations, so if you want to silently offer some good vibes to the demo gods, I would greatly appreciate it!
00:01:30.689
Before we dive into practical examples, I want to ensure you understand exactly what we're working with. I'll provide a brief introduction to containerization before we get our hands dirty. If you've heard about containers or worked with them, you’ve probably used Docker. It's crucial to note that Docker and containers are not the same thing: Docker is a tool that manages containers, but it is not a container itself. You'll use Docker as your interface to manage containers. There are many other types of containers and containerization techniques besides Docker, but Docker has simplified working with them. This ease of use is one of the reasons it has gained popularity.
00:02:29.750
So what does Docker actually do? Docker builds your images for running as containers, and it executes code inside those containers. Additionally, there's a project called Docker Machine, which helps manage entire applications using a tool called Docker Compose—something I'll be demonstrating later on. If you started using Docker in the last six to eight months, you likely encountered Docker Compose already. Docker also helps provision machines to run Docker through something called Docker Machine, which adds substantial value to its functionality.
00:03:05.300
Let's discuss containers themselves. Docker manages containers, but what exactly is a container? A container acts as a virtualization layer, serving as a self-contained execution environment, much like a virtual machine (VM). You can think of Docker containers as somewhat analogous to VMs, which is about 80% correct. The key difference is that while containers share the kernel of the host system you're running them on, they remain isolated from other running containers unless given explicit permissions. Containers are lightweight; they boot up really quickly—often in under a second—which is particularly valuable in the development process. In contrast to traditional VMs, which can be cumbersome to rebuild and manage, a container can simply be deleted and recreated in a matter of seconds if something goes wrong. This makes them excellent for development workflows, as they provide isolation and prevent substantial system disruptions.
00:04:25.970
Let’s visualize this comparison between applications running on virtual machines versus those running with Docker. When using virtual machines, you have a hypervisor managing your resources, and within that system, each service has its own guest operating system along with the libraries they require. This method can be resource-intensive. On the other hand, in the Docker world, we eliminate the need for dedicated guest operating systems and hypervisors by replacing them with a container runtime engine. This change leads to a significant reduction in the resources needed to run applications. Overall, although getting started with containerization might appear complex at first, containers drastically lower the time and space needed to run applications. The bottom line is that containers allow developers to spend less time on maintenance and dependencies and more time building features.
00:07:16.080
How do you integrate containerization into your development workflow? You'll likely adopt Docker, which has evolved from a tiny project in a basement in Paris into a billion-dollar startup in San Francisco. Docker has streamlined its functions into three main categories: build, ship, and run. In today's talk, I will primarily focus on the build step, which I believe is the most useful for developers beginning their journey with Docker. The complexity of running Docker in production requires additional tooling and is outside the scope of our discussion.
00:08:06.029
The first concept in Docker is the Docker image. A common misconception is that images and containers are the same thing, but they are quite different. When you pull something down from Docker, you're pulling an image. Picture an image as a class in programming and a container as an instance of that class. If you run 'docker pull ruby,' you're retrieving a Ruby image—not a container. This distinction is essential, as it contributes to clearer communication and troubleshooting in a complex system. The Docker Hub is a public registry where you can find a vast collection of images. As of my last check, there were about 15,000 images available on Docker Hub. It's a great resource for developers grappling with how to implement specific features in their applications.
00:10:28.209
The Docker Hub also functions as a GitHub-like platform for Docker images, offering webhooks, build triggers, and authentication features. It provides private repositories as an option, in case you want to push an image to the public registry but keep it private. You’ll probably interact with Docker Hub via its graphical user interface (GUI) or the command-line interface (CLI). Depending on your development setup, you may need to refer to the documentation for tips on using Docker images effectively.
00:12:24.610
There are three different types of Docker images you might encounter: service images, project base images, and official images. Service images are what you’re likely looking for right away since they come with endpoints to consume services, like a database you can run in a container. Project base images, like Ruby, merely provide a runtime environment for building applications—you’ll need to add additional components to run a service correctly. Finally, official images are maintained by the community or the companies behind those services, ensuring they're up to date with the latest versions. It's generally a good practice to use official images whenever possible.
00:14:44.910
To create your own Docker images, you first need to define a Dockerfile. Each image begins with a Dockerfile, which is a list of instructions for building the image. You'll use the 'docker build' command, specifying a tag for the image name. This naming convention is usually similar to how GitHub names repositories: 'username/image-name.' Don’t forget to include a '.' at the end of your build command to indicate where your Dockerfile is located.
00:16:28.670
A well-written Dockerfile can optimize the size and performance of your application. Each Dockerfile must contain a 'FROM' command to specify the base image. For my Rails application, I use the official Rails image as a starting point while ensuring that I set a specific version, avoiding the ‘latest’ tag in favor of a more stable version. I recommend being cautious with the 'latest' tag due to possible breaking changes that can be introduced and lead to debugging headaches.
00:18:55.170
Additionally, the Dockerfile can include various commands like 'RUN' for executing commands during the image build and 'COPY' for adding files to the image. It's essential to maintain a proper working directory context for running subsequent commands, preventing common pitfalls in executions. The 'CMD' instruction specifies the command that will run when the container starts. For instance, in my case, I'm using 'rails server' to fire up a Rails application. Important special note: When binding the application to a port, especially on non-Linux operating systems like macOS, correct port mapping is crucial to avoid connectivity issues.
00:21:49.730
Once the Docker image has been built, you can manage it effectively by using the listing command, 'docker images', which provides a concise overview of your available images, including their sizes and tags. You can utilize Docker Compose to stitch your containers together, allowing you to define applications in a simple YAML file that outlines the template for the app configuration.
00:23:29.030
If you haven't yet installed Docker, make sure to upgrade from any outdated processes like Boot2Docker to Docker Toolbox, which includes the Docker client and Docker Machine, responsible for provisioning virtual machines. This transition provides a more comprehensive toolset and a user-friendly atmosphere if the command line is daunting to you. Docker Toolbox also requires VirtualBox for your virtual machine environments, making installation critical for your initial setup.
00:25:35.670
Now that Docker is installed, we can begin our Rails development using Docker. Throughout this demonstration, I'll aim to accomplish several goals: viewing the running application in a browser, editing local files using your IDE, executing tasks against the Rails application, and checking log output to understand what's happening beneath the surface.
00:26:30.240
Let's commence the hands-on portion with live coding! I will create a new Rails application, initialize it, and explain the necessary Dockerfile and Docker Compose setup as we go. Docker Compose facilitates our development by merging everything together seamlessly while optimizing how services work, ensuring all functions compact neatly and efficiently. I’ll demonstrate how to run commands using Docker Compose, enabling you to execute Rails tasks, like scaffolding new components without complexity.
00:29:16.890
When making adjustments to CSS styles or HTML in your local development environment, it’s straightforward to see changes reflected immediately without additional overhead from creating new images or rebuilding containers. The integration of volume mounts in Docker Compose allows you to link your local directories to the containers efficiently.
00:31:18.090
What if we want to implement external services, such as databases, with our Dockerized applications? Container linking is an approach that allows your application to communicate effectively with external services while utilizing Docker Compose’s simplified configuration. By specifying the database service in your Docker Compose file, we can ensure our Rails application seamlessly interacts with it.
00:32:08.450
You can indeed manage complex multi-container applications effortlessly with Docker by mounting volumes similarly to before. However, you will need to adjust your application's database configuration files to ensure it can access the right database service name within the Docker networking environment. With that setup, your application can connect smoothly to the linked services.
00:34:52.810
Finally, let's address the deployment of Dockerized Rails applications. In a production environment, you'll run your tests, build your images, and push them to a repository like Docker Hub or a private registry. Those images will then be retrievable by hosts running the containers. This deployment flow, although straightforward, requires careful management to ensure a seamless transition from development to production.
00:36:43.389
If anyone has questions about CI with Docker or how to run in production, feel free to approach either Kurt or myself. It's a large topic, deserving of an entire conference; however, I’ll be here to help clarify any queries you have. I encourage everyone to always keep shipping, thank you for your attention, and appreciate your time. We may have a few minutes for questions, but I don’t want to hold you from lunch!
00:39:50.680
Thank you very much.