4 min read

Kamal 2 features that I’m excited about

I’m at Rails World which kicked off with @dhh talking about the improvements to Rails from 7 to 8 which is launching at Rails World, #nobuild, #nopaas. @djmb then got on the stage to delight us with all of the goodies that are shipping shipped with Kamal 2.

Here’s a few of the things I’m excited about with Kamal 2, this isn’t meant to be an exhaustive list but just a highlight reel. Here’s the compare link if you’re interested in digging into the full list of changes.

Aliases

Kamal 2 adds support for custom aliases which is just what it sounds like.

For example, if you want to run a rails console you’re most likely always remembering to add a few options to drop into a production console. Maybe you want to make sure you always target a specific host(a larger worker box that has more headroom than one of your production web servers). Or maybe you have a smaller machine and you want to ensure you always reuse(-i) an existing running container so you don’t chew up RAM you don’t have. I’ve been adding bin/kamal commands to accomplish this but Kamal 2 introduces a simple way to configure these in your deploy recipes now.

Instead of typing:

kamal app exec -i --reuse "bin/rails console"

You can now just create an alias for it:

aliases:
  console: app exec -r worker -i --reuse "bin/rails console" 

And then use it with:

kamal console

More details in the PR

Builder config has been simplified

There’s now a top-level arch option for the builder config and then you just set a remote SSH endpoint if you want to use a remote builder. If you don’t set a remote builder then it’s going to build locally and with the arch(s) that you list out.

This is more of a setup/config improvement, the supported functionality is nearly identical outside of also being able to specify a driver if you need.

More details in the PR

Let's talk about your secrets

.env has been ditched in favor of .kamal/secrets and so much more. Using .env was causing various issues and confusion because .env is used by quite a few tools and environments.

Kamal 2 now just loads secrets from .kamal/secrets. You can also interpolate values within .kamal/secrets if you’d like or just use your existing .env as-is with mkdir .kamal && mv .env .kamal/secrets. If you utilize destinations then that secrets file should now live in .kamal/secrets.production instead of .env.production as an example.

You also don’t need to remember to kamal env push or kamal envify, they’re interpolated and pushed at runtime. This also means they need to be up to date at all times. Clear and secret vars are pushed and then still booted with the docker run command via the --env-file.

  INFO Uploading .kamal/apps/hey-production/env/roles/web.env 100.0%
  INFO docker run [other-stuff] --env-file .kamal/apps/hey-production/env/roles/web.env

A new subcommand kamal secrets was also added which is basically a helper method to pull secrets from your favorite password managers.

AND there’s also a common secrets file that was added. So you can store your common secrets like your KAMAL_REGISTRY_PASSWORD across all environments by putting that in .kamal/secrets-common

More details in PR

traefik was replaced with kamal-proxy

Deploys are faster and the deploy process is a bit more straightforward because of this work, it’s a great improvement.

A few high-level big wins:

  • SSL certs out of the box withssl: true
  • Your app, proxy, and accessories all boot in the same Kamal network now. So you can utilize named host references. Have an accessory named db? You can now connect to it via db so mysql2://hey-db..., swapping hey with your service name
  • Multi-application hosting on the same server, routing is host-based so you just need to set a host for each web service
  • Cord file functionality has been removed which is what makes your deploys faster, if you don’t know or care what this is, you don’t need to, just know your deploys will roll over faster

One gotcha is the default listening port for your container changed from 3000 to 80 which makes a bit more sense but is not as obvious at first. To override the port just set app_port within your proxy config to whatever you’d like.

Also, there’s an upgrade process that you’ll need to read and look through before making this upgrade.

kamal-proxy is it’s own standalone project extracted from Basecamp/37Signals and there’s also some exciting stuff it introduces. Maintenance pages, pausing traffic(a quick restart of a service), and controlled rollouts(send 10% of traffic to the new version). Those features haven’t been bubbled up to Kamal yet but you can utilize server exec(PR) to run whatever you need.

More details in PR

Docs

The doc site has also been updated and there's now a version selector at the top. If you notice something off or missing from 2, you should open an issue/PR on the kamal-site repo.

Upgrading

There's also a great upgrade guide for Kamal 2, start here when you're ready to make the upgrade.

Kamal 2: Upgrade Guide
Deploy web apps anywhere