# Despliega desde GitLab CI

Requisitos: un Workload en marcha, el id de su instancia de servicio, el [token de despliegue](/es/guides/ci/overview#crea-un-token-que-solo-pueda-desplegar) y [`zaroz-deploy.sh`](/es/guides/ci/shell) en el repositorio como `deploy/zaroz-deploy.sh`.

## Variables

En **Settings > CI/CD > Variables**:

| Clave | Ajustes |
|---|---|
| `ZAROZ_TOKEN` | el token `zaroz_...`. **Masked** y **Protected**, para que solo lo lean las canalizaciones de ramas protegidas (`main`) |
| `ZAROZ_SERVICE` | el UUID de la instancia de servicio |
| `CI_DEPLOY_USER`, `CI_DEPLOY_PASSWORD` | solo para una imagen privada. Crea un **deploy token** con solo `read_registry` (Settings > Repository > Deploy tokens) y GitLab rellena estas dos variables en los trabajos automáticamente cuando se llama `gitlab+deploy-token` |

## La canalización

```yaml
# .gitlab-ci.yml
stages: [build, deploy]

variables:
  IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA   # one immutable tag per commit

build:
  stage: build
  image: docker:27
  services: [docker:27-dind]
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
    - docker build -t "$IMAGE" .
    - docker push "$IMAGE"

deploy:
  stage: deploy
  image: alpine:3.20
  needs: [build]
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  # Never two deployments at once, and never an older commit over a newer one.
  resource_group: production
  environment: production
  before_script:
    - apk add --no-cache curl jq
  script:
    - sh deploy/zaroz-deploy.sh
  variables:
    # ZAROZ_TOKEN and ZAROZ_SERVICE: Settings > CI/CD > Variables
    # (ZAROZ_TOKEN masked and protected). A private registry also needs these two,
    # for a deploy token with read_registry:
    REGISTRY_USERNAME: $CI_DEPLOY_USER
    REGISTRY_PASSWORD: $CI_DEPLOY_PASSWORD
```


Cómo se comporta:

- `resource_group: production` hace que GitLab ejecute **un** trabajo de despliegue a la vez y en orden, así un commit antiguo nunca aterriza sobre uno más nuevo.
- `needs: [build]` inicia el despliegue en cuanto se sube la imagen.
- El trabajo de despliegue falla si el despliegue falla, tras volver a poner la imagen anterior. La entrada `environment: production` te da un historial de despliegues en GitLab junto al de Zaroz.
- Añade `when: manual` a las `rules` del trabajo para tener un despliegue a producción con un botón.

## Revertir

En **Deploy > Environments > production**, pulsa el botón de reversión de un despliegue anterior: GitLab vuelve a ejecutar el trabajo de ese commit, que despliega la imagen de ese commit. A mano: `IMAGE=$CI_REGISTRY_IMAGE:<sha antiguo> sh deploy/zaroz-deploy.sh`.

## GitLab autoalojado

No cambia nada salvo el host del registro, que ya está en `CI_REGISTRY_IMAGE`. Zaroz descarga la imagen desde dentro de su clúster, así que el registro debe ser accesible desde internet (o permitir las direcciones de salida de Zaroz).
