Logo

Guide to Deploying Rails Applications with Kamal 2

avatar jayce 22 Nov 2024

Guide to Deploying Rails Applications with Kamal 2

Introduction

Kamal 2 is a tool for deploying Rails applications, but the related documentation is currently scattered and incomplete. This article will share my practical experience in deploying with Kamal 2, hoping to provide some reference for everyone.

Complete Configuration Example

# config/deploy.staging.yml

# Puma service name
service: ai-hub-server-staging
# Namespace / Image name
image: jayce9210/ai-hub-server-staging

servers:
  web:
    hosts:
      - your-host
  sidekiq:
    cmd: bundle exec sidekiq
    hosts:
      - your-host

proxy:
  ssl: true
  host: ai-hub-kamal.beansmile-dev.com
  # kamal-proxy connects to your container over port 80, use `app_port` to specify a different port.
  app_port: 3000

registry:
  # Your Docker Hub username and password
  # Using Alibaba Cloud service
  server: crpi-9ja5ymdca5joh9vj.cn-shenzhen.personal.cr.aliyuncs.com
  username: 396803555@qq.com
  password:
    - AI_HUB_KAMAL_REGISTRY_PASSWORD

builder:
  arch: amd64
  # Specify Dockerfile path
  dockerfile: Dockerfile.staging

# Logging configuration
logging:
  options:
    max-size: 100m

env:
  clear:
    HOST: http://ai-hub-kamal.beansmile-dev.com
    DB_HOST: ai-hub-server-staging-db
    REDIS_HOST: redis://ai-hub-server-staging-redis:6379/0
  secret:
    - RAILS_MASTER_KEY
    # Must be declared here, otherwise database.yml cannot get it
    # connection to server at "172.17.1.2", port 5432 failed: fe_sendauth: no password supplied
    - AI_HUB_KAMAL_POSTGRES_PASSWORD

accessories:
  db:
    image: postgres:15
    host: your-host # Your server IP
    env:
      clear:
        POSTGRES_USER: deploy
        POSTGRES_DB: ai-hub-server-staging
        POSTGRES_PASSWORD: AI_HUB_KAMAL_POSTGRES_PASSWORD
    volumes:
      - /var/lib/postgresql/data:/var/lib/postgresql/data
  redis:
    image: redis:7
    host: your-host # Your server IP

aliases:
  console: app exec --reuse -i "bin/rails console"

Database Configuration Example:

# database.yml.example
staging:
  <<: *default
  database: ai_hub_server_staging
  username: deploy
  password: <%= ENV['AI_HUB_KAMAL_POSTGRES_PASSWORD'] %>

Docker Network Explanation

Kamal 2 will create a Docker network named kamal and add all containers to it. Therefore:

  • Do not use IP or localhost
  • Redis address should be redis://ai-hub-server-staging-redis:6379/0
  • Database address should be ai-hub-server-staging-db

For example, if the project uses redis, enter docker ps on the server to find the name ai-hub-server-staging-redis, then the REDIS_HOST should be redis://ai-hub-server-staging-redis:6379/0.

env:
  clear:
    HOST: http://ai-hub-kamal.beansmile-dev.com
    DB_HOST: ai-hub-server-staging-db
    REDIS_HOST: redis://ai-hub-server-staging-redis:6379/0

Deployment Steps

1. Initialize Kamal

kamal init

2. Configure deploy.yml and Dockerfile

3. Run the setup command

kamal setup -c "config/deploy.staging.yml"

If there are accessories such as pg, redis, etc., the containers will start at this time, and you can see the container names.

4. Adjust Redis Configuration

env:
  clear:
    HOST: http://ai-hub-kamal.beansmile-dev.com
    DB_HOST: ai-hub-server-staging-db
    REDIS_HOST: redis://ai-hub-server-staging-redis:6379/0

5. Deploy the Application

kamal deploy -c "config/deploy.staging.yml"

Note that each deployment uses the last committed code locally. So remember to commit after making changes.

Common Issues and Solutions

1. Slow Access to Docker Hub

Solution:

  • Use Alibaba Cloud image service
  • Or configure a proxy in Docker Daemon:

Even with Alibaba Cloud images, the deployment still cannot pull the kamal-proxy image. Solve it by using a proxy.

# /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:10801"
Environment="HTTPS_PROXY=http://127.0.0.1:10801"

2. .kamal/secrets Environment Variable Issue

Need to configure in system environment variables:

# bash.rc / zshrc

export AI_HUB_KAMAL_REGISTRY_PASSWORD=
export AI_HUB_KAMAL_POSTGRES_PASSWORD=
# .kamal/secrets
AI_HUB_KAMAL_REGISTRY_PASSWORD=$AI_HUB_KAMAL_REGISTRY_PASSWORD
AI_HUB_KAMAL_POSTGRES_PASSWORD=$AI_HUB_KAMAL_POSTGRES_PASSWORD

3. Rails Logs Cannot Output to Docker

Add in config/environments/staging.rb:

config.logger = ActiveSupport::Logger.new(STDOUT)
  .tap  { |logger| logger.formatter = ::Logger::Formatter.new }
  .then { |logger| ActiveSupport::TaggedLogging.new(logger) }

Confirm docker log format:

> docker inspect --format='{{.HostConfig.LogConfig.Type}}' 9b0b24c16554
json-file

Kamal related configuration items

logging:
	# Default is this
  driver: json-file
  options:
    max-size: 100m

4. SSL Configuration

Kamal-proxy supports automatic HTTPS configuration through Let’s Encrypt:

proxy:
  ssl: true
  host: ai-hub-kamal.beansmile-dev.com
  # kamal-proxy connects to your container over port 80, use `app_port` to specify a different port.
  app_port: 3000

Common Commands

Enter the Container to View Details

docker exec -it CONTAINER_ID bash

Release Deployment Lock

kamal lock release
# Or
kamal lock release -c "config/deploy.staging.yml"

Rails Console

# deploy.staging.yml
# Configure alias
aliases:
  console: app exec --reuse -i "bin/rails console"

# Command line usage
kamal console -c "config/deploy.staging.yml"

View Remote Logs

kamal app logs  -c "config/deploy.staging.yml"

Practical Configuration Parameters

Rails Server Port Mapping

servers:
  web:
    hosts:
      - your-host
    options:
      publish:
        - "4022:3000"

Disable Kamal Proxy

servers:
  web:
    hosts:
      - your-host
    proxy: false

Summary

Kamal 2 is a Docker-based Rails application deployment tool. Compared to traditional Capistrano deployment solutions, it has the following advantages and disadvantages:

Advantages of Kamal 2

  1. Containerized Deployment

    • Completely isolated application environment, avoiding system dependency conflicts
    • Ensures consistency between development and production environments
    • Facilitates horizontal scaling and migration
  2. Simple Configuration

    • Single YAML configuration file
    • Built-in SSL support, automatic certificate application and renewal
    • Out-of-the-box health checks and zero-downtime deployment
  3. Operations Friendly

    • Built-in log management and capacity limits
    • Supports one-click rollback
    • Provides convenient remote debugging tools

Advantages of Capistrano

  1. Mature and Stable

    • Long usage history, rich community resources
    • Well-established problem-solving solutions
    • A large number of ready-made deployment scripts available
  2. Low Resource Usage

    • No need to run containers, lower system overhead
    • Suitable for small servers with limited resources
  3. High Flexibility

    • Can finely control each step of the deployment process
    • Supports complex custom deployment logic
    • Easier integration with existing systems

Kamal 2 represents the deployment trend in the containerization era, but this does not mean it is suitable for all scenarios. When choosing a deployment tool, you need to consider factors such as project scale, team situation, server resources, etc. comprehensively. No matter which tool you choose, ensuring it meets your deployment needs is the most important.

Tags
rails
Kamal 2
Puma
deploy