Skip to main content
kamal-coder This skill guides deploying Rails applications with Kamal 2. Use when configuring deploy.yml, setting up kamal-proxy, managing secrets, accessories, or preparing servers for container deployment.
跳到安装 Skills Marketplace 发现并探索由社区构建的 Agent Skills
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/majesticlabs-dev/majestic-marketplace --skill kamal-coder命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
下载 Zip 下载中... 同仓库更多 Skills Create distinctive, production-grade frontend interfaces with high design quality. Use when building web components, pages, or applications. Includes framework-specific guidance for Tailwind, React, Vue, and Rails/Hotwire ecosystems.
Skill file structure, naming conventions, directory layout, frontmatter requirements, and invocation control. Use when creating skill files or slash commands to ensure correct format and validation.
Forces adversarial reasoning before committing to decisions. Triggers on architectural choices, approach selection, and planning phases to prevent premature commitment bias.
name kamal-coder description This skill guides deploying Rails applications with Kamal 2. Use when configuring deploy.yml, setting up kamal-proxy, managing secrets, accessories, or preparing servers for container deployment. allowed-tools Read Write Edit Grep Glob Bash
Kamal 2 Coder
Servers need Docker, SSH access, and ports 22/80/443 open. Provision with Ansible or cloud-init.
Configuration: config/deploy.yml
Minimal Setup
service: myapp
image: myapp
servers:
web:
- 203.0 .113 .10
proxy:
ssl: true
host: myapp.com
registry:
username: username
password:
- KAMAL_REGISTRY_PASSWORD
env:
clear:
RAILS_ENV: production
RAILS_LOG_TO_STDOUT: "true"
secret:
-
RAILS_MASTER_KEY
Multi-Role Setup (Web + Job Worker) service: myapp
image: myapp
servers:
web:
- 203.0 .113 .10
job:
hosts:
- 203.0 .113 .10
cmd: bin/jobs start
proxy:
ssl: true
host: myapp.com
registry:
username: username
password:
- KAMAL_REGISTRY_PASSWORD
env:
clear:
RAILS_ENV: production
SOLID_QUEUE_IN_PUMA: false
secret:
- RAILS_MASTER_KEY
cmd: bin/jobs start runs Solid Queue in a separate container
Set SOLID_QUEUE_IN_PUMA: false to disable in-process queue
Job role has no proxy — only web role serves HTTP traffic
With Local Registry Eliminates Docker Hub dependency, rate limits, and external costs:
registry:
server: localhost:5555
username: ignored
password:
- KAMAL_REGISTRY_PASSWORD
Deploy the registry as an accessory:
accessories:
registry:
image: registry:2
host: 203.0 .113 .10
port: "5555:5000"
volumes:
- registry_data:/var/lib/registry
With Accessories accessories:
db:
image: postgres:16
host: 203.0 .113 .10
port: 5432
env:
clear:
POSTGRES_DB: myapp_production
secret:
- POSTGRES_PASSWORD
directories:
- data:/var/lib/postgresql/data
options:
shm-size: 256m
redis:
image: redis:7-alpine
host: 203.0 .113 .10
port: 6379
directories:
- data:/data
cmd: redis-server --appendonly yes
Docker Volumes for Persistence For SQLite + ActiveStorage apps, mount a named volume:
servers:
web:
hosts:
- 203.0 .113 .10
volumes:
- myapp_storage:/rails/storage
labels:
docker-volume-backup.stop-during-backup: "true"
job:
hosts:
- 203.0 .113 .10
cmd: bin/jobs start
volumes:
- myapp_storage:/rails/storage
Both web and job containers share the same volume for database access.
Proxy Configuration (kamal-proxy) Kamal 2 uses kamal-proxy (not Traefik). It handles SSL termination, routing, and zero-downtime deploys.
Basic SSL proxy:
ssl: true
host: myapp.com
Automatic Let's Encrypt certificate provisioning — no manual cert management.
Custom Port proxy:
ssl: true
host: myapp.com
app_port: 3000
Multiple Hosts proxy:
ssl: true
hosts:
- myapp.com
- www.myapp.com
Health Check proxy:
ssl: true
host: myapp.com
healthcheck:
path: /up
interval: 3
timeout: 3
Response Timeout proxy:
ssl: true
host: myapp.com
response_timeout: 30
Secrets: .kamal/secrets Kamal reads secrets from .kamal/secrets (git-ignored).
With 1Password CLI KAMAL_REGISTRY_PASSWORD=$(op read "op://Infrastructure/DockerHub/password" )
RAILS_MASTER_KEY=$(op read "op://MyApp/production/master_key" )
DATABASE_URL=$(op read "op://MyApp/production/database_url" )
With Environment Variables KAMAL_REGISTRY_PASSWORD=$DOCKERHUB_TOKEN
RAILS_MASTER_KEY=$RAILS_MASTER_KEY
DATABASE_URL=$DATABASE_URL
Multi-Environment
service: myapp
service: myapp-staging
servers:
web:
- 203.0 .113 .20
proxy:
host: staging.myapp.com
RAILS_MASTER_KEY=$(op read "op://MyApp/staging/master_key" )
Deploy with: kamal deploy -d staging
Common Commands
First Deployment
Regular Operations kamal deploy
kamal deploy --version=abc123
kamal deploy -d staging
kamal redeploy
Rollback kamal app containers
kamal rollback <version>
Debugging kamal app exec --interactive bash
kamal app logs -f
kamal app exec --interactive "bin/rails console"
kamal app exec "bin/rails db:migrate"
Accessories kamal accessory boot all
kamal accessory reboot db
kamal accessory exec db --interactive "psql -U postgres"
kamal accessory logs litestream
Builder Configuration
Native Builds
Multi-Architecture
Remote Builder builder:
remote:
arch: amd64
host: ssh://builder@build-server
Build Arguments builder:
args:
RUBY_VERSION: "3.3.0"
Hooks
Pre-Deploy
echo "Running pre-deploy checks..."
Post-Deploy
echo "Deploy complete: $(date) "
curl -s https://notify.example.com/deploy
Provisioning Workflow
Ansible + Kamal Pipeline
ansible-playbook -i hosts.ini playbook.yml
kamal setup
What Ansible Should Configure Task Purpose Install Docker Container runtime Configure fail2ban SSH intrusion prevention Setup UFW Firewall (22, 80, 443) Enable NTP Time synchronization Create swap Memory overflow protection Harden SSH Disable password auth, root login Unattended upgrades Automatic security patches
Litestream Backup Accessory For SQLite apps, add Litestream as an accessory (see litestream-coder for full config):
accessories:
litestream:
image: litestream/litestream:0.3
host: 203.0 .113 .10
cmd: replicate
volumes:
- myapp_storage:/rails/storage:ro
files:
- config/litestream.yml:/etc/litestream.yml
env:
secret:
- LITESTREAM_ACCESS_KEY_ID
- LITESTREAM_SECRET_ACCESS_KEY
Mount storage as read-only (:ro) — Litestream only reads WAL files.
Directory Structure myapp/
├── config/
│ ├── deploy.yml # Main Kamal config
│ └── deploy.staging.yml # Staging overrides
├── .kamal/
│ ├── secrets # Production secrets (git-ignored)
│ ├── secrets.staging # Staging secrets (git-ignored)
│ └── hooks/
│ ├── pre-deploy
│ └── post-deploy
├── Dockerfile # Application container
└── docker-entrypoint.sh # Entrypoint script
Troubleshooting Issue Cause Fix Connection refused Docker not running kamal setup or check Docker servicePermission denied SSH key not authorized Check server's authorized_keys Health check failing App not starting Check kamal app logs Registry auth failed Wrong credentials Verify .kamal/secrets 502 Bad Gateway Container not healthy Increase healthcheck timeout SSL cert not issued DNS not pointing to server Verify DNS A record Asset 404 after deploy Volume not mounted Check volumes: in deploy.yml
References