Guide to Deploying Rails Applications with Kamal 2
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
-
Containerized Deployment
- Completely isolated application environment, avoiding system dependency conflicts
- Ensures consistency between development and production environments
- Facilitates horizontal scaling and migration
-
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
-
Operations Friendly
- Built-in log management and capacity limits
- Supports one-click rollback
- Provides convenient remote debugging tools
Advantages of Capistrano
-
Mature and Stable
- Long usage history, rich community resources
- Well-established problem-solving solutions
- A large number of ready-made deployment scripts available
-
Low Resource Usage
- No need to run containers, lower system overhead
- Suitable for small servers with limited resources
-
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.