Docker

Summarized using AI

Kamal 2.0: Deploy Web Apps Anywhere

Donal McBreen • September 26, 2024 • Toronto, Canada

The video titled "Kamal 2.0: Deploy Web Apps Anywhere" features Donal McBreen from 37signals discussing the new version of Kamal, an imperative deployment tool designed to simplify web app deployment using Docker. The talk, presented at Rails World 2024, highlights the evolution from Kamal 1 to Kamal 2, along with the key features and improvements made to the tool.

Key points discussed in the video include:

- Background of Kamal: Donal explains the need for a deployment tool after migrating applications from AWS EKS to their own hardware, indicating that while Kubernetes was complex and not necessary, Docker provided the desired ease of managing deployments.

- Features of Kamal:

- Zero Downtime: Kamal ensures that applications are deployed without downtime, overcoming the issues associated with temporarily serving error pages during updates.

- Imperative Commands: Kamal employs an imperative approach, which means users run a command and receive confirmation once the action is complete, simplifying the deployment process.

- Speed and Efficiency: Emphasis is placed on minimizing deployment time by efficiently building and pushing Docker images without unnecessary overhead.

- Setup Requirements: To implement Kamal, users need a Dockerfile for their application, a Docker registry, and servers with SSH access. Donal provides steps for integrating Kamal into an app setup.

- Deployment Process: Kamal streamlines the deployment process by automating the necessary commands, checking for Docker installation, building and pushing images, and configuring a proxy to facilitate smooth transitions between application versions.

- Asset Bridging: An innovative feature that prevents 404 errors during deployment by ensuring assets from both old and new application versions are accessible, thus maintaining continuity for users.

- Proxy Changes: Kamal 2 replaces the previous proxy, Traefik, with a custom-built proxy to address issues related to configuration complexity and traffic direction, improving the robustness and simplicity of the deployment process.

- New Functionalities: The update introduces commands such as kamal exec to easily access a Rails console, along with the ability to set up aliases for customized command execution.

In conclusion, Kamal 2 aims to simplify web application deployment, reduce setup complexity, and enhance performance. The release of Kamal 2 is imminent, with further documentation updates promised to accompany the rollout, encouraging user feedback for continuous improvement.

Overall, this talk provides valuable insights into deploying applications more efficiently with the Kamal tool, paving the way for more accessible web app management for developers.

Kamal 2.0: Deploy Web Apps Anywhere
Donal McBreen • September 26, 2024 • Toronto, Canada

Kamal is an imperative deployment tool from 37signals for running your apps with Docker. Donal McBreen, from the Security, Infrastructure and Performance team at 37signals will run through how it works, what they've learned from v1.0 and the changes they've made for v2.0 at his talk at #RailsWorld.

#Kamal2 #rails #rubyonrails #deployment #Rails8

Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/

Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/

Rails World 2024

00:00:10.400 Um, yes, so let's go back one.
00:00:14.240 That's me, Donal McBreen. I'm a programmer.
00:00:16.279 I work at 37signals, and today, I'm going to discuss Kamal 2, which is the tool we're currently using to deploy.
00:00:20.560 So, I'm going to talk a little bit about Kamal in general, how it works,
00:00:22.720 and then more specifically about what we've added for Kamal 2.
00:00:25.000 We sort of have a history already, so we'll go through this. I won't take too long.
00:00:29.119 At the start, we were running a bunch of applications in AWS on their managed Kubernetes service, EKS, and we wanted to bring them in-house to run on our own hardware.
00:00:36.680 So, we needed a way to run them. One option would have been to start using Kubernetes locally, but we didn't really fancy that.
00:00:41.520 It looked quite tricky, and we were already using Basecamp, our biggest application, which had always run on our own hardware.
00:00:45.840 We were just using Capistrano to deploy it, and when we looked at what we were doing in AWS, we decided that we didn't really like this Kubernetes part.
00:00:50.559 Kubernetes looked a bit tricky, and we didn't really need it, but the Docker part looked great because we wouldn't need to artisanally manage our servers anymore, ensuring we could compile the latest Ruby and make sure all the gems installed correctly.
00:01:03.120 So, we decided we needed Capistrano for containers. If you don't know what Capistrano is, back in the days before it,
00:01:07.720 you would deploy your applications by running some script you had made up or by SSHing into a server and just typing some random commands, hoping that it worked.
00:01:19.680 Capistrano, which was originally built by Jamus Buck, who is actually talking right now in the other room, was a way to make this simpler.
00:01:29.680 The idea was that you would SSH, and Capistrano would SSH to your servers for you and have a bunch of recipes that it would run to deploy your app, allowing for repeatable builds.
00:01:43.159 That was what we decided we needed.
00:01:45.799 Kamal is kind of a modern take on Capistrano but decided to run with Docker. It's a Ruby gem built on top of SSHKit.
00:01:58.960 SSHKit is a library extracted from Capistrano that helps you run commands over SSH concurrently and wait for them all to return.
00:02:02.399 The idea is that you've got some Linux servers running Docker or about to run Docker that you want to deploy to.
00:02:12.240 These were the three big goals we had. First, it would be zero downtime. If you do a very naive version of just running Docker,
00:02:15.360 your application will boot up, sitting there on port 80, and then you've got a new version of the application, and what you need to do is take the first one down and bring the other one up.
00:02:30.240 There is a big gap during that time where you're serving error pages, which we wanted to avoid.
00:02:35.000 The second aspect was that it would be an imperative tool.
00:02:41.760 What this means is that we're going to run a command and then wait, and when the command is finished, we're done. There's nothing else going on.
00:02:57.520 Kubernetes is more declarative, and the distinction here is imperative means 'I insist,' while declarative means 'I suggest.'
00:03:08.000 With this, we're saying 'I insist you deploy,' and you tell me whether you've deployed or not.
00:03:12.240 Finally, if we're going to wait for a while to complete, we need to be as fast as possible, so we're going to be deploying Docker images.
00:03:29.439 You have to build them and move them around.
00:03:31.440 If that takes a long time, the process will take a long time, and we wanted Kamal to be as fast as possible and avoid adding any extra overhead, if possible.
00:03:35.000 So, let's move on to the prerequisites.
00:03:38.760 To run Kamal on your app, you'll need an app with a Dockerfile so you can build your Docker image.
00:03:46.480 It doesn't have to be Rails; it can be any kind of web app packaged up as a Docker image.
00:04:00.000 As David mentioned earlier, you do need a Docker registry right now. We have some ideas on how to get rid of this part, as it's quite annoying, but for now, it is necessary.
00:04:06.360 Finally, you need a bunch of servers that you have SSH access to.
00:04:09.480 If you want to install it with Rails 8, it will come installed already unless you add the skip command option.
00:04:14.080 If you want to try it out on an existing application, you can install the gem or include it in your bundle.
00:04:27.200 Then, run `kamal setup`, which will create files. The main file you need here is `config/deployed.yml`.
00:04:35.080 You'll need to specify the servers you are deploying to, details regarding your registry, and which architecture you want to build for.
00:04:47.440 Here's our simple infrastructure: you have a host from which you are deploying—this could be your laptop or a specific server.
00:04:56.000 You also have a host to which you want to deploy. You will talk over SSH, and it can do all the work to deploy in parallel if that's the case.
00:05:05.640 However, you will need your own load balancer somewhere to balance things out over those hosts, and we will just demonstrate using one host here.
00:05:21.040 We have our deployment host, application host, and Docker registry for now.
00:05:26.440 When you run `kamal setup`, you'll see the standard SSHKit output.
00:05:36.120 This is handy because you can inspect it after a deployment to see exactly what Kamal did. This heritage from Capistrano is very useful.
00:05:49.120 The first thing Kamal will do is check on the application host to see if Docker is installed. If it isn't, it will try to install it.
00:05:53.679 If it cannot be installed, you'll need to resolve that issue manually.
00:05:57.280 Otherwise, Kamal will get Docker installed, perform a Docker build on your deployment host, and push it.
00:06:02.480 Then, Kamal will SSH to your application host and perform a Docker pull, ensuring our container is present.
00:06:11.040 Next is the deployment phase. We'll focus on the application host for that.
00:06:18.400 We will start with commands coming in over SSH from our deployment host. Docker should be installed, and we have copied our image over.
00:06:30.160 The first thing we do is boot up a proxy, specifically the instance of Kamal Proxy, which is the new proxy we've built.
00:06:36.240 My colleague Kevin is giving a talk on that after this, so if you're interested in learning more, come along to that talk.
00:06:48.960 Once we boot up the application container, we tell the proxy to send traffic through to it, and now we are done, with service requests being directed to our application.
00:07:01.040 The next phase involves deploying a second version of your applications, where you've made your changes and committed them. You'll then run `kamal deploy`.
00:07:10.240 'Kamal setup' is the initial setup, and the deployment is the next phase. Initially, it will build the image, push it, and pull it onto the application host.
00:07:22.240 Now, this is where we left things off after our last deployment.
00:07:26.480 We will boot up a container running the second version of the application and then instruct Kamal Proxy to send traffic over there.
00:07:35.800 And we're done. This is a simple overview of how it works.
00:07:41.399 There are additional features for job servers where you don’t need a proxy, and you can configure those separately.
00:07:57.679 One interesting aspect to discuss is what we call asset bridging.
00:08:10.880 With the naive version of deployment, if you are running multiple application hosts and they deploy at different rates, you can encounter issues.
00:08:25.199 You may have new containers with updated assets and old containers still serving from older assets, which can lead to 404 errors and unstyled pages, making the deployment visible to users.
00:08:35.000 This is not desirable; we want zero downtime and to make the deployment as invisible as possible.
00:08:49.040 This is a common problem, and many rails apps take steps beforehand, like copying assets to an S3 bucket.
00:09:03.200 However, with Kamal, we want to ensure you don't have to worry about this.
00:09:14.720 For example, when you create a new Rails application, you'll find a line in the config that sets the asset path to Rails public assets.
00:09:23.520 Kamal will look for the assets and, during the build process, will boot up the application image but will change the entry point just to sleep, allowing it to remain idle.
00:09:35.880 Afterward, it will copy those assets into a specific folder on the application host, outside of Docker.
00:09:44.760 Then, when you deploy again, you’ll have the assets from the last deployment and the new ones you just collected.
00:09:55.840 By combining the old and new assets, you ensure that you won't face 404 errors; the application will have access to both sets of assets.
00:10:04.560 This fixes the issue where your old containers might still be serving to users.
00:10:13.280 You can map those assets back to public assets when you boot the new version of the application, ensuring a seamless transition.
00:10:22.520 When you boot up the new version of your application, the public assets will contain both the old and new assets.
00:10:34.080 This means you won't have to worry about which container the requests hit, thanks to this asset bridging feature.
00:10:45.440 The result is clear: you avoid 404 errors during deployments, and you don't need to rely on a CDN or create special asset hosts.
00:10:56.640 And yeah, that is asset bridging.
00:11:05.760 Now, just to confirm, it is releasing today, but it has not been released as of yet.
00:11:12.560 I decided it would be better to present this talk before the actual release to ensure everything is prepared and ready for it.
00:11:24.720 This means the documentation is not up to date yet; however, it will be updated later today.
00:11:38.560 So, what's new? One of the biggest changes is that we are switching the proxy we use.
00:11:45.840 In Kamal 1, we used Traefik as this proxy to switch between containers.
00:11:53.440 Traefik is an open-source application proxy designed to configure itself automatically and dynamically.
00:12:01.720 We would utilize it by booting our container and noticing the labels we set, allowing it to direct traffic based on those labels.
00:12:14.400 However, this created issues. The main problem was a mismatch between the declarative and imperative approaches.
00:12:22.800 With Kamal, we are insisting on specific commands, but Traefik works by taking suggestions.
00:12:31.920 You would need to boot the container with labels and wait for Traefik to notice them, which led to discrepancies.
00:12:46.560 This made draining requests very difficult because container labels are immutable.
00:12:52.800 You could tell Traefik to send traffic to a container, but you couldn't stop it from doing so.
00:13:05.600 This resulted in situations where we had to use hacks to manipulate the health check so Traefik would stop sending traffic.
00:13:16.320 It wasn't great, and we often faced difficulties understanding errors because Traefik was a general-purpose proxy with its complex language.
00:13:28.880 As a result, we decided to build our own proxy tailored for Kamal, which is zero-configuration and very straightforward.
00:13:41.840 With the new proxy, we can run multiple applications without boot time configuration, keeping it simple.
00:13:53.440 The command structure in Kamal is straightforward, where deploying is just a matter of sending a command that follows a one-to-one mapping.
00:14:07.080 When you type `kamal deploy`, it goes to the proxy, which confirms the action—we say we’ve deployed, and the entire process is smooth.
00:14:18.080 Everything is streamlined and quick because you are not polling and waiting for responses.
00:14:30.160 One of our goals is to simplify deployment, especially for users who may struggle with setup.
00:14:40.840 We added a command that can open a Rails console easily. `app exec` is a Kamal command that either boots a new container or execs into an existing one.
00:14:53.040 You can pass in `rails console`, which provides ready access to a running Rails console in production.
00:15:05.080 However, if users have specific requirements, they may want to run the console on a certain host. Aliases allow for this, letting you specify commands on an app level.
00:15:15.360 So, after setting up those aliases, running `kamal console` would launch the console directly.
00:15:24.680 In conclusion, we built Kamal 1 with a specific use case in mind, but Kamal 2 aims to streamline the process further.
00:15:35.040 Now, with Kamal 2, you're just typing `rails new`, and if you've got your domain and a $6 digital ocean droplet, you can get running on HTTPS as quickly as possible.
00:15:41.440 We appreciate your interest and engagement with Kamal and look forward to your feedback on these new functionalities.
00:15:54.920 As a final note, the Kamal 2 release will happen later today, and additional updates will be provided in the documentation at that time.
00:16:03.440 Feel free to ask any questions or provide insights about these changes. Thank you for your attention.
00:16:15.520 We hope you enjoy using Kamal!
Explore all talks recorded at Rails World 2024
+17