Skip to content

Kamal

Desplegar aplicaciones se ha vuelto cada vez más complejo, Kamal surge como una herramienta que busca simplicidad. Desarrollada por el equipo de 37signals (del creador de Ruby on Rails), Kamal es una solución ligera y moderna diseñada específicamente para desplegar contenedores Docker en servidores remotos (VM o VPS) de forma sencilla y confiable (usando ssh).

Pensado para desarrolladores y equipos que buscan enfocarse en construir su producto en lugar de pelear con infraestructuras, Kamal representa el "regreso a lo simple" en el ecosistema de despliegues. Con solo un archivo de configuración y unos pocos comandos, puedes tener tu aplicación corriendo en una VM, VPS o servidor dedicado de forma productiva.

Con Kamal puedes enfocarte dejando a un lado orquestadores pesados como Kubernetes (si tu proyecto no tiene ese requisito). Teniendo claro que se usan instancias de computo (VM o VPS) sobre las que se gestionan el despliegue de contenedores con Kamal. No se trata de IaC (Infraestructure as Code), puesto que requieres como infraestructura la instancia de computo, sino de un gestor simple para despliegues como herramienta DevOps. Por supuesto, puedes combinar Kamal con una herramienta de IaC, por ejemplo, Ansible.

En este artículo exploraremos cómo funciona esencialmente para comprender por qué es la herramienta favorita usada en muchos side-projects y aplicaciones en producción de tamaño medio.

Instalando Kamal

Kamal puede instalarse usando gem de Ruby. Por ejemplo, para Linux Ubuntu/Debian puedes ejecutar:

bash
sudo apt update
sudo apt install -y ruby-full
gem install kamal

Para macOS instala Ruby con: brew install ruby

Configurando Kamal

Kamal usa un archivo de configuración en tu proyecto de código (o repo) denominado deploy.yml y ubicado, por ejemplo, en la ruta ./config. Veamos un ejemplo para ilustrar su contendo:

yml
service: my-app           # Service name

image: myuser/my-app      # Docker image (or local)

servers:
  web:
    - 123.456.789.012     # IP or hostname for VM

env:                      # Variables in clear & secrets
  clear:
    RAILS_ENV: production
  secret:
    - DATABASE_URL
    - SECRET_KEY_BASE

ssh:
  user: deploy            # User to access the server by SSH

# Build (for local use)
builder:
  multiarch: false        # true when uses ARM + AMD

# Access to registry (Docker Hub, GHCR, etc.)
registry:
  username: myuser
  password:
    - KAMAL_REGISTRY_PASSWORD   # Saved in .kamal/secrets

Los elementos o atributos pueden sentirse familiares y una vez defines esto obtienes un mecanismo sencillo para desplegar

Comandos Básicos

  • kamal setup: Se usa por primera vez para configurar el servidor
  • kamal build: construye la imagen (aunque el deploy también lo hace)
  • kamal deploy: Despliega (o actualiza) el contenedor
  • kamal logs: Muestra logs
  • kamal app exec "node -v": Ejecuta comandos en el contenedor

Ejemplo de un proyecto Javascript

En siguiente ejemplo, de una imagen con entrono Javascript (Bun), ilustraremos el Dockerfile y el archivo de configuracion para usar Kamal. Veamos el contenido para Dockerfile...

Dockerfile
FROM oven/bun:1 AS builder

WORKDIR /app

COPY package.json bun.lockb* ./
RUN bun install --frozen-lockfile

COPY . .

FROM oven/bun:1-slim

WORKDIR /app

COPY --from=builder /app /app

EXPOSE 3000

CMD ["bun", "run", "start"]

En el archivo ./config/deploy.yml podríamos tener algo como lo siguiente:

yml
service: my-app-bun

image: my-user/my-app-bun

servers:
  web:
    - YOUR_IP_OR_HOSTNAME

env:
  clear:
    NODE_ENV: production

Este archivo de configuración debe adecuarse al proyecto específico, asignando la IP o HOSTNAME (dominio de tu VPS)
Puedes hacer un laboratorio localmente usando Colima como máquina virtual (VM)

Finalmente, ejecutamos:

bash
kamal build
kamal deploy