Configurar o executor de CI remoto

Guia para usar o script que provisiona uma máquina remota para executar pipelines gitrust CI/CD via SSH + rsync + Dagger.


1. Papel do roteiro

deployment/setup-remote-ci.sh (disponível no repositório de origem gitrust) prepara um servidor de construção remoto usado pelo trabalhador de CI gitrust. Ele automatiza 6 etapas:

  1. Verifica a conectividade SSH com o executor
  2. Instale Docker (curl https://get.docker.com | sh) se estiver ausente
  3. Instala Dagger CLI (curl https://dl.dagger.io/dagger/install.sh | sh) se ausente
  4. Cria o diretório de trabalho remoto (CI_REMOTE_PATH)
  5. Sincronize o módulo deployment/ci-engine/ (modo CI Easy) via rsync -az --delete
  6. Teste de fumaça: exibe docker --version e dagger version

O script é idempotente: reproduz sem danos, pula o que já existe.


2. Quando usar

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. Arquitetura alvo

+---------------------+        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  |
+---------------------+                           +-----------------------+

O trabalhador de CI gitrust (tarefa do Tokio no binário principal) não executa o Docker localmente — ele delega ao executor via SSH. Isso torna possível isolar cargas de trabalho gananciosas de CPU/RAM (compilações Rust, Node, Docker) do processo web gitrust.


4. Pré-requisitos

Na máquina de execução (onde lançamos o 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)

No corredor distante

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. Variáveis ​​de ambiente esperadas (o .env)

O script fonte um arquivo .env cujo caminho é passado como um argumento, ou por padrão ../.env (relativo ao script, portanto <project_root>/.env).

Tabela de variáveis

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

Essas variáveis ​​são mesmas aquelas lidas pelo gitrust em tempo de execução. Centralizar em .env evita discrepâncias entre provisionamento e tempo de execução.

Exemplo mínimo de .env (executor 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

Exemplo completo de .env coexistindo com a configuração do 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 “Executor local” (sem necessidade de script)

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

Neste caso, instale o Docker e o Dagger diretamente na máquina gitrust, copie deployment/ci-engine/ para CI_ENGINE_PATH (padrão /opt/gitrust/ci-engine) e siga em frente. Não execute setup-remote-ci.sh com CI_REMOTE_HOST=localhost.


6. Uso

Da raiz do projeto (padrão)

cd /chemin/vers/gitrust

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

Com um .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

Resultado esperado

==> 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. O que é encontrado no corredor

Após execução bem-sucedida:

/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 (ou equivalente) + soquete /var/run/docker.sock - /usr/local/bin/dagger

Espaços de trabalho de pipeline (checkouts temporários) são criados pelo trabalhador de CI gitrust em tempo de execução em CI_WORKSPACE_PATH (padrão /tmp/gitrust-ci) — não por este script.


8. Verificações pós-configuração

Da 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"

Pipeline de teste via gitrust

Enviando um repositório com um .gitrust-ci.yml mínimo:

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

Em seguida, na UI do gitrust: guia Pipelines → o pipeline deve ir para o status de sucesso.


9. Atualização após modificação do ci-engine/

O ci-engine/ sincronizado não está “ligado ao vivo”: reproduza o script após a modificação no lado da fonte.

# 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 exclui arquivos do lado do executor que não existem mais localmente — garante consistência.


10. Solução 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. Segurança

  • O executor de CI executa código arbitrário proveniente de repositórios hospedados. Nunca coloque-o com segredos confidenciais (prod PG, prod keys).
  • Isolar rede: bloquear o acesso de saída do runner para a LAN privada (apenas o acesso à Internet para docker pull é necessário).
  • Limite sudo NOPASSWD ao mínimo estrito no executor (idealmente: apenas para os comandos docker e apt).
  • Rotação regular da chave SSH CI_REMOTE_SSH_KEY. Revogue-o em ~/.ssh/authorized_keys no lado do executor em caso de suspeita.
  • O executor não deve ser capaz de se conectar via SSH à máquina gitrust (unidirecional).