Aller au contenu
CI/CD & Automatisation medium

Installation de Dagger et premier pipeline Python

11 min de lecture

logo dagger

Ce guide vous permet d’installer Dagger et d’exécuter votre premier pipeline Python en 15 minutes. Vous allez créer un projet minimal, initialiser Dagger et lancer deux fonctions : une qui affiche un message et une qui recherche du texte dans vos fichiers sources.

Prérequis : Docker (ou Podman) installé et un terminal Linux ou macOS.

À la fin de ce guide, vous aurez :

  1. Dagger CLI installé (version 0.19.11)
  2. Un projet Python minimal avec du code source
  3. Un module Dagger initialisé avec le SDK Python
  4. Deux fonctions pipeline testées et fonctionnelles

Contrairement aux CI traditionnelles où vous devez pousser votre code pour tester un pipeline, Dagger vous permet d’exécuter vos pipelines directement sur votre machine. C’est le principe “local-first” :

ApprocheCI traditionnelleDagger
Test d’un pipelinecommit → push → attendre → lire les logsexécuter directement
Temps de feedback2-10 minutesquelques secondes
Debugajouter des echo partoututiliser votre IDE
Reproductibilité”ça marche en CI”identique partout

Avant de commencer, vérifiez que vous avez :

  1. Docker ou Podman fonctionnel

    Fenêtre de terminal
    docker run hello-world

    Si vous utilisez Podman, activez le socket de compatibilité :

    Fenêtre de terminal
    systemctl --user start podman.socket
  2. Python 3.10 ou supérieur

    Fenêtre de terminal
    python3 --version
    # Python 3.10.x ou supérieur
  3. Un terminal avec accès sudo (pour l’installation)

  1. Téléchargez la dernière version stable

    Fenêtre de terminal
    cd /tmp
    wget https://github.com/dagger/dagger/releases/download/v0.19.11/dagger_v0.19.11_linux_amd64.tar.gz
  2. Extrayez et installez

    Fenêtre de terminal
    tar xzf dagger_v0.19.11_linux_amd64.tar.gz
    sudo mv dagger /usr/local/bin/
    rm dagger_v0.19.11_linux_amd64.tar.gz
  3. Vérifiez l’installation

    Fenêtre de terminal
    dagger version

    Résultat attendu :

    dagger v0.19.11 (image://registry.dagger.io/engine:v0.19.11) linux/amd64

L’autocomplétion facilite la découverte des commandes et options.

Pour Zsh :

Fenêtre de terminal
mkdir -p ~/.zsh/completions
dagger completion zsh > ~/.zsh/completions/_dagger
echo 'fpath=(~/.zsh/completions $fpath)' >> ~/.zshrc
echo 'autoload -Uz compinit && compinit' >> ~/.zshrc
source ~/.zshrc

Pour Bash :

Fenêtre de terminal
mkdir -p ~/.bash/completions
dagger completion bash > ~/.bash/completions/_dagger
echo 'source ~/.bash/completions/_dagger' >> ~/.bashrc
source ~/.bashrc

Avant d’initialiser Dagger, créons un projet Python simple sur lequel travailler. Ce projet servira de base pour tous les labs du Volet 1.

  1. Créez la structure du projet

    Fenêtre de terminal
    mkdir -p hello-dagger/src/hello_dagger
    cd hello-dagger
  2. Créez le fichier pyproject.toml

    pyproject.toml
    [project]
    name = "hello-dagger"
    version = "0.1.0"
    description = "Projet minimal pour apprendre Dagger"
    requires-python = ">=3.10"
    readme = "README.md"
    [build-system]
    requires = ["hatchling"]
    build-backend = "hatchling.build"
  3. Créez le fichier __init__.py

    src/hello_dagger/__init__.py
    """Hello Dagger - Projet minimal pour apprendre Dagger."""
    __version__ = "0.1.0"
  4. Créez le fichier main.py

    src/hello_dagger/main.py
    """Point d'entrée de l'application Hello Dagger."""
    def greet(name: str = "World") -> str:
    """Retourne un message de salutation.
    Args:
    name: Le nom à saluer (défaut: "World")
    Returns:
    Message de salutation formaté
    """
    return f"Hello, {name}!"
    def main() -> None:
    """Fonction principale."""
    print(greet("Dagger"))
    if __name__ == "__main__":
    main()

Structure finale :

  • Répertoirehello-dagger/
    • pyproject.toml
    • Répertoiresrc/
      • Répertoirehello_dagger/
        • __init__.py
        • main.py

Vérification :

Fenêtre de terminal
python3 src/hello_dagger/main.py

Résultat attendu :

Hello, Dagger!

Un “module” Dagger est un ensemble de fonctions pipeline écrites dans un SDK (Python, Go, TypeScript). La commande dagger init génère la structure nécessaire.

  1. Depuis la racine du projet, initialisez Dagger avec le SDK Python

    Fenêtre de terminal
    dagger init --sdk=python --source=./dagger

    Ce que fait cette commande :

    • Crée un fichier dagger.json (configuration du module)
    • Crée un dossier dagger/ avec le code Python du pipeline
    • Génère un fichier uv.lock (dépendances)
  2. Explorez la structure générée

    • Répertoirehello-dagger/
      • dagger.json
      • Répertoiredagger/
        • pyproject.toml
        • Répertoiresrc/
          • Répertoirehello_dagger/
            • main.py
        • Répertoiresdk/
        • uv.lock
      • pyproject.toml
      • Répertoiresrc/
        • Répertoirehello_dagger/
          • __init__.py
          • main.py
  3. Regardez le code généré

    Fenêtre de terminal
    cat dagger/src/hello_dagger/main.py
    import dagger
    from dagger import dag, function, object_type
    @object_type
    class HelloDagger:
    @function
    def container_echo(self, string_arg: str) -> dagger.Container:
    """Returns a container that echoes whatever string argument is provided"""
    return dag.container().from_("alpine:latest").with_exec(["echo", string_arg])
    @function
    async def grep_dir(self, directory_arg: dagger.Directory, pattern: str) -> str:
    """Returns lines that match a pattern in the files of the provided Directory"""
    return await (
    dag.container()
    .from_("alpine:latest")
    .with_mounted_directory("/mnt", directory_arg)
    .with_workdir("/mnt")
    .with_exec(["grep", "-R", pattern, "."])
    .stdout()
    )

Que signifie ce code ?

ÉlémentRôle
@object_typeDéfinit une classe comme module Dagger
@functionExpose une méthode comme fonction appelable via CLI
dag.container()Crée un nouveau conteneur
.from_("alpine:latest")Utilise l’image Alpine comme base
.with_exec([...])Exécute une commande dans le conteneur
.stdout()Récupère la sortie standard

Maintenant que le module est initialisé, testons les deux fonctions générées.

Cette fonction crée un conteneur Alpine et exécute echo avec l’argument fourni.

Fenêtre de terminal
dagger call container-echo --string-arg HelloDagger stdout

Explication de la commande :

  • dagger call : appelle une fonction du module
  • container-echo : nom de la fonction (kebab-case automatique)
  • --string-arg HelloDagger : argument de la fonction
  • stdout : récupère la sortie standard du conteneur

Résultat attendu :

✔ connect 0.3s
✔ load module: . 0.3s
✔ parsing command line arguments 0.0s
✔ helloWorld: HelloDagger! 0.0s
✔ .containerEcho(stringArg: "HelloDagger"): Container! 0.2s
✔ .stdout: String! 0.2s
HelloDagger

Cette fonction monte un répertoire dans un conteneur et recherche un pattern dans les fichiers.

Fenêtre de terminal
dagger call grep-dir --directory-arg=src --pattern=Hello

Résultat attendu :

✔ connect 0.2s
✔ load module: . 0.4s
✔ parsing command line arguments 0.0s
✔ helloWorld: HelloDagger! 0.0s
✔ .grepDir(
┆ directoryArg: Address.directory: Directory!
┆ pattern: "Hello"
): String! 1.5s
./hello_dagger/__init__.py:"""Hello Dagger - Projet minimal pour apprendre Dagger."""
./hello_dagger/main.py:"""Point d'entrée de l'application Hello Dagger."""
./hello_dagger/main.py: return f"Hello, {name}!"

La fonction a trouvé toutes les occurrences de “Hello” dans vos fichiers Python.

Récapitulons ce qui se passe quand vous exécutez dagger call :

  1. Connexion à l’Engine : Dagger se connecte au daemon Docker/Podman
  2. Chargement du module : le code Python de dagger/ est interprété
  3. Parsing des arguments : les options CLI sont validées
  4. Exécution : un conteneur est créé et la commande s’exécute
  5. Cache : le résultat est stocké pour réutilisation

Tout cela se passe localement sur votre machine. Quand vous exécuterez le même pipeline en CI (GitLab, GitHub Actions…), il produira exactement le même résultat.

Le binaire n’est pas dans votre PATH.

Fenêtre de terminal
# Vérifiez où il est installé
ls -la /usr/local/bin/dagger
# Si absent, refaites l'installation
# ou ajoutez le chemin à votre PATH
export PATH=$PATH:/usr/local/bin

Docker n’est pas démarré.

Fenêtre de terminal
# Linux avec systemd
sudo systemctl start docker
# Vérifiez que docker fonctionne
docker run hello-world

Votre utilisateur n’a pas les droits Docker.

Fenêtre de terminal
# Ajoutez-vous au groupe docker
sudo usermod -aG docker $USER
# Déconnectez-vous et reconnectez-vous
# ou utilisez newgrp
newgrp docker

C’est normal lors de la première exécution. Dagger télécharge :

  • L’image de l’Engine (~200 Mo)
  • Le SDK Python et ses dépendances
  • L’image de base (alpine:latest)

Les exécutions suivantes utilisent le cache et sont quasi-instantanées.

  • Dagger CLI s’installe en quelques secondes (télécharger + déplacer)
  • dagger init --sdk=python génère un module avec des fonctions d’exemple
  • dagger call exécute une fonction pipeline depuis le terminal
  • Le cache accélère drastiquement les exécutions répétées
  • Local-first : debug rapide sans pousser de code

Maintenant que Dagger est installé et fonctionnel, vous pouvez :

  • Connexion, async et erreurs — Comprendre le cycle de vie async et gérer les erreurs
  • Module 4 : Container API — Maîtriser la création de conteneurs, l’exécution de commandes et la gestion des variables d’environnement (à venir)

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.