Configurar el ejecutor de CI remoto

Guía para usar el script que aprovisiona una máquina remota para ejecutar canalizaciones de CI/CD de gitrust a través de SSH + rsync + Dagger.


1. Papel del guión

deployment/setup-remote-ci.sh (disponible en el repositorio fuente de gitrust) prepara un servidor de compilación remoto utilizado por el trabajador de CI de gitrust. Automatiza 6 pasos:

  1. Comprueba la conectividad SSH con el corredor.
  2. Instale Docker (curl https://get.docker.com | sh) si no está
  3. Instala Dagger CLI (curl https://dl.dagger.io/dagger/install.sh | sh) si está ausente
  4. Crea el directorio de trabajo remoto (CI_REMOTE_PATH)
  5. Sincronice el módulo deployment/ci-engine/ (modo CI Easy) mediante rsync -az --delete
  6. Prueba de humo: muestra docker --version y dagger version

El guión es idempotente: se reproduce sin daños, se salta lo que ya existe.


2. Cuándo usarlo

Scénario Besoin de setup-remote-ci.sh ?
Dev local, CI sur la même machine que gitrust (CI_REMOTE_HOST=localhost) Non — Docker et Dagger déjà installés localement, le ci-engine/ est lu depuis deployment/ci-engine/ directement
Prod on-premise, un seul serveur (gitrust + CI colocalisés) Non — idem, un simple curl get.docker.com \| sh suffit sur le serveur gitrust
Prod avec runner CI dédié (machine séparée) OUI — c'est le cas cible de ce script
Prod avec plusieurs instances gitrust partageant un runner OUI — le runner est provisionné une fois, chaque instance pointe dessus
CI dans Kubernetes / Nomad / runner managé cloud Non — ce script est pensé pour une VM Debian/Ubuntu classique

3. Arquitectura de destino

+---------------------+        SSH + rsync        +-----------------------+
|  Gitrust (web+SSH)  |---------------------------|  CI Runner (distant)  |
|  <your-server-ip>   |  CI_REMOTE_HOST/USER/KEY  |  <ci-runner-ip>       |
|                     |                           |                       |
|  Worker CI Tokio    |   push .gitrust-ci.yml    |  /opt/gitrust-ci/     |
|  (dans gitrust.bin) |   + code source checkout  |   ├── ci-engine/      |
|                     |                           |   └── workspaces/     |
|                     |   dagger call ...         |                       |
|                     |                           |  Docker + Dagger CLI  |
+---------------------+                           +-----------------------+

El trabajador de CI de gitrust (tarea de Tokio en el binario principal) no ejecuta Docker localmente: lo delega al ejecutor a través de SSH. Esto hace posible aislar cargas de trabajo codiciosas de CPU/RAM (compilaciones Rust, Node, Docker) del proceso web de gitrust.


4. Requisitos previos

En la máquina de ejecución (donde lanzamos el script)

Outil Rôle
bash ≥ 4 Interpréteur
ssh, rsync Transport et synchro
ssh-agent chargé ou CI_REMOTE_SSH_KEY défini Auth SSH sans mot de passe interactif (BatchMode=yes)
Fichier .env avec les variables CI_REMOTE_* Config (voir section 5)

En el corredor lejano

Pré-requis Pourquoi
OS Linux récent (Debian 12+, Ubuntu 22.04+) Docker install script compatible
User avec sudo passwordless ou droits docker get.docker.com fait sudo en interne
Clé SSH publique du user local dans ~/.ssh/authorized_keys Auth SSH non-interactive
Réseau sortant autorisé vers get.docker.com et dl.dagger.io Installation des binaires
Au minimum ~5 Go libres dans CI_REMOTE_PATH Images Docker + workspaces

5. Variables de entorno esperadas (el .env)

El script genera un archivo .env cuya ruta se pasa como argumento, o por defecto ../.env (relativo al script, por lo tanto, <project_root>/.env).

Tabla de variables

Variable Obligatoire Défaut Description
CI_REMOTE_HOST OUI Hostname ou IP du runner (ex: ci-runner.internal)
CI_REMOTE_USER non $(whoami) (user courant) Compte SSH sur le runner
CI_REMOTE_SSH_PORT non 22 Port SSH du runner
CI_REMOTE_PATH non /opt/gitrust-ci Répertoire de travail distant (créé par le script)
CI_REMOTE_SSH_KEY non — (ssh-agent) Chemin d'une clé privée SSH spécifique

Estas variables son iguales que las leídas por gitrust en tiempo de ejecución. La centralización en .env evita discrepancias entre el aprovisionamiento y el tiempo de ejecución.

Ejemplo mínimo de .env (corredor dedicado)

# --- CI runner distant ---
CI_REMOTE_HOST=<ci-runner-ip>
CI_REMOTE_USER=ci-runner
CI_REMOTE_SSH_PORT=22
CI_REMOTE_PATH=/opt/gitrust-ci
CI_REMOTE_SSH_KEY=/home/gitrust/.ssh/ci_runner_ed25519

Ejemplo completo de .env coexistiendo con la configuración de gitrust

DATABASE_URL=postgres://...
JWT_SECRET=...
# ... (voir .env.example pour le reste)

# --- CI/CD (lu par gitrust ET par setup-remote-ci.sh) ---
CI_ENABLED=true
CI_MAX_CONCURRENT=4
CI_REMOTE_HOST=ci-runner.internal
CI_REMOTE_USER=ci-runner
CI_REMOTE_PATH=/opt/gitrust-ci
CI_REMOTE_SSH_KEY=/opt/gitrust/data/ci_runner_key

Caso “corredor local” (no es necesario el guión)

CI_REMOTE_HOST=localhost
# Les autres CI_REMOTE_* sont ignorés

En este caso, instale Docker y Dagger directamente en la máquina gitrust, copie deployment/ci-engine/ a CI_ENGINE_PATH (predeterminado /opt/gitrust/ci-engine) y continúe. No ejecute setup-remote-ci.sh con CI_REMOTE_HOST=localhost.


6. uso

Desde la raíz del proyecto (predeterminado)

cd /chemin/vers/gitrust

# .env a la racine (défaut) :
./deployment/setup-remote-ci.sh

Con un .env explícito

./deployment/setup-remote-ci.sh /chemin/vers/mon.env
# Utile si vous avez .env.production, .env.staging, etc.
./deployment/setup-remote-ci.sh .env.production

Salida esperada

==> Configuration :
    Serveur  : ci-runner@<ci-runner-ip>
    Port SSH : 22
    Chemin   : /opt/gitrust-ci

==> [1/6] Vérification de la connectivité SSH...
SSH OK
    OK
==> [2/6] Vérification de Docker...
    Docker déjà installé
==> [3/6] Vérification de Dagger CLI...
    Installation de Dagger CLI...
    Dagger installé
==> [4/6] Création du répertoire distant...
    /opt/gitrust-ci créé
==> [5/6] Synchronisation du ci-engine...
sending incremental file list
ci-engine/
ci-engine/profiles/
...
    ci-engine synchronisé vers /opt/gitrust-ci/ci-engine/
==> [6/6] Smoke test...
    Versions distantes :
Docker version 28.0.1, build abcd123
dagger v0.19.2 (linux/amd64)

==> Setup terminé. Le serveur ci-runner@<ci-runner-ip> est prêt pour l'exécution CI.
    Pensez à configurer CI_EXECUTION_MODE=remote dans votre .env

7. Qué se encuentra en el corredor

Después de una ejecución exitosa:

/opt/gitrust-ci/                    <- CI_REMOTE_PATH
└── ci-engine/                      <- synchronisé depuis deployment/ci-engine/
    ├── README.md
    └── profiles/                   <- templates par stack (Python, Node, Rust, ...)

Plus, installés globalement : - /usr/bin/docker (o equivalente) + socket /var/run/docker.sock - /usr/local/bin/daga

Los espacios de trabajo de canalización (pagos temporales) son creados por el trabajador de CI de gitrust en tiempo de ejecución en CI_WORKSPACE_PATH (predeterminado /tmp/gitrust-ci) — no mediante este script.


8. Comprobaciones posteriores a la configuración

De la máquina gitrust

# Source le .env
set -a; source .env.production; set +a

# 1. SSH direct (doit passer sans prompt)
ssh -p ${CI_REMOTE_SSH_PORT:-22} \
    ${CI_REMOTE_SSH_KEY:+-i $CI_REMOTE_SSH_KEY} \
    $CI_REMOTE_USER@$CI_REMOTE_HOST 'docker info && dagger version'

# 2. Rsync round-trip (lecture/écriture sur CI_REMOTE_PATH)
echo "test" | ssh $CI_REMOTE_USER@$CI_REMOTE_HOST \
    "cat > $CI_REMOTE_PATH/.gitrust-test && cat $CI_REMOTE_PATH/.gitrust-test && rm $CI_REMOTE_PATH/.gitrust-test"
# Attendu : "test"

Tubería de prueba a través de gitrust

Impulsando un repositorio con un mínimo .gitrust-ci.yml:

# .gitrust-ci.yml
version: 1
pipeline:
  - name: smoke
    image: alpine:3
    run: echo "CI runner OK"

Luego, en la interfaz de usuario de gitrust: pestaña "Pipelines" → la canalización debe pasar al estado "éxito".


9. Actualización después de la modificación de ci-engine/

El ci-engine/ sincronizado no está “vinculado en vivo”: reproduzca el script después de modificarlo en el lado fuente.

# Modifier deployment/ci-engine/profiles/*.py ou similaire
./deployment/setup-remote-ci.sh
# Les étapes 2-3 sont skip (déjà installés), seule l'étape 5 refait le rsync

rsync -az --delete elimina archivos del lado del ejecutor que ya no existen localmente: garantiza la coherencia.


10. Solución de problemas

Symptôme Cause probable Fix
ERREUR: fichier .env introuvable .env absent ou chemin incorrect cp .env.example .env && $EDITOR .env ou passer le chemin : ./setup-remote-ci.sh /path/to/.env
ERREUR: CI_REMOTE_HOST non défini Variable commentée ou absente Décommenter CI_REMOTE_HOST=... dans le .env
ERREUR: impossible de se connecter SSH bloqué, mauvais user, clé non autorisée Tester manuellement : ssh -v -p X user@host ; vérifier ~/.ssh/authorized_keys sur le runner
Permission denied (publickey) BatchMode=yes interdit les prompts, clé non chargée ssh-add ~/.ssh/ci_runner_ed25519 ou définir CI_REMOTE_SSH_KEY=/path/to/key
sudo: a password is required pendant l'install Docker User sans NOPASSWD sudo Ajouter le user au sudoers : ci-runner ALL=(ALL) NOPASSWD:ALL (runner uniquement)
curl: (7) Failed to connect to get.docker.com Réseau sortant du runner bloqué Whitelist get.docker.com et dl.dagger.io, ou pré-installer Docker + Dagger manuellement
ATTENTION: ... ci-engine introuvable Lancé hors du repo gitrust cd dans la racine du projet avant de lancer
Pipeline reste queued indéfiniment Worker CI ne trouve pas le runner Vérifier CI_EXECUTION_MODE=remote dans .env gitrust + logs : journalctl -u gitrust \| grep -i 'ci\|dagger'
dagger: command not found au smoke test $PATH du user SSH ne contient pas /usr/local/bin echo 'export PATH=$PATH:/usr/local/bin' >> ~/.bashrc sur le runner, ou CI_DAGGER_BIN=/usr/local/bin/dagger côté gitrust

11. Seguridad

  • El ejecutor de CI ejecuta código arbitrario procedente de repositorios alojados. Nunca lo coloque con secretos confidenciales (prod PG, claves de producción).
  • Aislar red: bloquear el acceso saliente desde el corredor a la LAN privada (solo es necesario el acceso a Internet para "docker pull").
  • Limite sudo NOPASSWD al mínimo estricto en el corredor (idealmente: solo para los comandos docker y apt).
  • Rotación regular de la clave SSH CI_REMOTE_SSH_KEY. Revocarlo en ~/.ssh/authorized_keys en el lado del corredor en caso de sospecha.
  • El corredor no debe poder conectarse vía SSH a la máquina gitrust (unidireccional).