docs Aplicaciones

Aplicaciones

Crea, configura, despliega, escala y opera aplicaciones construidas desde Git o descargadas de un registry.

Tipos de origen

Crea una aplicación desde la página de tu proyecto con New Application. El campo Source acepta:

GitHub

Elige un repositorio a través de la GitHub App (cuando hay una configurada), o usa la URL de un repositorio con un token de acceso opcional para repos privados.

GitLab

URL del repositorio con un token de acceso de GitLab opcional para repos privados.

Git (any)

Cualquier repositorio Git accesible por HTTPS, con autenticación opcional mediante token.

Docker Image

Despliega una imagen existente desde un registry. No se construye nada: la imagen se descarga en cada despliegue.

Cuando una aplicación está conectada a través de la GitHub App, se clona con una credencial de instalación de corta duración (no se almacena ningún token para la aplicación), los pushes y pull requests llegan sin un webhook por repositorio, y DeployKit puede reportar el estado de los commits a GitHub. Puedes cambiar una aplicación existente entre la GitHub App y una URL + token desde la pestaña General (Change repository / Connect through the GitHub App instead). Sin la App, copia la URL del webhook que aparece en la pestaña General en la configuración de webhooks de tu repositorio para desplegar automáticamente en cada push.

Para un origen Docker Image, la referencia de la imagen (por ejemplo ghcr.io/acme/api:1.4.0) se guarda en el campo Repository URL de la pestaña General.

Puerto y red

Establece Port con el puerto en el que escucha tu proceso dentro del contenedor (por defecto 3000). Con al menos un dominio, Traefik enruta el tráfico a ese puerto y no se publica nada en el host. Sin dominio, el mismo puerto se publica en el host (host:port → container:port), por lo que dos aplicaciones sin dominio no pueden compartir puerto. Los dominios se gestionan desde la pestaña Domains — una aplicación puede tener varios; consulta Dominios y SSL.

Consejo: tu aplicación debe escuchar en el puerto configurado y enlazarse a 0.0.0.0, no a localhost. Un proceso enlazado a localhost arranca sin problemas, pero Traefik no puede alcanzarlo.

Estrategias de build

Nixpacks (detección automática, por defecto)

Detecta tu lenguaje y framework y construye una imagen sin configuración. Sobrescribe el comando de inicio detectado con Start Command (solo Nixpacks). Si Nixpacks falla o no está instalado, el build recurre automáticamente a la estrategia Dockerfile. Un build con Nixpacks caduca a los 10 minutos.

Dockerfile

Usa tu propio Dockerfile. Establece Dockerfile Path relativo a la raíz del repo (o al Root Directory), sin el prefijo ./ ; la ruta debe permanecer dentro del contexto de build. Si no existe ningún Dockerfile, DeployKit genera uno para los stacks más comunes: Go, Python, Next.js, SPAs estáticas (Vite, CRA, Vue, Angular, Svelte) y servidores Node. Para servidores Node ejecuta tu script start , de modo que comandos de varios pasos como prisma migrate deploy && node dist/index.js se ejecutan completos.

Buildpacks

Cloud Native Buildpacks mediante pack build. Ideal para proyectos que siguen convenciones estándar.

Servidores remotos: las aplicaciones desplegadas en un servidor remoto se clonan y se construyen en ese servidor con docker build usando el Dockerfile del repositorio. Nixpacks, Buildpacks y la generación automática de Dockerfile solo funcionan para aplicaciones en el servidor local, así que asegúrate de que el repo incluya un Dockerfile cuando el destino sea un servidor remoto.

Soporte para monorepos

Despliega aplicaciones desde subdirectorios estableciendo el Root Directory (por ejemplo apps/web). DeployKit usa ese directorio como contexto de build. Cuando genera un Dockerfile para un miembro del workspace, detecta el gestor de paquetes (archivos lock, después pnpm-workspace.yaml o el campo packageManager ) y construye el paquete junto con sus dependencias del workspace.

Variables de entorno

Gestiona las variables de entorno desde la pestaña Environment de tu aplicación, en formato KEY=VALUE , una por línea. Los valores están ocultos hasta que haces clic en Reveal. Todas las variables se cifran en reposo con AES-256-GCM y se inyectan en el contenedor en tiempo de ejecución. Los cambios surten efecto en el siguiente despliegue.

Por seguridad, las variables de entorno no se pasan como build args de Docker — los build args se filtran en las capas de la imagen y pueden leerse con docker inspect. En su lugar, antes de cada build DeployKit escribe las variables de tu aplicación en un archivo .env en la raíz del contexto de build, para que los frameworks que incrustan variables en tiempo de build (Vite, Create React App, Next.js) puedan leerlas.

  • Nixpacks / Buildpacks — el .env generado se encuentra en la raíz del contexto de build, donde la mayoría de los frameworks lo leen automáticamente. No requiere configuración adicional.
  • Dockerfile propio — tu Dockerfile debe hacer COPY del .env generado a la etapa de build antes de que se ejecute el paso de build; de lo contrario, las variables de build faltan sin avisar.
  • Monorepos — el .env se escribe en la raíz del contexto (la raíz del repo cuando Root Directory está vacío). Cópialo al subdirectorio de la aplicación: frameworks como Vite leen los archivos env desde el directorio de la aplicación, no desde la raíz del monorepo.
  • Revisa tu .dockerignore — si excluye .env, el daemon de Docker descarta el archivo generado del contexto de build y las variables de build nunca llegan.

Ejemplo para una aplicación Vite en un monorepo con pnpm (contexto de build = raíz del repo):

dockerfile
# DeployKit writes your app's env vars to a .env at the context root.
# The ".env*" glob keeps local builds working when no .env exists.
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json .env* ./

COPY apps/web apps/web
# Vite reads env files from the app directory, not the monorepo root
RUN if [ -f .env ]; then cp .env apps/web/.env; fi
RUN pnpm --filter web build

Volúmenes persistentes

Añade montajes en Persistent Volumes dentro de la pestaña General (hasta 20). El origen puede ser una ruta absoluta del host o un volumen con nombre de Docker, y la ruta del contenedor debe ser absoluta. Un sufijo opcional :ro lo monta en modo solo lectura. Los volúmenes persisten entre despliegues, rollbacks y réplicas.

bash
/srv/myapp/uploads:/app/uploads      # bind mount from the host
myapp-data:/var/lib/data             # Docker named volume
/srv/myapp/config:/app/config:ro     # read-only
  • Los bind mounts de directorios sensibles del host (como /etc, /proc, /sys, /dev, /boot, /root) y las rutas que contienen '..' se rechazan.
  • Las rutas que la imagen declara con una directiva VOLUME y que no montaste quedan cubiertas automáticamente por un volumen con nombre estable (dk-<app>-<path>), de modo que sus datos sobreviven a los redespliegues en lugar de acabar en un volumen anónimo nuevo cada vez.
  • Tras arrancar el contenedor, DeployKit inspecciona sus montajes reales. Si falta un volumen configurado, el despliegue falla de forma explícita en lugar de dejar que las escrituras vayan al sistema de archivos del contenedor, donde el siguiente redespliegue las borraría.

Health checks

Después de arrancar el contenedor, DeployKit puede comprobar que tu aplicación realmente está sirviendo. Elige el tipo en la pestaña General:

  • HTTP — envía un GET a la ruta configurada (por defecto /) en el primer dominio de la aplicación, o en localhost:<port> cuando no tiene dominio. Las respuestas 2xx y 3xx cuentan como saludables; las redirecciones no se siguen.
  • TCP — comprueba que el puerto acepta conexiones. Útil para servicios que no son HTTP.
  • None — omite la comprobación; la aplicación se marca como en ejecución en cuanto arranca el contenedor.

Configura el timeout (por defecto 5 s), el intervalo (por defecto 10 s) y los reintentos (por defecto 6). Con Fail deploy if health check does not pass activado, un health check fallido marca el despliegue como fallido; en caso contrario solo registra una advertencia y el contenedor sigue en ejecución.

Límites de recursos

En Resources, establece un límite de CPU (cores) (de 0.1 a 8) y un límite de Memory (MB) (de 64 a 32768) por contenedor. Déjalos vacíos para no aplicar límite. Los límites se aplican a cada réplica y surten efecto en el siguiente despliegue.

Réplicas y autoescalado

Establece Replicas (de 1 a 10) para ejecutar varios contenedores idénticos; Traefik reparte la carga entre ellos. La pestaña General muestra el estado en vivo de cada instancia.

Activa Autoscaling para ajustar el número de réplicas según la carga media de las réplicas en ejecución, dentro de Min replicas y Max replicas. Establece un CPU target % (relativo al límite de CPU, o a un núcleo si no hay límite) y/o un Memory target %; deja un objetivo vacío para ignorar esa métrica. El escalado se realiza en vivo, sin reconstruir.

  • La carga se evalúa cada 30 segundos.
  • Escalar hacia arriba: se añade una réplica cuando la carga se mantiene por encima del objetivo durante 1 minuto.
  • Escalar hacia abajo: se elimina una réplica solo cuando la carga se mantiene por debajo de la mitad del objetivo durante 5 minutos.
  • Tras cualquier acción de escalado hay un periodo de espera (cooldown) de 180 segundos.
  • Actualmente el autoescalado solo funciona para aplicaciones en el servidor local.

Las réplicas necesitan un dominio. Sin dominio, la aplicación publica un puerto fijo del host, que un segundo contenedor no puede enlazar, así que DeployKit despliega una única instancia (el log del despliegue dice Replicas require a domain). Los campos Replicas y Autoscaling permanecen deshabilitados hasta que la aplicación tenga un dominio. Si el autoescalado «no hace nada», revisa esto primero.

Modo mantenimiento

Haz clic en Maintenance en la cabecera de la aplicación para mostrar una página de mantenimiento en todos los dominios de la aplicación, con un mensaje opcional (hasta 500 caracteres). Tu aplicación no se detiene ni se redespliega: un pequeño contenedor de mantenimiento toma el control de los dominios de la aplicación en Traefik, y al desactivarlo el tráfico se restablece de inmediato.

  • Todas las URL devuelven HTTP 503 con Retry-After, de modo que las cachés y los monitores de uptime nunca consideran la página como disponible.
  • La página muestra desde cuándo la aplicación está en mantenimiento, se adapta al modo claro/oscuro y a inglés/español, y se recarga sola cuando la aplicación vuelve.
  • El mantenimiento sobrevive a los despliegues. Puedes desplegar, detener o escalar la aplicación que hay detrás y comprobarla antes de reabrirla; solo termina cuando haces clic en Turn off.
  • Usa Edit message para cambiar el texto mientras está activo. Los dominios añadidos durante el mantenimiento también quedan cubiertos.
  • La aplicación necesita al menos un dominio, y necesitas el rol de operador en el proyecto. También funciona en servidores remotos.

Logs

Los logs de los contenedores se recopilan de forma continua para cada contenedor en ejecución, haya o no alguien con el dashboard abierto. La pestaña Logs tiene dos modos:

  • Live — transmite la salida del contenedor en tiempo real.
  • History — busca por texto en los logs persistidos y filtra por nivel (error, warn, info, debug, fatal). Los niveles se infieren del texto del log con el mejor esfuerzo posible.

Los logs persistidos se conservan 7 días por defecto (establece LOG_RETENTION_DAYS en la API para cambiarlo). Los secretos habituales — tokens como ghp_ o sk_live_, cabeceras Bearer/Basic, tokens en URLs de Git, pares password= y claves de AWS — se ocultan antes de almacenar o transmitir los logs. La salida del build de cada despliegue está en la pestaña Deployments.

Terminal web

La pestaña Terminal abre una shell interactiva dentro del contenedor en ejecución desde tu navegador (haz clic en Connect; hay disponible pantalla completa).

  • La aplicación debe estar desplegada y en ejecución.
  • Requiere el rol global de operador o admin y el rol de operador en el proyecto de la aplicación.
  • La imagen debe contener /bin/sh, /bin/bash o /bin/ash; las imágenes sin shell (p. ej. distroless) no pueden abrir una terminal.
  • Las sesiones se cierran tras 15 minutos de inactividad.
  • Los comandos no se registran. Para un comando puntual con código de salida y salida almacenados, usa la pestaña Tasks.

Rollbacks

Cada despliegue registra su commit, los logs del build y la imagen que produjo. Desde la pestaña Deployments puedes hacer rollback a un despliegue anterior. No se reconstruye nada: DeployKit reinicia la aplicación desde la imagen almacenada, por lo que un rollback tarda segundos. Aparece como un nuevo despliegue llamado Rollback to <commit>. Solo cambia la imagen: se usan las variables de entorno, dominios, volúmenes, límites y número de réplicas actuales de la aplicación. Hacer rollback requiere el rol de operador en el proyecto.

La profundidad de rollback es 3. Una limpieza diaria (hacia las 03:00) conserva solo las imágenes de los 3 despliegues exitosos más recientes de cada aplicación, además de cualquier imagen en uso. Las entradas más antiguas siguen apareciendo en la lista, pero no se puede hacer rollback a ellas (No image stored — cannot roll back).

Despliegue y controles del día a día

  • Deploy — construye y despliega la rama por defecto de la aplicación.
  • Deploy from branch (el botón de rama junto a Deploy) — despliega cualquier rama una sola vez, sin cambiar la rama por defecto de la aplicación.
  • Stop / Start — detiene todos los contenedores de la aplicación o los vuelve a iniciar sin reconstruir.
  • Auto-deploy — un push a la rama por defecto dispara un despliegue a través de la GitHub App o del webhook del repositorio (consulta Webhooks).
  • Otras pestañas: Monitoring (métricas de CPU/memoria), Security (resultados del escaneo de vulnerabilidades de la imagen), Tasks (comandos programados y puntuales) y Previews (entornos de pull requests).

Pipeline de despliegue

Cuando lanzas un despliegue, ocurre lo siguiente:

  • Se crea un registro del despliegue con estado 'queued' y la petición devuelve la respuesta de inmediato.
  • Los despliegues de una misma aplicación se ejecutan de uno en uno; un nuevo despliegue espera hasta que termine el anterior.
  • El repositorio se clona (shallow, rama elegida) usando la credencial de la GitHub App o el token almacenado — o, en los orígenes Docker Image, se descarga la imagen.
  • Las variables de entorno se descifran y se escriben en un archivo .env en la raíz del contexto de build, de modo que las variables de build llegan al build.
  • La imagen se construye con la estrategia seleccionada y se etiqueta como deploykit/<app>:<commit>. En servidores remotos, el clonado y el build ocurren en ese servidor.
  • Opcionalmente, se escanea la imagen en busca de vulnerabilidades (solo informativo: un escaneo nunca bloquea un despliegue).
  • DeployKit vuelve a leer la configuración de la aplicación, de modo que los cambios guardados durante el build (env, dominios, volúmenes, límites) se aplican.
  • Todos los contenedores antiguos de la aplicación se detienen y se eliminan, y después arrancan los nuevos contenedores con las etiquetas de enrutado de Traefik, los volúmenes configurados y los límites de recursos.
  • Se verifican los montajes reales y se ejecuta el health check (si está configurado).
  • Se actualiza el estado del despliegue, se envían las notificaciones y, con la GitHub App, se reporta el estado del commit.
  • Los logs de build y de despliegue se transmiten al dashboard en tiempo real.