Ce guide installe GARM v0.2.0 (nightly) sur une VM Ubuntu 24.04 qui fait déjà tourner Gitea. À la fin, GARM sera actif en tant que service systemd, le provider LXD sera enregistré, et l’API répondra sur le port 9997.
GARM (GitHub/Gitea Actions Runner Manager) peut être installé :
- De la même façon que Gitea : un seul binaire, un service systemd
- Sans Docker en production (Docker sert uniquement à extraire le binaire depuis l’image nightly)
Prérequis
Section intitulée « Prérequis »- VM Ubuntu 24.04 avec 4 Go de RAM, 30 Go de disque
- Gitea installé et accessible (voir Installer Gitea)
- Docker installé sur votre machine locale (pas sur la VM)
- Accès SSH avec
sudosur la VM
Étape 1 — Extraire les binaires GARM depuis Docker (machine locale)
Section intitulée « Étape 1 — Extraire les binaires GARM depuis Docker (machine locale) »GARM ne publie pas encore de releases binaires pour la branche nightly. La méthode la plus simple est d’extraire les binaires depuis l’image Docker officielle.
Sur votre machine locale :
# 1. Télécharger l'image nightlydocker pull ghcr.io/cloudbase/garm:nightly
# 2. Créer un conteneur sans le démarrerCONTAINER_ID=$(docker create ghcr.io/cloudbase/garm:nightly)
# 3. Extraire les 3 binairesdocker cp "${CONTAINER_ID}:/usr/bin/garm" /tmp/garmdocker cp "${CONTAINER_ID}:/usr/bin/garm-cli" /tmp/garm-clidocker cp "${CONTAINER_ID}:/usr/bin/garm-provider-lxd" /tmp/garm-provider-lxd
# 4. Supprimer le conteneur temporairedocker rm "${CONTAINER_ID}"
# 5. Vérifier la version extraite/tmp/garm --version# → v0.2.0-alpha-274-g8ff29e19 (ou version plus récente)Étape 2 — Copier les binaires sur la VM
Section intitulée « Étape 2 — Copier les binaires sur la VM »VM_IP="192.168.122.52" # Adapter à votre VM
# Copier les 3 binairesscp /tmp/garm /tmp/garm-cli /tmp/garm-provider-lxd lab@${VM_IP}:/tmp/
# Se connecter à la VMssh lab@${VM_IP}
# Installer les binairessudo install -o root -g root -m 755 /tmp/garm /usr/local/bin/garmsudo install -o root -g root -m 755 /tmp/garm-cli /usr/local/bin/garm-cli
# Installer le provider LXD dans un répertoire dédiésudo mkdir -p /opt/garm/providers.dsudo install -o root -g root -m 755 /tmp/garm-provider-lxd /opt/garm/providers.d/garm-provider-lxd
# Vérifiergarm --version# → v0.2.0-alpha-274-g8ff29e19Étape 3 — Installer LXD (snap)
Section intitulée « Étape 3 — Installer LXD (snap) »LXD est le provider local qui va créer les conteneurs runners. Sur Ubuntu 24.04, il s’installe via snap.
# Installer LXD via snap (version LTS 5.x)sudo snap install lxd
# Initialiser LXD avec les paramètres par défautsudo lxd init --auto
# Vérifier que le socket Unix est présenttest -S /var/snap/lxd/common/lxd/unix.socket && echo "LXD OK"
# Ajouter votre utilisateur au groupe lxd (pour utiliser lxc sans sudo)sudo usermod -aG lxd ${USER}newgrp lxd
# Vérifier la versionlxd --version# → 5.21.4 LTSÉtape 4 — Créer l’utilisateur système GARM
Section intitulée « Étape 4 — Créer l’utilisateur système GARM »GARM tourne en tant qu’utilisateur dédié, sans shell, membre du groupe lxd pour accéder au
socket LXD.
sudo useradd \ --system \ --no-create-home \ --shell /usr/sbin/nologin \ --groups lxd \ garm
# Vérifierid garm# → uid=997(garm) gid=997(garm) groups=997(garm),988(lxd)Étape 5 — Créer les répertoires et la configuration
Section intitulée « Étape 5 — Créer les répertoires et la configuration »-
Créer les répertoires :
Fenêtre de terminal sudo mkdir -p /etc/garm /var/lib/garmsudo chown garm:garm /var/lib/garm && sudo chmod 750 /var/lib/garmsudo chown root:garm /etc/garm && sudo chmod 750 /etc/garm -
Créer
/etc/garm/config.toml:Fenêtre de terminal sudo tee /etc/garm/config.toml << 'EOF'[default]listen_address = "0.0.0.0"listen_port = 9997# Clé AES-256 — doit faire exactement 32 caractèrespassphrase = "Rk7mPvXhQdNwYeWpKsLuJ3TbFcGnAz12"[jwt_auth]secret = "garm-lab-jwt-secret-change-in-prod"time_to_live = "24h"[apiserver]bind = "0.0.0.0"port = 9997[apiserver.cors]allow_origins = ["*"][logging]log_level = "info"log_format = "text"[database]backend = "sqlite3"passphrase = "Rk7mPvXhQdNwYeWpKsLuJ3TbFcGnAz12"[database.sqlite3]db_file = "/var/lib/garm/garm.db"[[provider]]name = "lxd_local"description = "LXD local"provider_type = "external"[provider.external]provider_executable = "/opt/garm/providers.d/garm-provider-lxd"config_file = "/etc/garm/garm-provider-lxd.toml"EOF -
Créer
/etc/garm/garm-provider-lxd.toml:Fenêtre de terminal sudo tee /etc/garm/garm-provider-lxd.toml << 'EOF'[lxd]# Socket Unix local — pas de TLS nécessaireunix_socket = "/var/snap/lxd/common/lxd/unix.socket"instance_type = "container"profile_name = "default"image_timeout = 300EOF -
Fixer les permissions :
Fenêtre de terminal sudo chown garm:garm /etc/garm/config.toml /etc/garm/garm-provider-lxd.tomlsudo chmod 640 /etc/garm/config.toml /etc/garm/garm-provider-lxd.toml
Étape 6 — Créer le service systemd
Section intitulée « Étape 6 — Créer le service systemd »sudo tee /etc/systemd/system/garm.service << 'EOF'[Unit]Description=GARM — GitHub/Gitea Actions Runner ManagerAfter=network.target
[Service]Type=simpleUser=garmGroup=garmWorkingDirectory=/var/lib/garmExecStart=/usr/local/bin/garm -config /etc/garm/config.tomlRestart=on-failureRestartSec=5sStandardOutput=journalStandardError=journalNoNewPrivileges=trueProtectSystem=strictReadWritePaths=/var/lib/garm /etc/garmReadOnlyPaths=/opt/garm
[Install]WantedBy=multi-user.targetEOF
sudo systemctl daemon-reloadsudo systemctl enable garmsudo systemctl start garmValidation
Section intitulée « Validation »# Vérifier que le service tournesudo systemctl status garm --no-pager
# Vérifier que le socket est en écoutess -tlnp | grep 9997# → LISTEN 0 0.0.0.0:9997
# Tester l'API (401 = normal, GARM répond mais requiert une auth)curl -s -o /dev/null -w "%{http_code}" http://localhost:9997/api/v1/# → 401Étape 7 — Initialiser le compte admin
Section intitulée « Étape 7 — Initialiser le compte admin »GARM ne crée pas de compte admin automatiquement. La première commande garm-cli init crée
l’administrateur et configure le profil local de garm-cli. Cette opération est à faire une
seule fois sur chaque installation.
garm-cli init \ --name "mon-garm" \ --url "http://localhost:9997" \ --username "garmadmin" \ --password "MotDePasseForte2026!" \ --email "admin@garm.lab"Vérification :
# Afficher les infos du contrôleurgarm-cli controller show# → Controller ID, version, URLs...
# Lister les providersgarm-cli provider list# → lxd_localDépannage courant
Section intitulée « Dépannage courant »| Symptôme | Cause | Solution |
|---|---|---|
passphrase must be…32 characters | Passphrase trop courte | Compter exactement 32 chars dans config.toml |
permission denied sur le socket LXD | L’user garm n’est pas dans le groupe lxd | sudo usermod -aG lxd garm + restart |
| Port 9997 déjà utilisé | Autre processus | `ss -tlnp |
garm-cli: token expired | Le token JWT a expiré | garm-cli profile login -u admin -p pass |
Service en failed au démarrage | Erreur config | journalctl -u garm -n 20 pour voir l’erreur |
À retenir
Section intitulée « À retenir »- Les binaires GARM nightly s’extraient depuis l’image Docker
ghcr.io/cloudbase/garm:nightly. - La passphrase dans
config.tomldoit faire exactement 32 caractères (AES-256). - L’user
garmdoit être dans le groupelxdpour accéder au socket Unix de LXD. garm-cli initest une opération unique : elle crée l’admin et configure le profil local.- Une réponse HTTP 401 de l’API confirme que GARM tourne correctement.