kamal-deploy
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseKamal Deploy Expert
Kamal部署专家
Expert guidance for deploying applications with Kamal - DHH's zero-downtime deployment tool from 37signals.
为使用Kamal部署应用提供专业指导——Kamal是37signals公司DHH开发的零停机部署工具。
Step 1: Fetch Latest Documentation (MANDATORY)
步骤1:获取最新文档(必填)
BEFORE answering ANY Kamal question, you MUST use the WebFetch tool to get current documentation. The docs below may be outdated - always fetch fresh docs first.
Execute these WebFetch calls in parallel:
-
WebFetch(url: "https://kamal-deploy.org/docs/installation/", prompt: "Extract complete installation and setup guide") -
WebFetch(url: "https://kamal-deploy.org/docs/configuration/overview/", prompt: "Extract all configuration options and deploy.yml structure") -
WebFetch(url: "https://kamal-deploy.org/docs/commands/view-all-commands/", prompt: "Extract all Kamal commands and usage") -
WebFetch(url: "https://kamal-deploy.org/docs/configuration/proxy/", prompt: "Extract proxy, SSL, and health check configuration")
Fetch these additional docs based on user's question:
- Servers/roles:
https://kamal-deploy.org/docs/configuration/servers/ - Accessories (DB, Redis):
https://kamal-deploy.org/docs/configuration/accessories/ - Environment variables:
https://kamal-deploy.org/docs/configuration/environment-variables/ - Docker build options:
https://kamal-deploy.org/docs/configuration/builders/ - Deployment hooks:
https://kamal-deploy.org/docs/hooks/overview/ - Upgrading v1→v2:
https://kamal-deploy.org/docs/upgrading/overview/
Only after fetching fresh docs, use the reference material below as supplementary context.
**在回答任何Kamal相关问题之前,你必须使用WebFetch工具获取当前文档。**以下文档可能已过时——务必先获取最新文档。
并行执行以下WebFetch调用:
-
WebFetch(url: "https://kamal-deploy.org/docs/installation/", prompt: "Extract complete installation and setup guide") -
WebFetch(url: "https://kamal-deploy.org/docs/configuration/overview/", prompt: "Extract all configuration options and deploy.yml structure") -
WebFetch(url: "https://kamal-deploy.org/docs/commands/view-all-commands/", prompt: "Extract all Kamal commands and usage") -
WebFetch(url: "https://kamal-deploy.org/docs/configuration/proxy/", prompt: "Extract proxy, SSL, and health check configuration")
根据用户的问题获取以下额外文档:
- 服务器/角色:
https://kamal-deploy.org/docs/configuration/servers/ - 附属组件(数据库、Redis):
https://kamal-deploy.org/docs/configuration/accessories/ - 环境变量:
https://kamal-deploy.org/docs/configuration/environment-variables/ - Docker构建选项:
https://kamal-deploy.org/docs/configuration/builders/ - 部署钩子:
https://kamal-deploy.org/docs/hooks/overview/ - 从v1升级到v2:
https://kamal-deploy.org/docs/upgrading/overview/
仅在获取最新文档后,才可将以下参考资料作为补充上下文使用。
What is Kamal?
什么是Kamal?
Kamal deploys containerized apps to any server via SSH + Docker. Created by 37signals (DHH's company) to deploy Basecamp, HEY, and other apps.
Core architecture:
- SSHs into servers, installs Docker automatically
- Builds app into Docker container
- Pushes to registry (Docker Hub, GHCR, etc.)
- Pulls and runs on target servers
- kamal-proxy handles routing, SSL (Let's Encrypt), zero-downtime
Mental model: Hetzner/DigitalOcean = the computer, Kamal = deploys your app to it
Kamal通过SSH + Docker将容器化应用部署到任意服务器。由37signals(DHH的公司)开发,用于部署Basecamp、HEY及其他应用。
核心架构:
- 通过SSH连接到服务器,自动安装Docker
- 将应用构建为Docker容器
- 推送到镜像仓库(Docker Hub、GHCR等)
- 在目标服务器上拉取并运行
- kamal-proxy处理路由、SSL(Let's Encrypt)和零停机部署
理解模型: Hetzner/DigitalOcean = 服务器,Kamal = 将你的应用部署到该服务器
Before You Start
开始之前
Check these first to avoid common friction:
-
Kamal version - Run. If on 1.x, upgrade with
kamal version. Config syntax changed significantly (1.x usesgem install kamal, 2.x usestraefik).proxy -
Local Docker situation - Ask the user if they have Docker working locally. If not (or if Docker Desktop is problematic on macOS), configure a remote builder:yaml
builder: arch: amd64 remote: ssh://root@SERVER_IPThis builds on the target server and avoids local Docker entirely. -
37signals open-source repos - If deploying Campfire, HEY, or other 37signals apps, immediately delete- it uses their internal 1Password setup and will fail with
.env.erb.op: command not found -
Registry access - Confirm the user has a container registry (Docker Hub, GHCR) and knows their credentials before writing config.
请先检查以下内容,避免常见问题:
-
Kamal版本 - 运行。如果是1.x版本,使用
kamal version升级。配置语法有重大变化(1.x使用gem install kamal,2.x使用traefik)。proxy -
本地Docker环境 - 询问用户本地是否已正常运行Docker。如果没有(或macOS上Docker Desktop存在问题),配置远程构建器:yaml
builder: arch: amd64 remote: ssh://root@SERVER_IP这会在目标服务器上构建镜像,完全无需本地Docker。 -
37signals开源仓库 - 如果部署Campfire、HEY或其他37signals应用,请立即删除文件——它使用的是37signals内部的1Password配置,运行时会提示
.env.erb错误。op: command not found -
镜像仓库访问权限 - 在编写配置之前,确认用户拥有容器镜像仓库(Docker Hub、GHCR)及对应的凭据。
Quick Start
快速开始
bash
undefinedbash
undefinedInstall (or upgrade)
安装(或升级)
gem install kamal
gem install kamal
Initialize in project
在项目中初始化
kamal init
kamal init
First deploy (installs Docker, proxy, deploys app)
首次部署(安装Docker、代理、部署应用)
kamal setup
kamal setup
Subsequent deploys
后续部署
kamal deploy
undefinedkamal deploy
undefinedEssential Commands
核心命令
| Command | Purpose |
|---|---|
| First deploy - installs Docker, proxy, deploys |
| Deploy new version |
| Revert to previous version |
| View application logs |
| SSH into running container |
| Start accessory (db, redis) |
| Restart kamal-proxy |
| Remove everything from servers |
| 命令 | 用途 |
|---|---|
| 首次部署 - 安装Docker、代理、部署应用 |
| 部署新版本 |
| 回滚到上一个版本 |
| 查看应用日志 |
| 进入运行中的容器 |
| 启动附属组件(数据库、Redis) |
| 重启kamal-proxy |
| 移除服务器上的所有相关组件 |
Minimal config/deploy.yml
最简配置/deploy.yml
yaml
service: my-app
image: username/my-app
servers:
- 123.45.67.89
registry:
username: username
password:
- KAMAL_REGISTRY_PASSWORD
proxy:
ssl: true
host: myapp.com
env:
secret:
- RAILS_MASTER_KEY
- DATABASE_URLyaml
service: my-app
image: username/my-app
servers:
- 123.45.67.89
registry:
username: username
password:
- KAMAL_REGISTRY_PASSWORD
proxy:
ssl: true
host: myapp.com
env:
secret:
- RAILS_MASTER_KEY
- DATABASE_URLSecrets Management
密钥管理
Secrets live in :
.kamal/secretsbash
undefined密钥存储在中:
.kamal/secretsbash
undefined.kamal/secrets
.kamal/secrets
KAMAL_REGISTRY_PASSWORD=ghp_xxxxxxxxxxxx
RAILS_MASTER_KEY=abc123def456
DATABASE_URL=postgres://user:pass@db:5432/app
Reference in deploy.yml:
```yaml
env:
clear:
RAILS_ENV: production
secret:
- RAILS_MASTER_KEY
- DATABASE_URLKAMAL_REGISTRY_PASSWORD=ghp_xxxxxxxxxxxx
RAILS_MASTER_KEY=abc123def456
DATABASE_URL=postgres://user:pass@db:5432/app
在deploy.yml中引用:
```yaml
env:
clear:
RAILS_ENV: production
secret:
- RAILS_MASTER_KEY
- DATABASE_URLMulti-Server with Roles
多服务器与角色配置
yaml
servers:
web:
hosts:
- 123.45.67.89
- 123.45.67.90
workers:
hosts:
- 123.45.67.91
cmd: bin/jobs
proxy: false # Workers don't need proxyyaml
servers:
web:
hosts:
- 123.45.67.89
- 123.45.67.90
workers:
hosts:
- 123.45.67.91
cmd: bin/jobs
proxy: false # 工作节点不需要代理Accessories (Databases, Redis)
附属组件(数据库、Redis)
yaml
accessories:
db:
image: postgres:16
host: 123.45.67.89
port: 5432
env:
clear:
POSTGRES_DB: app_production
secret:
- POSTGRES_PASSWORD
directories:
- data:/var/lib/postgresql/data
redis:
image: redis:7
host: 123.45.67.89
port: 6379
directories:
- data:/datayaml
accessories:
db:
image: postgres:16
host: 123.45.67.89
port: 5432
env:
clear:
POSTGRES_DB: app_production
secret:
- POSTGRES_PASSWORD
directories:
- data:/var/lib/postgresql/data
redis:
image: redis:7
host: 123.45.67.89
port: 6379
directories:
- data:/dataSSL Configuration
SSL配置
Automatic (Let's Encrypt):
yaml
proxy:
ssl: true
host: myapp.com # Must point to server IPCustom certificate:
yaml
proxy:
ssl:
certificate_pem:
- SSL_CERTIFICATE
private_key_pem:
- SSL_PRIVATE_KEY自动配置(Let's Encrypt):
yaml
proxy:
ssl: true
host: myapp.com # 必须指向服务器IP自定义证书:
yaml
proxy:
ssl:
certificate_pem:
- SSL_CERTIFICATE
private_key_pem:
- SSL_PRIVATE_KEYHealth Checks
健康检查
yaml
proxy:
healthcheck:
interval: 3
path: /up
timeout: 3App must return 200 on (Rails default) or configured path.
/upyaml
proxy:
healthcheck:
interval: 3
path: /up
timeout: 3应用必须在路径返回200状态码(Rails默认)或配置的自定义路径。
/upDestinations (Staging/Production)
部署目标(预发布/生产环境)
Create :
config/deploy.staging.ymlyaml
servers:
- staging.myapp.com
proxy:
host: staging.myapp.comDeploy:
kamal deploy -d stagingSecrets:
.kamal/secrets.staging创建:
config/deploy.staging.ymlyaml
servers:
- staging.myapp.com
proxy:
host: staging.myapp.com部署命令:
kamal deploy -d staging密钥文件:
.kamal/secrets.stagingHooks
钩子
Place in (no file extension):
.kamal/hooks/Available hooks:
- ,
pre-connect,pre-build,pre-deploypost-deploy - ,
pre-app-bootpost-app-boot - ,
pre-proxy-rebootpost-proxy-reboot
Example :
.kamal/hooks/post-deploybash
#!/bin/bash
curl -X POST "https://api.honeybadger.io/v1/deploys" \
-d "deploy[revision]=$KAMAL_VERSION"将钩子文件放在目录下(无文件扩展名):
.kamal/hooks/可用钩子:
- ,
pre-connect,pre-build,pre-deploypost-deploy - ,
pre-app-bootpost-app-boot - ,
pre-proxy-rebootpost-proxy-reboot
示例:
.kamal/hooks/post-deploybash
#!/bin/bash
curl -X POST "https://api.honeybadger.io/v1/deploys" \
-d "deploy[revision]=$KAMAL_VERSION"Dockerfile Requirements
Dockerfile要求
Kamal needs a Dockerfile. For Rails:
dockerfile
FROM ruby:3.3-slim
WORKDIR /appKamal需要Dockerfile。对于Rails应用:
dockerfile
FROM ruby:3.3-slim
WORKDIR /appInstall dependencies
安装依赖
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev
COPY Gemfile* ./
RUN bundle install
COPY . .
RUN bundle exec rails assets:precompile
EXPOSE 80
CMD ["bin/rails", "server", "-b", "0.0.0.0", "-p", "80"]
Note: Kamal 2.x defaults to port 80 (not 3000).RUN apt-get update -qq && apt-get install -y build-essential libpq-dev
COPY Gemfile* ./
RUN bundle install
COPY . .
RUN bundle exec rails assets:precompile
EXPOSE 80
CMD ["bin/rails", "server", "-b", "0.0.0.0", "-p", "80"]
注意:Kamal 2.x默认使用80端口(而非3000)。Common Issues
常见问题
"Container not healthy"
- Check endpoint returns 200
/up - Increase if app boots slowly
deploy_timeout - Check logs:
kamal app logs
"Permission denied"
- Ensure SSH key is added:
ssh-add ~/.ssh/id_rsa - Check SSH user has Docker access
Registry auth failed
- Verify in
KAMAL_REGISTRY_PASSWORD.kamal/secrets - For GHCR: use personal access token with
write:packages
"Address already in use"
- Another service on port 80/443
- Run or check
kamal proxy rebooton serverdocker ps
"容器不健康"
- 检查端点是否返回200
/up - 如果应用启动缓慢,增加
deploy_timeout - 查看日志:
kamal app logs
"权限被拒绝"
- 确保已添加SSH密钥:
ssh-add ~/.ssh/id_rsa - 检查SSH用户是否拥有Docker访问权限
"镜像仓库认证失败"
- 验证中的
.kamal/secretsKAMAL_REGISTRY_PASSWORD - 对于GHCR:使用拥有权限的个人访问令牌
write:packages
"地址已被占用"
- 80/443端口被其他服务占用
- 运行或在服务器上执行
kamal proxy reboot检查docker ps
Kamal vs Alternatives
Kamal与其他方案对比
| Kamal | Kubernetes | Heroku | |
|---|---|---|---|
| Complexity | Low | High | None |
| Cost | VPS only | VPS + overhead | $$$ |
| Control | Full | Full | Limited |
| Zero-downtime | Yes | Yes | Yes |
| SSL | Auto | Manual | Auto |
| Learning curve | Hours | Weeks | Minutes |
| Kamal | Kubernetes | Heroku | |
|---|---|---|---|
| 复杂度 | 低 | 高 | 无 |
| 成本 | 仅VPS费用 | VPS费用+额外开销 | 高 |
| 控制权 | 完全控制 | 完全控制 | 有限 |
| 零停机部署 | 支持 | 支持 | 支持 |
| SSL | 自动配置 | 手动配置 | 自动配置 |
| 学习曲线 | 数小时 | 数周 | 数分钟 |
Best Practices
最佳实践
- Always test locally first:
docker build . && docker run -p 3000:80 <image> - Use staging destination before production
- Keep secrets out of git: in
.kamal/secrets.gitignore - Set up monitoring: Use hooks to notify on deploy
- Regular backups: Especially accessory volumes
- Use asset bridging for Rails:
asset_path: /app/public/assets
- 始终先在本地测试:
docker build . && docker run -p 3000:80 <image> - 在生产环境前使用预发布目标
- 不要将密钥提交到git:将加入
.kamal/secrets.gitignore - 设置监控:使用钩子在部署时发送通知
- 定期备份:尤其是附属组件的卷
- 为Rails应用使用资源桥接:
asset_path: /app/public/assets
Reference Files
参考文件
For detailed configuration options, see:
- references/configuration.md - Complete deploy.yml reference
- references/troubleshooting.md - Common issues and solutions
如需详细配置选项,请查看:
- references/configuration.md - 完整的deploy.yml参考
- references/troubleshooting.md - 常见问题及解决方案