Kamal2: Guía de inicio para el despliegue en VPS

Ahora, los frameworks full-stack que uso principalmente son Next.js 16 y Rails 8. Usando Rails, conocí la herramienta de despliegue recomendada oficialmente, Kamal. Normalmente la uso para desplegar proyectos en servidores de RN y Alibaba Cloud. Es muy cómoda y sencilla de usar, ahora me gustaría presentarles el concepto de Kamal2 y cómo empezar a usarlo.
Este artículo no empezará con contenidos demasiado complejos. Prefiero dejar claro lo más esencial de Kamal2: qué es realmente, qué nos ayuda a hacer, cómo empezar con lo más básico, y cuáles son las operaciones más comunes. Al final, daré un caso de uso con Next.js para ayudarte a aplicar los conceptos anteriores a un proyecto concreto.
¿Qué es Kamal2?
Si se pudiera resumir en una frase, Kamal2 es una herramienta que **completa el despliegue de aplicaciones a través de SSH y Docker**. No proporciona capacidades de plataforma completa como Heroku, ni es un sistema de orquestación pesado como Kubernetes; más bien organiza la tarea de "desplegar un conjunto de contenedores Docker" en un conjunto de comandos y configuraciones repetibles.
La idea central de Kamal es bastante directa:
Hay un
Dockerfileestándar localmente.Usa
config/deploy.ymlpara describir los objetivos de despliegue y la información de la imagen.Conéctate al servidor a través de SSH y prepara el entorno Docker en el servidor.
Construye la imagen localmente y súbela al registro de imágenes, luego haz que el servidor la descargue y la ejecute.
Usa
kamal-proxypara manejar los puertos 80 y 443, y cambia el tráfico después de que pase la verificación de salud del nuevo contenedor.
Esta es una de las razones por las que me gusta Kamal. No introduce demasiadas abstracciones adicionales; sabes más o menos lo que está haciendo, por lo que es más fácil solucionar problemas cuando surgen.
¿Para qué escenarios es adecuado Kamal2?
Creo que Kamal es especialmente adecuado para la siguiente situación:
Ya estás empaquetando aplicaciones con Docker.
Tienes uno o varios servidores Linux propios.
Deseas que el proceso de despliegue sea lo más simple posible, sin tener que mantener una plataforma compleja.
Deseas que Rails, Next.js e incluso otros servicios web puedan usar el mismo método de despliegue.
En otras palabras, Kamal no te ayuda a "reemplazar Docker", sino a hacer el despliegue con Docker más cómodo.
Primero, entiende algunos conceptos básicos
Antes de comenzar, te sugiero que recuerdes los conceptos más importantes de Kamal.
config/deploy.yml
Este es el archivo de configuración principal de Kamal, la configuración de despliegue se lee de aquí. Puedes entenderlo como el "manual de instrucciones de este despliegue": el nombre del servicio, el nombre de la imagen, la lista de servidores, el registro de imágenes, las variables de entorno, builder, proxy, etc., todo se escribe aquí.
.kamal/secrets
Esta es la ubicación predeterminada del archivo de secrets, Kamal leerá las variables sensibles de aquí. Por ejemplo, la contraseña del registro de imágenes, o RAILS_MASTER_KEY de Rails, generalmente no se codifican directamente en deploy.yml, sino que se inyectan a través de .kamal/secrets.
kamal setup
Este es el comando más importante para el primer despliegue. La documentación dice claramente que se conecta al servidor, instala Docker (si no está), inicia sesión en el registro de imágenes, construye la imagen, la sube, la descarga, inicia kamal-proxy, inicia el nuevo contenedor y cambia el tráfico después de que GET /up devuelva 200 OK.
kamal deploy
Este es el comando más utilizado para versiones posteriores. Una vez que el primer setup ha funcionado, los despliegues posteriores se realizan habitualmente con kamal deploy.
Cómo instalar Kamal2
Si ya tienes un entorno Ruby local, la forma más directa de instalarlo es:
gem install kamalEsta es la forma estándar de instalación indicada en la documentación oficial. Si no tienes Ruby, también puedes ejecutar Kamal dockerizado, pero la documentación menciona explícitamente que esta forma tiene algunas limitaciones, por lo que para principiantes recomiendo usar la instalación con gem.
Una vez instalado, puedes ver la versión:
kamal versionInicializar un proyecto
Entra en el directorio de tu proyecto y ejecuta:
kamal initEste comando inicializará los archivos básicos necesarios para Kamal, los más importantes son config/deploy.yml y .kamal/secrets.
Si tu proyecto ya tiene un Dockerfile en la raíz, entonces ya tienes una condición previa clave. El proceso de despliegue de Kamal por defecto construye la imagen a partir del Dockerfile estándar en el directorio raíz del proyecto.
Configuración mínima viable
Recomiendo empezar con un config/deploy.yml muy pequeño. El ejemplo mínimo que da la documentación oficial es algo así:
service: myapp
image: your-registry-user/myapp
servers:
- 203.0.113.10
registry:
username: your-registry-user
password:
- KAMAL_REGISTRY_PASSWORD
builder:
arch: amd64
env:
secret:
- AUTH_SECRETEn esta configuración, lo más importante que debes entender primero son los siguientes elementos:
service: obligatorio, se usa como prefijo del nombre del contenedor.image: nombre de la imagen, finalmente se sube al registro.servers: lista de máquinas destino del despliegue.registry: configuración del registro de imágenes.env.secret: variables de entorno que deben leerse del archivo de secrets.builder.arch: arquitectura de construcción, en el ejemplo de la documentación se usa directamenteamd64.
En esta etapa, no busques una configuración completa; es más importante asegurarte de que el flujo básico funcione.
Configurar los secrets
A continuación, prepara .kamal/secrets. Por ejemplo:
KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD
AUTH_SECRET=your-auth-secretSi es un proyecto Rails, en el ejemplo de la documentación se lee RAILS_MASTER_KEY desde config/master.key. Esta es también una de las razones por las que Rails y Kamal se integran tan naturalmente: los proyectos nuevos de Rails ya son bastante fáciles de conectar con este método de despliegue.
¿Qué ocurre en el primer despliegue?
Cuando la configuración y los secrets están listos, puedes ejecutar:
kamal setupEste comando hace muchas cosas, pero puedes entenderlo como un "despliegue inicial completo". Según la documentación oficial, al menos realiza estas acciones:
Se conecta al servidor a través de SSH.
Si al servidor le falta Docker, lo instala automáticamente.
Inicia sesión en el registro de imágenes local y remoto.
Construye la imagen usando el Dockerfile en la raíz del proyecto.
Sube la imagen al registro.
Hace que el servidor descargue la imagen.
Asegura que
kamal-proxyesté funcionando en los puertos 80/443.Inicia el nuevo contenedor.
Espera a que
GET /updevuelva200 OK.Cambia el tráfico al nuevo contenedor.
Detiene el contenedor antiguo y limpia imágenes y contenedores detenidos innecesarios.
Hay un detalle muy importante aquí: **la verificación de salud por defecto es GET /up**. Por lo tanto, es mejor que tu aplicación tenga una interfaz de verificación de salud ligera como esta; de lo contrario, el contenedor nuevo podría estar funcionando pero Kamal no cambiará el tráfico.
Los despliegues posteriores son mucho más simples
Una vez que el primer setup ha tenido éxito, las actualizaciones posteriores generalmente solo requieren ejecutar:
kamal deployLa documentación ya lo establece claramente como el comando de despliegue posterior. Puedes entenderlo como "entrada de lanzamiento normal": reconstruye la imagen, la sube, la descarga, inicia un nuevo contenedor, verifica la salud, cambia el tráfico y detiene el contenedor antiguo.
Por lo tanto, desde la experiencia de uso, lo más cómodo de Kamal es: el primer despliegue requiere un poco más de preparación, pero luego se vuelve muy estable.
Operaciones comunes
Para empezar, creo que estos comandos son los más útiles:
Inicializar
kamal initGenera los archivos básicos de despliegue.
Primer despliegue
kamal setupPone en marcha el servidor, Docker, la imagen, el proxy y la aplicación por primera vez.
Lanzamientos posteriores
kamal deployEl comando más utilizado en el día a día.
Despliegue multi-entorno
Si luego empiezas a diferenciar staging y production, Kamal admite especificar el destino con -d, por ejemplo:
kamal deploy -d stagingLa documentación oficial explica que en este caso Kamal combina config/deploy.staging.yml con la configuración base.
Esta capacidad es muy práctica, pero si estás empezando, puedes saber que existe, sin necesidad de usarla de inmediato.
Por qué se complementa bien con Rails
Los proyectos nuevos de Rails 8 ya suelen incluir su propio Dockerfile, y el flujo de despliegue de Kamal se basa precisamente en el Dockerfile. Además, el ecosistema de Rails acepta naturalmente la cadena de herramientas de gemas de Ruby, por lo que conocer Kamal desde Rails es casi algo natural.
Para mí personalmente, fue precisamente porque vi este método en un proyecto de Rails que empecé a considerarlo seriamente como una solución de despliegue viable a largo plazo.
Un caso de uso básico con Next.js
Finalmente, un ejemplo más cercano a mi día a día: si quiero desplegar un proyecto Next.js con Kamal, normalmente lo convierto en una aplicación Docker estándar y luego se la entrego a Kamal para su publicación.
Primer paso: hacer que Next.js genere un standalone
La documentación de Next.js indica que al habilitar output: 'standalone', el resultado de la compilación genera .next/standalone, que contiene los archivos mínimos necesarios para ejecutar el despliegue y un server.js. Esto es muy adecuado para el despliegue con Docker, ya que no requiere copiar todo el entorno de desarrollo completo.
En next.config.js se puede escribir así:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone',
}
module.exports = nextConfigCabe señalar que la documentación de Next.js menciona que el modo output: 'standalone' es más adecuado para usar directamente el server.js generado, en lugar de seguir usando next start.
Segundo paso: preparar el Dockerfile
Un Dockerfile simple para Next.js podría verse así:
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
FROM node:22-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/static ./.next/static
EXPOSE 3000
CMD ["node", "server.js"]El punto aquí no son los trucos de Docker en sí, sino la idea: **primero convertir Next.js en un contenedor estándar y ejecutable, y luego dejar que Kamal se encargue del despliegue.**
Tercer paso: escribir la configuración de Kamal
Por ejemplo:
service: my-next-app
image: your-registry-user/my-next-app
servers:
- 203.0.113.10
registry:
username: your-registry-user
password:
- KAMAL_REGISTRY_PASSWORD
builder:
arch: amd64
env:
clear:
PORT: 3000
NODE_ENV: productionLa lógica de esta configuración es muy simple:
Kamal sabe cuál es el nombre del servicio.
Kamal sabe dónde debe subirse la imagen.
Kamal sabe en qué servidor debe desplegarse.
Una vez que el contenedor se inicia, la aplicación escucha en el puerto 3000, y el proxy maneja el tráfico externo.
Cuarto paso: añadir una interfaz de verificación de salud
Dado que Kamal por defecto verifica GET /up, en Next.js añadiré una ruta muy simple, por ejemplo, en App Router:
export async function GET() {
return Response.json({ ok: true })
}Colócalo en, por ejemplo, app/up/route.ts, así /up devolverá una respuesta simple de éxito. Esta interfaz debe ser lo más ligera posible; su único propósito es decirle a Kamal: el contenedor ya puede recibir tráfico.
Quinto paso: desplegar
Finalmente, volvemos al flujo estándar de Kamal:
kamal setupActualizaciones posteriores:
kamal deploySi este flujo se ejecuta de manera estable en un proyecto Next.js, descubrirás que a Kamal no le importa si usas Rails o no; lo que realmente le importa es **que puedas proporcionar una imagen Docker estándar y un servicio web que pueda verificar su estado de salud.**
Hasta aquí por ahora
Si eres como yo, que conociste Kamal a través de Rails 8 y luego fuiste migrando este método a proyectos de Next.js 16, entonces la posición de Kamal2 es muy fácil de entender: no es una plataforma, sino una herramienta que ordena el despliegue autogestionado con Docker.
En la fase inicial, basta con dominar esto:
Instalar Kamal.
Inicializar los archivos de configuración.
Entender
deploy.ymly.kamal/secrets.Saber usar
kamal setuppara el primer despliegue.Saber usar
kamal deploypara actualizaciones posteriores.Saber que la verificación de salud por defecto depende de
GET /up.
Cuando todo esto funcione bien, será más natural explorar temas como múltiples entornos, accessories, hooks y configuraciones de proxy complejas.
Seguir en Google
Añadir HeyBinyang como fuente preferida en Google
Si quieres seguir encontrando mis actualizaciones en Google, puedes marcar este sitio como fuente preferida.
Compartir
Compartir
Comparte este artículo.