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.