Heroku cambió las reglas del juego para el despliegue de aplicaciones Rails cuando apareció en 2007. Un git push heroku main y la aplicación estaba en producción. Durante años fue la solución por defecto para proyectos Rails pequeños y medianos. Cuando Heroku eliminó su plan gratuito en 2022 y subió precios, mucha gente empezó a buscar alternativas. Kamal (antes MRSK) es la apuesta de 37signals para desplegar en tu propio servidor con Docker sin perder la comodidad de un PaaS.
Qué es Kamal
Kamal es una herramienta de despliegue desarrollada por 37signals, la empresa de DHH. Funciona con Docker y SSH: toma tu imagen Docker de la aplicación, la sube al servidor, y gestiona la transición entre versiones con zero downtime usando Traefik como proxy inverso.
Kamal 2.0 salió en 2024 con mejoras importantes respecto a la versión 1: mejor soporte para múltiples servidores, gestión de accessories (servicios auxiliares como Redis o bases de datos) y una configuración más limpia.
# Instalar en el Gemfile gem "kamal" # O como herramienta standalone gem install kamal # Inicializar la configuración kamal init
La configuración de Kamal
El fichero principal es config/deploy.yml. Aquí va todo lo que Kamal necesita para desplegar:
# config/deploy.yml
service: mi_app
image: usuario/mi_app
servers:
web:
hosts:
- 192.168.1.100
- 192.168.1.101
labels:
traefik.http.routers.mi_app.rule: Host(`miapp.com`)
workers:
hosts:
- 192.168.1.102
cmd: bundle exec sidekiq
registry:
server: ghcr.io
username: usuario_github
password:
- KAMAL_REGISTRY_PASSWORD
env:
clear:
RAILS_ENV: production
DB_HOST: db.interno.com
secret:
- RAILS_MASTER_KEY
- DATABASE_URL
- REDIS_URL
accessories:
db:
image: mysql:8.0
host: 192.168.1.200
port: 3306
env:
secret:
- MYSQL_ROOT_PASSWORD
volumes:
- /var/lib/mysql:/var/lib/mysql
redis:
image: redis:7
host: 192.168.1.200
port: 6379
proxy:
ssl: true
host: miapp.com
El flujo de despliegue
# Primer despliegue (configura el servidor y despliega) kamal setup # Despliegues posteriores kamal deploy # Ver estado de los contenedores kamal details # Ver logs en tiempo real kamal logs # Ejecutar comandos en producción kamal app exec 'bundle exec rails console' kamal app exec 'bundle exec rails db:migrate' # Rollback al deploy anterior kamal rollback # Gestionar accessories por separado kamal accessory boot redis kamal accessory reboot db
El mecanismo de zero downtime funciona así: Kamal arranca el nuevo contenedor en el servidor, espera a que pase el healthcheck, le indica a Traefik que envíe el tráfico al nuevo contenedor, y luego para el contenedor antiguo. En la mayoría de los casos, el usuario no nota nada durante el despliegue.
Variables de entorno y secretos
Kamal separa las variables de entorno en dos categorías: clear (van en texto plano en deploy.yml) y secret (se leen de variables de entorno locales o de un fichero .env que no va al repositorio).
# .env (no subir al repositorio) KAMAL_REGISTRY_PASSWORD=ghp_xxxxxxxxxxxxxx RAILS_MASTER_KEY=xxxxxxxxxxxxxx DATABASE_URL=mysql2://usuario:[email protected]/mi_app_production REDIS_URL=redis://192.168.1.200:6379 # En el servidor, Kamal inyecta estas variables en el contenedor Docker # No necesitas gestionar un fichero .env en producción
Comparación con alternativas
Opción | Control | Coste | Complejidad |
Heroku | Bajo | Alto (desde ~50$/mes) | Muy baja |
Kamal + VPS | Total | Bajo (VPS desde ~5-20$/mes) | Media |
Kubernetes | Total | Variable | Alta |
Render/Fly.io | Medio | Medio | Baja |
Requisitos del servidor
Para usar Kamal, el servidor solo necesita:
- Ubuntu 22.04 o Debian 12 (o cualquier distro Linux moderna)
- Acceso SSH con clave pública
- Docker instalado (Kamal puede instalarlo automáticamente con
kamal server bootstrap)
Un VPS de 2 núcleos y 4 GB de RAM en Hetzner, DigitalOcean o Vultr cuesta entre 10 y 20 euros al mes y es más que suficiente para muchas aplicaciones Rails con tráfico moderado.
Kamal en Rails 8
Rails 8 incluye Kamal en su stack por defecto. Al crear una nueva aplicación con rails new, el generador ya crea el config/deploy.yml y el Dockerfile necesarios para desplegar con Kamal. Es la primera vez que Rails incluye una solución de despliegue out-of-the-box.
La integración con la suite Solid (Queue, Cache, Cable) hace que una aplicación Rails 8 desplegada con Kamal solo necesite un contenedor de aplicación y una base de datos, sin Redis, sin Memcached y sin Node.js. Una pila considerablemente más simple que hace tres años.
Imagen: Pexels / panumas nikhomkhai
