Files
fn_registry/bash/functions/pipelines/dockerize_app.md
T
egutierrez fc4180cbb3 chore: auto-commit (129 archivos)
- .claude/agents/fn-analizador/SKILL.md
- .claude/agents/fn-constructor/SKILL.md
- .claude/agents/fn-executor/SKILL.md
- .claude/agents/fn-mejorador/SKILL.md
- .claude/agents/fn-orquestador/SKILL.md
- .claude/agents/fn-recopilador/SKILL.md
- .claude/commands/app.md
- .claude/commands/compile.md
- .claude/commands/cpp-app.md
- .claude/commands/create_functions.md
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-01 22:23:12 +02:00

7.5 KiB

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports params output tested tests test_file_path file_path
dockerize_app pipeline bash pipelines 1.0.0 impure dockerize_app(app_name: string, [--domain DOMAIN], [--port PORT], [--ssh-host HOST], [--remote-dir DIR], [--basic-auth USER:PASS], [--no-auth], [--no-gzip], [--env KEY=VAL]..., [--volume NAME], [--build-cmd CMD], [--standalone], [--dry-run]) -> json Empaqueta una app Go del registry para deploy a VPS organic-machine via Docker + Traefik + Coolify. Genera Dockerfile multi-stage, docker-compose.yml, traefik-dynamic.yml con basicAuth opcional y gzip, sube via rsync al VPS y arranca el stack remoto. Replica el patron de apps/registry_api/.
docker
traefik
coolify
deploy
pipeline
launcher
generate_dockerfile_go_infra
bcrypt_htpasswd_go_infra
generate_compose_traefik_go_infra
generate_traefik_dynamic_go_infra
rsync_deploy_bash_infra
docker_compose_remote_deploy_bash_infra
health_check_http_go_infra
gitea_create_repo_bash_infra
gitea_push_directory_bash_infra
ComposeTraefikConfig_go_infra
TraefikDynamicConfig_go_infra
false error_go_core
name desc
app_name Nombre o ID parcial de la app en registry.db (ej: kanban, deploy_server). Se busca con LIKE '<app_name>%' OR name='<app_name>'.
name desc
domain Dominio publico completo para el router Traefik (ej: kanban.organic-machine.com). Obligatorio.
name desc
port Puerto interno del contenedor Docker (default: 8080). Debe coincidir con el puerto en que la app escucha.
name desc
ssh-host Alias o IP del host SSH destino (default: organic-machine.com). Debe estar en ~/.ssh/config o ser accesible con key auth.
name desc
remote-dir Ruta absoluta en el VPS donde se desplegara la app (default: /home/ubuntu/coolify-apps/<app_name>). En modo rsync apunta al subdir de la app dentro del build root.
name desc
basic-auth Credenciales para basicAuth de Traefik en formato USER:PASS. Obligatorio si auth esta ON (defecto). Se hashea con bcrypt via htpasswd o python3+bcrypt.
name desc
no-auth Flag para deshabilitar basicAuth. Por defecto auth esta habilitado; se requiere --basic-auth USER:PASS si no se pasa --no-auth.
name desc
no-gzip Flag para deshabilitar el middleware gzip de Traefik. Por defecto gzip esta habilitado.
name desc
env Variable de entorno KEY=VAL a incluir en el .env y en la seccion environment del docker-compose.yml. Repetible para multiples vars.
name desc
volume Nombre de un Docker volume que se monta en /data dentro del contenedor. Se declara en la seccion volumes del compose.
name desc
build-cmd Comando de build personalizado (documentado para uso futuro; Phase 1 usa el Dockerfile multi-stage generado).
name desc
standalone Modo standalone: crea repo Gitea dataforge/<app> y usa git clone/pull en el VPS en vez de rsync. Requiere GITEA_URL y credenciales Gitea configuradas.
name desc
dry-run Imprime los artefactos generados (Dockerfile, docker-compose.yml, traefik-dynamic.yml, .env) a stderr y retorna JSON con status=dry-run sin ejecutar ningun comando remoto ni escribir ficheros en la app.
JSON a stdout: {status, app, domain, remote_dir, container_id, duration_seconds, auth_enabled, gzip_enabled, http_code, url}. status='ok' si el health check responde HTTP 200/401, 'failed' si hay timeout, 'dry-run' en modo dry-run. false
bash/functions/pipelines/dockerize_app.sh

Ejemplo

# Deploy completo con basicAuth
cd $HOME/fn_registry
bash bash/functions/pipelines/dockerize_app.sh kanban \
  --domain kanban.organic-machine.com \
  --port 8421 \
  --basic-auth lucas:supersecret \
  --env KANBAN_DB=/data/kanban.db \
  --volume kanban_data

# Salida esperada:
# {"status":"ok","app":"kanban","domain":"kanban.organic-machine.com","remote_dir":"...","container_id":"abc123","duration_seconds":45,"auth_enabled":true,"gzip_enabled":true,"http_code":"401","url":"https://kanban.organic-machine.com"}

# Deploy sin auth (app publica)
bash bash/functions/pipelines/dockerize_app.sh registry_api \
  --domain registry.organic-machine.com \
  --port 8080 \
  --no-auth \
  --env REGISTRY_API_TOKEN=mytoken

# Dry-run: ver YAMLs sin tocar nada
bash bash/functions/pipelines/dockerize_app.sh kanban \
  --dry-run \
  --domain kanban.organic-machine.com \
  --port 8421 \
  --basic-auth lucas:test123

# Standalone: repo Gitea + git clone en VPS
bash bash/functions/pipelines/dockerize_app.sh deploy_server \
  --domain deploy.organic-machine.com \
  --port 9090 \
  --basic-auth lucas:secret \
  --standalone

Pasos internos

Paso Descripcion
1 Valida la app en registry.db (SQL sobre tabla apps)
2 Valida conectividad SSH (BatchMode, ConnectTimeout=5)
3 Genera hash bcrypt via htpasswd o python3+bcrypt
4 Genera Dockerfile multi-stage Go (heredoc, patron generate_dockerfile_go_infra)
5 Genera docker-compose.yml con Traefik labels y red coolify
6 Genera traefik-dynamic.yml con routers HTTP/HTTPS, basicAuth, gzip, certResolver letsencrypt
7 Genera/actualiza .env con merge no destructivo
8 Rsync del repo completo al VPS (o git clone en standalone)
9 Crea directorio remoto de deploy
10 Sube traefik-dynamic.yml a /data/coolify/proxy/dynamic/.yml via SSH+sudo tee
11 Sube docker-compose.yml, Dockerfile y .env al remote_dir via scp
12 Crea red Docker coolify si no existe; docker compose up -d --build remoto
13 Health check: 10 intentos, 3s intervalo, acepta HTTP 200 y 401

Decision de implementacion

Los YAMLs se generan con heredocs bash inline, replicando la logica de generate_dockerfile_go_infra, generate_compose_traefik_go_infra y generate_traefik_dynamic_go_infra. Esta decision evita crear un nuevo binario cmd/dockerize_helpers/ y mantiene el pipeline completamente self-contained, siguiendo el patron de setup_registry_api_bash_infra. Las funciones Go quedan referenciadas en uses_functions como fuente de verdad documental del patron que replica.

Requisitos en el host local

  • ssh y rsync instalados
  • htpasswd (apache2-utils) o python3 + modulo bcrypt para generar hash
  • Acceso SSH sin password al host destino (key en ~/.ssh/config)
  • sqlite3 CLI para leer registry.db

Requisitos en el VPS

  • Docker + docker compose (v2)
  • Coolify con Traefik corriendo y /data/coolify/proxy/dynamic/ accesible via sudo
  • Red Docker coolify (se crea automaticamente si no existe)
  • Usuario SSH con sudo sin password para: mkdir, tee en /data/coolify/proxy/dynamic/

Codigos de salida

Codigo Significado
0 Exito: stack activo y health check OK
1 Error: app no encontrada, SSH inavalcable, fallo de build, health check timeout

Notas

  • Phase 1 soporta exclusivamente apps lang: go. Soporte para Python y Bash en fases futuras.
  • El Dockerfile se genera solo si no existe en el directorio de la app. Si ya existe (con tweaks manuales), se preserva y se avisa por stderr.
  • El build context del Dockerfile es ../../ relativo a apps/<app>/ para que el multi-stage copie el go.mod del root del registry y compile correctamente.
  • El nombre del router Traefik reemplaza _ por - (ej: registry_apiregistry-api).
  • En modo --standalone, se requieren las variables GITEA_URL, GITEA_TOKEN (o GITEA_USER/GITEA_PASS) configuradas para gitea_create_repo y gitea_push_directory.