Article  |  Development

Deploying a Ruby on Rails app to DigitalOcean Using Kamal

Reading time: ~ 6 minutes

Deploying a Ruby on Rails app to DigitalOcean Using Kamal

If you’re deploying Ruby on Rails applications to the cloud, you may have explored tools to simplify and streamline the process. Recently, we’ve been experimenting with Kamal, a tool for deploying containerized applications, and we’re excited to share our experience with deploying a Rails app to DigitalOcean using their Managed Database service.

This post introduces Kamal, explains why it’s worth exploring, and walks you through a sample deployment configuration to demystify Kamal and help you decide if it’s the right tool for your next project.

What Is Kamal?

Here's how the official Kamal documentation describes it:

Kamal offers zero-downtime deploys, rolling restarts, asset bridging, remote builds, accessory service management, and everything else you need to deploy and manage your web app in production with Docker. Originally built for Rails apps, Kamal will work with any type of web app that can be containerized.”

In simpler terms, Kamal is a deployment tool designed for containerized applications. Whether you’re managing Rails apps or other containerized projects, Kamal handles complex tasks like asset management, remote builds, and service orchestration. It provides powerful features for those looking to avoid the overhead of Kubernetes while still leveraging Docker-based workflows.

The Case for Kamal: Why It’s Worth Exploring

You may have heard Kamal described as a "Capistrano-like tool for containerized apps." While that description is somewhat accurate, Kamal is much more than that. It stands out for developers who:

  • Want a simpler alternative to Capistrano.
  • Are focused on lightweight deployment workflows.
  • Appreciate a tool that integrates deeply with Rails (but also supports other frameworks).

Kamal offers several unique advantages, making it a compelling choice for deploying containerized applications.

Optimized for Rails

Kamal was initially built with Ruby on Rails in mind, offering built-in support for Rails conventions. But it’s versatile enough to work with any containerized web app, making it a great fit for diverse tech stacks.

Rails 8 Integration

Kamal is tightly integrated with Rails 8, coming pre-installed and leveraging new features like simplified containerization out of the box. This reduces setup time and ensures compatibility with the latest Rails conventions.

Streamlined Asset Management

Kamal automates asset bridging between deployment versions, ensuring static files like CSS and JavaScript are handled seamlessly without downtime. This eliminates the manual asset precompilation headaches often encountered in traditional workflows.

Easy Environment Management

With Kamal, environment variables and secrets are centralized in .kamal/secrets, simplifying managing production settings across servers. This reduces configuration drift and enhances security by keeping sensitive data out of version control.

A Modern Alternative to Capistrano

Kamal modernizes deployment by replacing Capistrano’s script-based approach with a Docker-centric workflow, offering better scalability and consistency. It’s easier to set up for containerized apps while retaining the simplicity Capistrano users love.

Flexible Support for Managed Databases

Kamal integrates effortlessly with managed database services like DigitalOcean’s, allowing you to configure database connections via environment variables without managing database containers. This flexibility simplifies infrastructure while leveraging cloud provider reliability.

Ideal for Small Teams or Solo Devs

Kamal’s lightweight design and minimal setup make it perfect for small teams or solo developers who need efficient deployments without the complexity of Kubernetes. It balances power and simplicity, reducing the learning curve for resource-constrained projects.

Developer-Friendly Debugging Tools

Kamal provides commands that give developers quick access to runtime diagnostics and interactive troubleshooting. These tools streamline issue resolution without requiring external monitoring setups.

Active Community and Documentation

Kamal benefits from a growing community on GitHub and comprehensive official documentation, offering quick support and detailed guides for both beginners and advanced users. This ecosystem ensures you’re never stuck when exploring its features.

Why We Chose a Managed Database Instead of a Database Container

Choosing a managed database service was a deliberate decision that has made our deployment process much simpler and more efficient. With DigitalOcean’s managed database service, many of the operational headaches of managing a database—like backups, scaling, and connection management—are handled automatically. This not only saves time but also ensures that the service provider professionally manages critical tasks like disaster recovery and high availability.

Managed databases also remove the need to configure and maintain database containers, which can be tricky to set up correctly, especially for production environments. Instead of worrying about things like replication, version upgrades, and performance tuning, you can focus entirely on building and improving your application. This approach is a game-changer for small-to-medium apps, where development resources might be limited. It allows developers to deploy confidently, knowing that the database infrastructure is reliable, scalable, and secure.

In our case, DigitalOcean’s managed database service was particularly appealing because of its seamless integration with other DigitalOcean products, intuitive user interface, and competitive pricing. Setting up the database was straightforward, and connecting it to the Rails app required only minor adjustments to configuration files. This simplicity made it easy to get the app up and running quickly, without spending hours on infrastructure setup.

If you're deploying small or medium-sized apps or new to cloud deployments, managed databases are worth considering. They offer a balance of simplicity and robustness that’s hard to achieve with self-managed solutions.

Getting Started with Kamal - Tips, Tools, and Insider Know-How

Kamal is designed to make deployments simple and efficient, but setting up a new tool can always feel a little daunting. Here’s how to get started with Kamal and some helpful tips to make the process smoother.

Prepare Your Environment

Before diving in, ensure you have the following tools and concepts ready:

  • Docker Installed and Configured: Kamal relies on Docker to build and run containers, so install Docker and familiarize yourself with basics like creating a Dockerfile and running containers. Test it locally with docker run hello-world to confirm it’s working.
  • SSH Access to Your Server: Kamal uses SSHKit to communicate with your server, so set up SSH keys and verify access with ssh user@your-server-ip. Passwordless login via keys is recommended for automation.
  • A Cloud Service Provider: Decide where you’ll host your app. Kamal works seamlessly with AWS, Google Cloud Platform, DigitalOcean, and more.
  • A Deployed App or Sample Rails App: To experiment with Kamal, it helps to have a simple Rails app ready to deploy.

Install Kamal

If you’re using Ruby on Rails 8, Kamal comes pre-installed in your app. For older versions or other frameworks:

  1. Add Kamal to your Gemfile:
    gem 'kamal'
  2. Run bundle install to install the gem.
  3. Initialize Kamal with:
    kamal init

This generates config/deploy.yml (your deployment blueprint) and .kamal/secrets (for sensitive data). Add .kamal/ to .gitignore to keep secrets out of version control.

Configure Your deploy.yml File

The deploy.yml file defines how Kamal deploys your app. Here’s a starter example for a Rails app on DigitalOcean with a managed database:

service: my-app
image: username/my-app:1.0.0
servers:
  web:
    - 192.168.1.100  # Replace with your server IP
env:
  secret:
    - RAILS_MASTER_KEY
    - PRODUCTION_DB_HOST
registry:
  username: username
  password:
    - KAMAL_REGISTRY_PASSWORD   

To connect your Rails app to a managed database like DigitalOcean’s, grab the host, username, and password from your provider’s dashboard, store them in .kamal/secrets, and reference them in deploy.yml under env.secret.

Pro Tips:

  • Service Name: Match it to your app’s repository name (e.g., my-app) for consistency.
  • Image Tagging: Use specific versions (e.g., 1.0.0) instead of the latest for easier rollbacks.
  • Secrets: Store sensitive values like RAILS_MASTER_KEY and PRODUCTION_DB_HOST in .kamal/secrets, not the YAML file.
  • Roles: Add workers: under servers if using background jobs (e.g., Sidekiq).

Understand the Deployment Workflow

Kamal uses a simple yet powerful workflow for deployments:

  1. Build the Docker Image: Kamal builds your app’s image locally or remotely (configurable in deploy.yml).
  2. Push to a Registry: Upload the image to DockerHub or another registry specified in the registry section.
  3. Deploy: Run: kamal deploy

This pulls the image to your server, starts containers, and performs a rolling restart for zero downtime. If using accessories (e.g., Redis), they’re deployed automatically—no separate accessories flag is needed unless isolating specific updates.

Master Kamal’s Debugging Tools

Kamal includes several built-in commands to simplify debugging:

Logs: View real-time output with:

kamal logs -f

Rails Console: Debug interactively on the server:

kamal app exec --interactive "bin/rails console"

Shell Access: Inspect the container directly:

kamal app exec --interactive bash

Work with Accessories

For services like Redis or Sidekiq, define them as accessories in deploy.yml:

accessories:
  redis:
    image: redis:latest
    host: 192.168.1.100
    port: 6379

Deploy with Kamal deploy, and Kamal manages them alongside your app. Add volumes or environment variables as needed for persistence or configuration.

Example Configuration for Deploying with Kamal

Here’s the deploy.yml for a Rails app on DigitalOcean with their managed database:

service: my-rails-app
image: myusername/my-rails-app:1.0.0
servers:
  web:
    - your-droplet-ip  # From DigitalOcean dashboard
env:
  secret:
    - RAILS_MASTER_KEY
    - PRODUCTION_DB_HOST
registry:
  username: myusername
  password:
    - KAMAL_REGISTRY_PASSWORD
accessories:
  redis:
    image: redis:latest
    host: your-droplet-ip
    port: 6379

Kamal's Community and Documentation

Using a new tool can be much easier with a strong community and resources at your fingertips. Kamal offers both, making learning, troubleshooting, and exploring advanced features simple. Whether you are looking for quick answers, detailed guidance, or inspiration from other developers, tapping into Kamal’s community and documentation will accelerate your journey to mastering this powerful deployment tool.

Ready to give Kamal a try?

Explore its features, or experiment with a simple app to see how it fits your workflow. Whether managing small apps or planning larger deployments, tools like Kamal and managed databases can save you time and effort. Take the first step by trying it out on your next project—you might just discover your new favorite deployment tool!

Have a project that needs help?