Deploying with Kamal

Choose Kamal (kamal: true) and the tool writes config/deploy.yml and .kamal/secrets for your stack. The generated Dockerfile comes from dockerfile-rails. Only the values it cannot know are left as CHANGE_ME_*.

Table of contents
  1. What you fill in
  2. What is already done for you
  3. First deploy
  4. Staging
  5. Redis in production

What you fill in

Placeholder Meaning
CHANGE_ME_registry_username Your container registry user (appears twice: image and registry)
CHANGE_ME_server_ip The server to deploy to (also for the job role and Redis accessory with Sidekiq)
CHANGE_ME.example.com The host Kamal’s proxy should serve, with automatic SSL

bin/kamal config parses and validates the file without touching a server. The placeholders are valid strings, so it passes before you edit them.

What is already done for you

Secrets. RAILS_MASTER_KEY is passed to the container, read from config/master.key. For PostgreSQL and MySQL, DATABASE_URL is a secret read from your environment. KAMAL_REGISTRY_PASSWORD is read from your environment. .kamal/secrets is safe to commit: it contains no values, only references.

export KAMAL_REGISTRY_PASSWORD=...          # a registry access token
export DATABASE_URL=postgres://...          # PostgreSQL or MySQL only

Persistent data. Without a volume, every deploy starts from an empty database.

Database Volumes
SQLite <app>_data:/data (the database) and <app>_storage:/rails/storage (uploads)
PostgreSQL, MySQL <app>_storage:/rails/storage

Background jobs.

Stack Setup
Solid SOLID_QUEUE_IN_PUMA: true, so jobs run inside the web process on a single server
Redis + Sidekiq A job role running bundle exec sidekiq, a Redis accessory (redis:7 with persistence), and REDIS_URL pointing at it

Assets. asset_path: /rails/public/assets keeps old fingerprinted assets available to in-flight requests during a deploy.

Aliases. bin/kamal console, shell, logs and dbc.

First deploy

bin/kamal setup      # first time: installs Docker on the server, boots accessories, deploys
bin/kamal deploy     # later deploys

See the Kamal documentation for registries, multiple servers, and destinations.

Staging

Choosing a staging environment adds a Rails staging environment, but not a separate Kamal destination. To deploy staging, create config/deploy.staging.yml and .kamal/secrets.staging (see Kamal’s destinations), and set RAILS_ENV for it.

Staging uses the :test mail delivery method, so it cannot send email through your production Postmark account. To test real delivery, create a separate Postmark server for staging and follow the comment in config/environments/staging.rb.

Redis in production

With Redis + Sidekiq the app refuses to boot in production without REDIS_URL; the generated deploy.yml sets it for you. The Docker build runs assets:precompile with SECRET_KEY_BASE_DUMMY set, which is exempt, so image builds do not need Redis.


Back to top

Released under the MIT License.