使用 Kamal 2 部署 Rails 应用实践指南
jayce
22 Nov 2024
使用 Kamal 2 部署 Rails 应用实践指南
前言
Kamal 2 是一个用于部署 Rails 应用的工具,但目前相关文档比较分散且不够完整。本文将分享笔者在使用 Kamal 2 部署过程中的实践经验,希望能给大家一些参考。
完整配置示例
# config/deploy.staging.yml
# puma 服务名
service: ai-hub-server-staging
# 命名空间 / 镜像名
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:
# 你的 Docker Hub 用户名和密码
# 使用阿里云服务
server: crpi-9ja5ymdca5joh9vj.cn-shenzhen.personal.cr.aliyuncs.com
username: 396803555@qq.com
password:
- AI_HUB_KAMAL_REGISTRY_PASSWORD
builder:
arch: amd64
# 指定 Dockerfile 路径
dockerfile: Dockerfile.staging
# 日志配置
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
# 需要在这里声明,不然 database.yml 没法获取到
# 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 # 你的服务器 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 # 你的服务器 IP
aliases:
console: app exec --reuse -i "bin/rails console"
数据库配置示例:
# database.yml.example
staging:
<<: *default
database: ai_hub_server_staging
username: deploy
password: <%= ENV['AI_HUB_KAMAL_POSTGRES_PASSWORD'] %>
Docker 网络说明
Kamal 2 会创建一个名为 kamal
的 Docker 网络,并将所有容器加入其中。因此:
- 不能使用 IP 或 localhost
- Redis 地址应该是
redis://ai-hub-server-staging-redis:6379/0
- 数据库地址应该是
ai-hub-server-staging-db
例如项目中使用 redis
,进入服务器上docker ps
找到 name ai-hub-server-staging-redis
那 REDIS_HOST 就应该是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
部署步骤
1. 初始化 Kamal
kamal init
2. 配置 deploy.yml 和 Dockerfile
3. 运行 setup 命令
kamal setup -c "config/deploy.staging.yml"
如果有 accessories 此时比如 pg, redis 等容器会启动好,可以看到容器名称。
4. 调整 Redis 配置
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. 部署应用
kamal deploy -c "config/deploy.staging.yml"
需要留意的是每次部署都是拿本地最后一次 commit 的代码部署的。 所以修改后要记得提交。
常见问题及解决方案
1. Docker Hub 访问慢
解决方案:
- 使用阿里云镜像服务
- 或在 Docker Daemon 配置代理:
即使使用了阿里云镜像,部署最后还是无法 pull kamal-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 环境变量问题
需要在系统环境变量中配置:
# 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 日志无法输出到 Docker
在 config/environments/staging.rb 中添加:
config.logger = ActiveSupport::Logger.new(STDOUT)
.tap { |logger| logger.formatter = ::Logger::Formatter.new }
.then { |logger| ActiveSupport::TaggedLogging.new(logger) }
确认 docker 日志格式:
> docker inspect --format='{{.HostConfig.LogConfig.Type}}' 9b0b24c16554
json-file
kamal 相关配置项
logging:
# 默认就是这个
driver: json-file
options:
max-size: 100m
4. SSL 配置
Kamal-proxy 支持通过 Let’s Encrypt 自动配置 HTTPS:
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
常用命令
进入容器查看详情
docker exec -it CONTAINER_ID bash
解除部署锁
kamal lock release
# 或
kamal lock release -c "config/deploy.staging.yml"
Rails Console
# deploy.staging.yml
# 配置别名
aliases:
console: app exec --reuse -i "bin/rails console"
# 命令行使用
kamal console -c "config/deploy.staging.yml"
查看远程日志
kamal app logs -c "config/deploy.staging.yml"
实用配置参数
Rails 服务端口映射
servers:
web:
hosts:
- your-host
options:
publish:
- "4022:3000"
禁用 Kamal Proxy
servers:
web:
hosts:
- your-host
proxy: false
总结
Kamal 2 是一个基于 Docker 的 Rails 应用部署工具。相比传统的 Capistrano 部署方案,它有以下优势和不足:
Kamal 2 的优势
-
容器化部署
- 应用环境完全隔离,避免系统依赖冲突
- 保证开发环境和生产环境的一致性
- 便于横向扩展和迁移
-
配置简单
- 单一 YAML 配置文件
- 内置 SSL 支持,自动申请和续期证书
- 开箱即用的健康检查和零停机部署
-
运维友好
- 内置日志管理和容量限制
- 支持一键回滚
- 提供便捷的远程调试工具
Capistrano 的优势
-
成熟稳定
- 使用历史长,社区资源丰富
- 问题解决方案完善
- 大量现成的部署脚本可用
-
资源占用小
- 不需要运行容器,系统开销更小
- 适合资源受限的小型服务器
-
灵活性高
- 可以精细控制部署流程的每个步骤
- 支持复杂的自定义部署逻辑
- 与现有系统集成更容易
Kamal 2 代表了容器化时代的部署趋势,但这并不意味着它适合所有场景。选择部署工具时,需要根据项目规模、团队情况、服务器资源等因素综合考虑。无论选择哪种工具,确保它能满足你的部署需求才是最重要的。
Tags
rails
部署
Kamal
Kamal 2
Puma