David Heinemeier Hansson (DHH), the creator and leader of Ruby on Rails, reaffirmed his vision for the framework at Rails World last September. He described his philosophy as “from Hello World to IPO.”
Over the past two years, DHH has been ruthlessly simplifying the framework he invented more than two decades ago. Spin up a new Rails 8 application in production today, and you don’t need Node.js, Redis, or even a remote database! And yet, despite all that pruning and shearing, there are no compromises. In fact, Rails somehow packs in even more production-grade functionality than ever before.
These simplifications are impressive on their own but they were also necessary to achieve something even more remarkable: Hello World to Production in three minutes. To make this possible, DHH and his team created Kamal, a tool that allows you to deploy any Dockerized web application to a remote server via SSH in seconds, without any downtime.
If you haven’t seen the demo, it’s extraordinary. (Start at 55:45!)
Kamal is more than just software – it’s intended to change hearts and minds. It was purposefully designed to free app builders from what DHH calls “the learned helplessness” that has led to the popularity of Platform as a Service (PaaS) providers. The goal is to empower teams to confidently step into a world where they get the most powerful compute for their dollar, without paying upwards of a 100x markup for a serviceable deployment model and basic OS patching.
At 1Password, this mission hits close to home. We exist in an industry that benefits greatly when people and organizations believe it’s too complicated and dangerous to secure themselves, leading them to relinquish control and “leave it up to professionals.” This fear-driven learned helplessness directly opposes our core values.
At 1Password, we believe that everyone who uses computers is entitled to use them with dignity. When we do our job well, 1Password’s software should make you feel smarter and more capable – not infantilized. To accomplish this, we make sure our tools teach you how to be more secure. Through Checks, Watchtower, and more, we aim to share security best practices in a way that’s accessible but never condescending.
It’s these values that makes me so proud to know that 1Password is playing a meaningful part in Kamal’s story. Kamal ships with a 1Password adapter that allows you to source credentials, like your RAILS_MASTER_KEY
, from a shared vault and set them as environment variables on your remote servers. This integration can be further enhanced by using 1Password’s GitHub Actions to both access your 1Password account remotely and fetch the secrets Kamal needs.
Here’s where it gets even more exciting: 1Password can also store the SSH keys you use to connect to remote servers in your production environment. Not only can it hold the credentials, but 1Password also comes bundled with an SSH agent, so you can use 1Password to directly provide your SSH client with the credentials as you sign in. How cool is that?
If you’re a Rails developer that’s ready to put this into use right now, I’ve created a tutorial that makes best use of 1Password’s capabilities.
How to use Kamal 2 and 1Password
To demonstrate this whole flow, I’ll deploy my second-favorite Rails application at 1Password, the Feline Snooker League. This is the Rails app we use at Kolide (acquired by 1Password earlier this year) as a take-home exercise when we interview candidates for our Rails developer position.
Step 1: Get a server with Linux and set up SSH
Kamal works by directly connecting to Linux servers via SSH. So you’ll need an internet-accessible server running Linux – preferably the latest Ubuntu LTS, which is 24.04 as of this writing.
For this tutorial I’m using DigitalOcean but the setup experience will be similar for any provider. One thing I love about modern VPS providers is they make it easy to set up SSH key-based authentication. 1Password makes the remaining complication – securely encrypting and storing these SSH keys – trivial.
With the 1Password browser extension installed in Safari, I can generate and store the SSH key without leaving the webpage.
Next, install the Next, install the 1Password SSH agent. Once configured, access your server from your terminal via ssh root@example.com
. If you’ve installed the agent and stored the SSH key correctly, 1Password will pop up and ask you to unlock your vault. (In my case, as soon as I touched my TouchID sensor, I was signed into my server!)
Step 2: Add your Rails secrets to the vault
Before we discuss how to add secrets to a 1Password vault, you should prepare your Rails application so that your production credentials are separate from the credentials you’ll need for local development and testing in CI.
Rails has supported multi-environment credentials since Rails 6 but they aren’t enabled by default. To enable bespoke credentials for production, run the following command:
$ rails credentials:edit --environment production
This will generate a production-specific master.key in config/credentials/production.key
. You’ll want to immediately store this key in 1Password and delete it from your filesystem when done.
In my case, I created a new vault called “Snookums” and created a new empty password item called “Production”. From there, I created a new password field called RAILS_MASTER_KEY
and pasted the key in the password field. I also created a KAMAL_REGISTRY_PASSWORD
for my Docker Hub access token, as described in the Kamal documentation.
When everything is said and done, you should have a 1Password vault item that looks like the one below:
Step 3: Configure Kamal
In this section, you’re going to allow Kamal to programmatically access the information in your 1Password vault. The most crucial step here is installing the 1Password CLI tool. The kamal secrets
1Password adapter simply wraps the op
CLI tool to source the credentials.
Once you’ve installed the 1Password CLI, you’ll want to edit the .kamal/secrets
file. Here is what mine looks like:
SECRETS=$(kamal secrets fetch --adapter 1password --account kolide.1password.com --from Snookums/Production KAMAL_REGISTRY_PASSWORD RAILS_MASTER_KEY)
KAMAL_REGISTRY_PASSWORD=$(kamal secrets extract KAMAL_REGISTRY_PASSWORD ${SECRETS})
RAILS_MASTER_KEY=$(kamal secrets extract RAILS_MASTER_KEY ${SECRETS})
You’ll also need to edit the config/deploy.yml to add the DNS names for your server and application (for SSL certificate provisioning). My file ended up looking like this:
service: snookums
image: terracatta/snookums
servers:
web:
- feline-snooker-league.com
proxy:
ssl: true
host: feline-snooker-league.com
registry:
username: terracatta
password:
- KAMAL_REGISTRY_PASSWORD
env:
secret:
- RAILS_MASTER_KEY
clear:
SOLID_QUEUE_IN_PUMA: true
aliases:
console: app exec --interactive --reuse "bin/rails console"
shell: app exec --interactive --reuse "bash"
logs: app logs -f
dbc: app exec --interactive --reuse "bin/rails dbconsole"
volumes:
- "snookums_storage:/rails/storage"
asset_path: /rails/public/assets
builder:
arch: amd64
Remember, we don’t want to hardcode any secrets here or source them from any other place locally than the kamal secrets
command, which will run automatically when we invoke Kamal.
Step 4: Deploy!
That should do it! All you need to do now is run kamal setup
. You’ll be prompted by 1Password to unlock our vault, which will allow you to SSH to our remote servers and source the Docker Hub credentials and the production Rails Master Key.
After a couple of minutes, my deploy was finished, and when I browsed to https://feline-snooker-league.com, I was greeted with the following masterpiece.
Subsequent deployments can happen by simply running kamal deploy
right at the root of the Rails app from the terminal. Here’s a video of a full 35-second deploy in action.
Additional reading
Congratulations, you’re now using all that 1Password has to offer with Kamal to deploy Rails apps (or actually any containerized web app) to production while keeping your secrets and server credentials safe and secure. And since these things are in 1Password, you can share the vaults with the production engineers in your company with ease.
If you’re still looking for more to do, I recommend exploring 1Password’s ability to load secrets from within GitHub Actions. With this, combined with a reasonable GitHub action for running Kamal itself, you can turn your local development production deployment flow into a true continuous deployment model. Or, even enable both local and GitHub-driven deployments.
As Kamal frees software engineers from the merchants of complexity telling them that they’re in over their head, 1Password stands shoulder to shoulder in that security side of that mission—making it both accessible and empowering. Together, we’re reshaping the way developers think about both app deployment and security: reclaiming control, reducing complexity, and elevating confidence.
The future belongs to teams who refuse to compromise between simplicity and power, and with tools like Kamal and 1Password working in tandem, that future is closer than ever.
Tweet about this post