Rails 8 adds Kamal by default.

What is Kamal?

Kamal is a deployment tool developed by 37signals, designed to simplify the deployment of web applications by using Docker containers and the Traefik reverse proxy for seamless, zero-downtime deployments.

Before

Before Rails 8, we had to manually install Kamal into our project and then do the setup.

Installation:

gem install kamal

Or add it to the Gemfile of the project.

# Gemfile
gem 'kamal', require: false

and then run

bundle install

Initialize Kamal

kamal init

This creates a default configuration file at config/deploy.yml and a .env file.

After

Rails 8 now adds Kamal by default.

While creating a new rails app with rails new <app_name>, an entry for kamal gem will be added in the Gemfile and two additional files will be created with default configuration.

# Gemfile
gem "kamal", require: false
.env.erb
config/deploy.yml

Default Configuration

Here are the contents of the

config/deploy.yml template:

# Name of your application. Used to uniquely configure containers.
service: <%= app_name %>

# Name of the container image.
image: your-user/<%= app_name %>

# Deploy to these servers.
servers:
  web:
    - 192.168.0.1
  # job:
  #   hosts:
  #     - 192.168.0.1
  #   cmd: bin/solid_queue work

# Credentials for your image host.
registry:
  # Specify the registry server, if you're not using Docker Hub
  # server: registry.digitalocean.com / ghcr.io / ...
  username: your-user

  # Always use an access token rather than real password when possible.
  password:
    - KAMAL_REGISTRY_PASSWORD

# Inject ENV variables into containers (secrets come from .env).
# Remember to run `kamal env push` after making changes!
env:
  secret:
    - RAILS_MASTER_KEY
  # clear:
  #   DB_HOST: 192.168.0.2

# Use a persistent storage volume for sqlite database files and local Active Storage files.
# Recommended to change this to a mounted volume path that is backed up off server.
volumes:
  - "<%= app_name %>_storage:/rails/storage"

# Bridge fingerprinted assets, like JS and CSS, between versions to avoid
# hitting 404 on in-flight requests. Combines all files from new and old
# version inside the asset_path.
asset_path: /rails/public/assets

# Use a different ssh user than root
# ssh:
#   user: app

# Configure builder setup (defaults to multi-arch images).
# builder:
#   # Build same-arch image locally (use for x86->x86)
#   multiarch: false
#
#   # Build diff-arch image via remote server
#   remote:
#     arch: amd64
#     host: ssh://app@192.168.0.1
#
#   args:
#     RUBY_VERSION: <%= ENV["RBENV_VERSION"] || ENV["rvm_ruby_string"] || "#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}" %>
#   secrets:
#     - GITHUB_TOKEN
#     - RAILS_MASTER_KEY

# Use accessory services (secrets come from .env).
# accessories:
#   db:
#     image: mysql:8.0
#     host: 192.168.0.2
#     port: 3306
#     env:
#       clear:
#         MYSQL_ROOT_HOST: '%'
#       secret:
#         - MYSQL_ROOT_PASSWORD
#     files:
#       - config/mysql/production.cnf:/etc/mysql/my.cnf
#       - db/production.sql:/docker-entrypoint-initdb.d/setup.sql
#     directories:
#       - data:/var/lib/mysql
#   redis:
#     image: redis:7.0
#     host: 192.168.0.2
#     port: 6379
#     directories:
#       - data:/data

Contents of .env.erb template

<%%# This env template should lookup values from a password store or from ENV -%>
# Generated by kamal envify from .env.erb
KAMAL_REGISTRY_PASSWORD=<%%= ENV["KAMAL_REGISTRY_PASSWORD"] %>
RAILS_MASTER_KEY=<%%= File.read("config/master.key") %>
# GITHUB_TOKEN=<%%#= `gh config get -h github.com oauth_token`.strip %>

How to skip Kamal while creating a new Rails app?

If we don’t want to use kamal in our rails application, we can always skip it by passing --skip-kamal flag while creating the app.

rails new <app_name> --skip-kamal

Documentation & References

Visit the official Kamal website for documentation and more information.

Need help on your Ruby on Rails or React project?

Join Our Newsletter