Despliega desde CI con un token de API
Todas las guías de esta sección hacen las mismas cuatro cosas, en cualquier sistema de CI:
- construir una imagen y subirla a un registro, con una etiqueta inmutable por commit;
- decirle a Zaroz que ejecute esa imagen (
PUT /service-instances/{id}/source); - iniciar un despliegue y esperar a que termine (
POST /service-instances/{id}/deployments); - hacer fallar el trabajo si el despliegue falló y volver a poner la imagen anterior.
Los pasos 2 a 4 son un pequeño script, zaroz-deploy.sh. Las guías de GitHub, GitLab y Forgejo solo se diferencian en cómo construyen, dónde viven los secretos y cómo evitan que dos despliegues corran a la vez.
| Sistema de CI | Guía |
|---|---|
| GitHub Actions | GitHub Actions |
| GitLab CI | GitLab CI |
| Forgejo Actions y Gitea Actions | Forgejo y Gitea Actions |
| cualquier otro (Jenkins, Drone, un cron en tu servidor) | Shell genérico |
Crea un token que solo pueda desplegar
CI nunca debería tener un token que pueda leer tus facturas o borrar tu cuenta. Dale un token limitado a una instancia de servicio.
services.deploy es el permiso de despliegue. Permite exactamente dos escrituras sobre un servicio: PUT /service-instances/{id}/source y POST /service-instances/{id}/deployments. No lee nada, no cambia variables de entorno, copias de seguridad, archivos ni el cortafuegos, no inicia, detiene ni reinicia el servicio (services.power), no abre terminal y no toca la facturación ni los miembros. Añade services.read para que el trabajo pueda leer el source y esperar a que termine el despliegue. Qué token usar depende de lo estrecho que lo necesites:
- Un token personal (
POST /me/api-tokens, abajo) se puede limitar a una instancia de servicio. Actúa como la persona que lo creó y para crearlo hace falta una sesión completa: un token de API no puede crear otro. - Un token de organización (
POST /organizations/{id}/api-tokens) pertenece a la organización y puede sobrevivir a quien lo creó ("lifetime": "organization_owned"), pero cada permiso se limita a toda la organización, nunca a un solo servicio.GET /organizations/{id}/api-tokens/grantable-capabilitieslista lo que puedes poner en él. Úsalo para un pipeline de equipo que despliega varios servicios.
curl
Code
TypeScript
Code
Python
Code
resource_ides el id de la instancia de servicio, el mismo UUID que aparece en la URL del Workload en la consola.- Dale al token un
expires_aty pon un recordatorio para rotarlo. Un token personal se revoca conDELETE /me/api-tokens/{token_id}. - El secreto (
zaroz_...) se muestra una sola vez. Guárdalo directamente en el almacén de secretos de tu CI. Nunca lo pongas en el repositorio, en archivos.envque se suban ni en la imagen. - Mantén el secreto fuera de los argumentos de la línea de comandos, que cualquier usuario de un runner compartido puede leer con
ps. Pásalo como variable de entorno desde el almacén de secretos de CI, como hacen los flujos; el script se lo entrega acurlpor la entrada estándar. - Crea un token por servicio y por entorno (staging, producción), de modo que revocar uno no detenga a los demás.
Un token personal actúa como la persona que lo creó: si esa persona deja la organización o pierde el acceso al servicio, el token deja de funcionar. Para un equipo, prefiere un token de organización con lifetime: "organization_owned" (sobrevive a quien lo creó, pero cubre todos los servicios de la organización):
Code
Para crearlo hace falta ser Owner o Admin. Si omites lifetime, el token se revoca cuando termina tu pertenencia.
Qué hace el token en cada paso
| Paso | Petición | Permiso |
|---|---|---|
| Leer qué se ejecuta ahora | GET /service-instances/{id}/source | services.read |
| Elegir la imagen | PUT /service-instances/{id}/source | services.deploy |
| Desplegar | POST /service-instances/{id}/deployments | services.deploy |
| Esperar y comprobar | GET /service-instances/{id}/deployments | services.read |
PUT /source no despliega: solo guarda lo que bajará el siguiente despliegue. POST /deployments no lleva cuerpo y despliega lo guardado, así que no hay forma de desplegar algo que no se guardó antes.
Despliegue, éxito y reversión
Un despliegue tiene un status (cómo terminó la operación) y un outcome (succeeded o failed, con un failure_reason como cluster_rejected o subscription_not_active). succeeded significa que el despliegue se aplicó; no dice que los pods nuevos estén sanos. Por eso el script también lee workloads[].status de la misma lista y exige que todos estén en running.
Revertir es desplegar la imagen anterior. El script lee running_image antes de cambiar nada y, si el despliegue nuevo falla, vuelve a guardar esa imagen y la despliega. Con ROLLBACK=0 se desactiva. Un despliegue se rechaza con 409 mientras una restauración, un cambio de tamaño u otro despliegue tiene el servicio, y la respuesta dice cuál y desde cuándo.
Zaroz no vigila un registro por si una etiqueta se mueve (watch_tag siempre es false), así que una canalización que sube latest y no despliega nada nunca actualizará. Usa una etiqueta única por commit, como hacen las guías.
Imágenes privadas
Si la imagen es privada, añade un token de registro de solo lectura y pásalo como REGISTRY_USERNAME y REGISTRY_PASSWORD. Zaroz lo guarda, nunca lo devuelve y lo usa para descargar desde dentro del clúster. No debe ser el token que usa tu CI para subir.
Repositorios de ejemplo
Cada ejemplo trae un flujo de despliegue listo para los tres sistemas de CI y se ejecuta de punta a punta contra un proyecto tuyo.
| Repositorio | Qué muestra |
|---|---|
example-scaled-api | una API HTTP con de 1 a 8 unidades autoescaladas detrás de un endpoint |
example-queue-worker | trabajadores que escalan con una cola |
example-game-network | hub, lobbies, duelos y parcelas (Minecraft), fase 2 |
example-job-runner | una unidad por trabajo, iniciada por clave, resultado por evento |
Viven en la organización zaroz-oss, en https://git.zaroz.cloud/zaroz-oss/.
