Ir al contenido

Deploy en producción

El WhyStack Agent se distribuye como imagen de contenedor. Corre dentro de tu infraestructura, lee tus credenciales desde tu secret manager y abre una única conexión de salida hacia el control-plane.

Antes de empezar, haz el Quickstart: valida la imagen, el certificado y el túnel sin involucrar ninguna de tus credenciales. Si algo de la plomería está mal, es mucho más barato descubrirlo ahí.

Ítem Qué es
Dirección de la imagen En ECR o Artifact Registry, con tu cuenta/proyecto autorizado a hacer pull.
Un camino de identidad Donde tu plataforma prueba identidad por sí sola (GKE, EC2/EKS), nada: configuras la atestación. Si no, un bootstrap token que generas en Onboarding. El certificado que emitimos (runner.crt · runner.key · ca.pem) es el puente para todo lo demás.
RUNNER_TUNNEL_URL La dirección del túnel.

No hay credencial de WhyStack que tengas que guardar o rotar: el pull usa la identidad de tu propia nube.

Ventana de terminal
# AWS (ECR)
docker pull <whystack-account>.dkr.ecr.<region>.amazonaws.com/rootpilot-agent:<version>
# GCP (Artifact Registry)
docker pull <region>-docker.pkg.dev/<whystack-project>/rootpilot/rootpilot-agent:<version>

Multiarquitectura: la misma dirección sirve amd64 y arm64 (Graviton, Tau, Axion).

El registry es privado: autentícate con tus credenciales antes del pull, y asegúrate de que la identidad que usa tu orquestador también esté autorizada. Consulta La imagen › Autenticarse antes del pull.

El contenedor corre como usuario no root (uid 1000). No necesita privilegios, ni capabilities extra, ni acceso al socket de Docker.

El Agent se autentica por mTLS, y el certificado es de vida corta: 15 minutos, renovado solo. La elección aquí es de dónde viene la primera identidad, y decide si un deploy necesita a alguien en un navegador. El tema completo está en Identidad y enrollment; en producción, la versión corta es:

Si tu plataforma prueba identidad (GKE, o cualquier lugar con una credencial de AWS: EC2, EKS), usa la atestación de nube. Es la mejor opción porque no hay secreto que generar, entregar ni rotar:

Ventana de terminal
RUNNER_ENROLL_URL=https://app.rootpilot.sh
RUNNER_ATTESTATION_MODE=gke-oidc # or aws-sts

Si no (VPS, host propio), usa un bootstrap token y persiste la identidad, o cada reemplazo de contenedor cuesta un token nuevo, generado a mano:

Ventana de terminal
RUNNER_ENROLL_URL=https://app.rootpilot.sh
RUNNER_ATTESTATION_MODE=bootstrap-token
RUNNER_BOOTSTRAP_TOKEN=<minted under Onboarding>
RUNNER_IDENTITY_DIR=/identity # volume writable by uid 1000
RUNNER_INSTANCE_ID=agent-prod-1 # optional: identifies the instance in logs and in Fleet

Si WhyStack te entregó un certificado, monta los tres PEMs en /certs, de solo lectura. El entrypoint los carga por ti:

/certs/runner.crt
/certs/runner.key
/certs/ca.pem

Si tu orquestador inyecta los secretos como variables y no como archivos, pasa el contenido inline en RUNNER_CERT_PEM, RUNNER_KEY_PEM y RUNNER_CA_PEM. Es equivalente. Ese certificado no se renueva: anota en el calendario el notAfter del log de boot.

El Agent lee las credenciales de tus servicios desde tu secret manager en el boot y las mantiene solo en memoria. Elige el backend:

Ventana de terminal
RUNNER_SECRET_STORE_MODE=aws # AWS Secrets Manager
RUNNER_SECRET_STORE_MODE=vault # HashiCorp Vault KV v2

Los detalles de cada uno están en Secret stores; qué claves pide cada servicio, en Credenciales por connector.

Si el Agent corre en la misma cuenta que quieres observar, prefiere la identidad del propio workload a una clave estática: RUNNER_AWS_CRED_MODE=chain o RUNNER_GCP_CRED_MODE=chain. Consulta Credenciales de nube.

Lo mínimo:

Ventana de terminal
RUNNER_TUNNEL_URL=wss://tunnel.rootpilot.sh:8443
RUNNER_CONNECTORS=real
RUNNER_SECRET_STORE_MODE=aws
NODE_ENV=production

La referencia completa está en Variables de entorno. Para Kubernetes, consulta Kubernetes, en especial la parte de los probes, que tiene una trampa.

Los logs son JSON, una línea por evento. La que importa es la última:

{"level":"info","message":"hello accepted","context":"runner","sessionId":"..."}

A partir de ahí el Agent aparece en la vista Flota del control-plane, con el estado de cada servicio conectado: si la credencial existe y si funciona. Una clave inválida o sin autorización aparece ahí como error, con la causa.

No hay endpoint HTTP de health: el Agent es un cliente de salida y no escucha en ningún puerto. La señal de salud es un archivo, leído desde dentro del contenedor: docker exec <container> rootpilot-health ready te dice si tiene el enrollment hecho, si está conectado y si su hello fue aceptado. La imagen declara un HEALTHCHECK de liveness (rootpilot-health live), que es lo que docker ps muestra como healthy: vivo, no necesariamente conectado.

El certificado tiene fecha de vencimiento y no se renueva solo. Cuando vence, el Agent deja de conectarse y toda la flota deja de responder.

El notAfter sale en el log en cada boot, y es tu aviso previo:

{"level":"info","message":"using provisioned cert","context":"runner","notAfter":"2027-08-10T00:00:00.000Z"}

Trata el cambio como mantenimiento planificado: WhyStack emite el par nuevo, tú reemplazas el contenido montado en /certs y reciclas las réplicas. No se pierde ningún dato, porque el Agent no guarda estado durable.

Asegúrate de que tu supervisor (ReplicaSet, servicio de ECS, restart de Compose) levante un reemplazo cuando el proceso termine. El Agent es descartable por construcción: con SIGTERM deja de aceptar trabajo nuevo, termina lo que está en curso y sale, dentro de RUNNER_DRAIN_TIMEOUT_MS (2 minutos por defecto). Dale al orquestador un timeout de parada mayor que ese, o el SIGKILL llega en medio del drain.

Un SIGTERM que llega durante el boot sale de inmediato: antes del hello no hay trabajo que drenar, incluso mientras el túnel todavía intenta conectarse. La excepción es en medio del enrollment. El bootstrap token es de un solo uso, así que el Agent espera a que el enrollment termine (con el mismo límite del timeout de drain) en vez de salir con el token gastado y la identidad todavía sin guardar.

Un proceso que quedara en pie sin servir seguiría healthy en el liveness, porque su event loop sigue latiendo. Por eso el Agent prefiere salir antes que degradarse en silencio, y cuenta con el supervisor para levantar un reemplazo limpio.