Logo

Practical Guide to Deploying Rails Applications with Kamal 2

avatar jayce 02 Dec 2024

Practical Guide to Deploying Rails Applications with Kamal 2

Introduction

Kamal 2 is a tool for deploying Rails applications, but currently, the related documentation is somewhat scattered and incomplete. This article shares the author’s practical experiences during the deployment process using 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

# Log 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
    # Needs to be declared here, otherwise database.yml cannot access 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 creates a Docker network named kamal and adds all containers to it. Therefore:

  • You cannot use IP or localhost
  • The Redis address should be redis://ai-hub-server-staging-redis:6379/0
  • The database address should be ai-hub-server-staging-db

For example, if the project uses redis, enter the server and run docker ps to find the name ai-hub-server-staging-redis, then 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 setup command

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

If there are accessories, such as pg, redis, etc., the containers will start, 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 latest commit code from the local repository. So remember to commit after making changes.

Common Issues and Solutions

1. Slow Access to Docker Hub

Solution:

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

Even when using Alibaba Cloud mirrors, if the deployment still cannot pull the kamal-proxy image, use a proxy to resolve it.

# /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 Issues

You need to configure in the 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 Not Outputting to Docker

Add the following 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 the 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 via 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 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"

Useful 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

Conclusion

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

Advantages of Kamal 2

  1. Containerized Deployment
    • Application environments are completely isolated, 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, automatically applies for and renews certificates
    • Out-of-the-box health checks and zero-downtime deployments
  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
    • Comprehensive solutions for problem resolution
    • A large number of ready-made deployment scripts available
  2. Low Resource Usage
    • Does not require running containers, lower system overhead
    • Suitable for resource-constrained small servers
  3. High Flexibility
    • Allows fine control over each step of the deployment process
    • Supports complex custom deployment logic
    • Easier integration with existing systems

Kamal 2 represents the deployment trend of the containerized era, but that does not mean it is suitable for all scenarios. When choosing a deployment tool, it is essential to consider factors such as project scale, team situation, and server resources comprehensively. Regardless of which tool you choose, ensuring it meets your deployment needs is the most important.

Tags
rails
部署
Kamal
Kamal 2
Puma