GitOps & CI/CD

Werf

Outil GitOps full-stack Flant - build d'images Stapel/Dockerfile, push registry, deploy Helm sur Kubernetes dans un workflow CI unifié. Apache 2.0.

Werf est un outil CLI développé par Flant (Deckhouse) qui unifie le cycle complet build-push-deploy dans une seule commande. Il construit les images Docker (via Dockerfile standard ou son builder Stapel avec couches de cache avancées), les tague selon la stratégie content-based (hash du contenu), les push vers le registry, puis déploie via Helm sur Kubernetes - le tout avec une gestion automatique du nettoyage des images obsolètes dans le registry. Werf s'intègre directement dans les pipelines CI existants (GitLab CI, GitHub Actions, Jenkins).


Informations essentielles

Origine : Flant (Deckhouse, Russie)  ·  Licence : Apache 2.0  ·  Architectures : x86_64, ARM64

Liens : Site officiel  ·  Documentation  ·  GitHub  ·  Releases

Support : Projet actif, maintenu par Flant/Deckhouse. Utilisé en production par Flant et leurs clients.

Stack par défaut

ComposantValeur
BuildStapel (builder custom) ou Dockerfile standard
Tags imagesContent-based (hash du contenu - reproductible)
DeployHelm 3 intégré
Configwerf.yaml (définition des images)
NettoyagePurge automatique des images obsolètes en registry
CIGitLab CI, GitHub Actions, Jenkins, CircleCI

Prérequis

RessourceValeur
DockerEngine ou Buildah pour le build
KubernetesConfiguré avec kubeconfig pour le deploy
RegistryDocker Hub, GHCR, ECR, registry privée
GitDépôt Git (werf s'appuie sur l'historique Git)

Installation

# Script d'installation officiel (installe la version stable)
curl -sSL https://werf.io/install.sh | bash -s -- --version 2 --channel stable

# Recharger le shell
source ~/.bashrc   # ou ~/.zshrc

werf version

Alternative - téléchargement direct

WERF_VERSION=$(curl -s "https://api.github.com/repos/werf/werf/releases/latest" \
  | grep '"tag_name"' | sed 's/.*"v\([^"]*\)".*/\1/')
curl -Lo werf "https://github.com/werf/werf/releases/download/v${WERF_VERSION}/werf-linux-amd64-v${WERF_VERSION}"
chmod +x werf && sudo mv werf /usr/local/bin/

Configuration - werf.yaml

Le fichier werf.yaml à la racine du projet définit les images à construire :

Avec Dockerfile

# werf.yaml
project: my-app
configVersion: 1

image: backend
dockerfile: Dockerfile
context: .

---
image: frontend
dockerfile: frontend/Dockerfile
context: frontend/

Avec le builder Stapel (cache avancé)

# werf.yaml
project: my-app
configVersion: 1

image: backend
from: golang:1.22-alpine
git:
  - add: /
    to: /app
    stageDependencies:
      install:
        - go.sum
        - go.mod
      setup:
        - "**/*.go"
shell:
  install:
    - cd /app && go mod download
  setup:
    - cd /app && go build -o /app/server ./cmd/server
docker:
  EXPOSE: "8080"
  CMD: ["/app/server"]

Commandes principales

Build uniquement

# Builder toutes les images définies dans werf.yaml
werf build

# Builder avec push vers le registry
werf build --repo ghcr.io/org/my-app

Deploy (build + push + helm)

# Build, push et déployer en production
werf converge \
  --repo ghcr.io/org/my-app \
  --env production

# Werf utilise le chart Helm dans le dossier .helm/
# La variable .Values.werf.image.<name> contient le tag généré automatiquement

Structure du projet avec Helm

my-app/
├── werf.yaml           # Définition des images
├── .helm/              # Chart Helm
│   ├── Chart.yaml
│   ├── templates/
│   │   ├── deployment.yaml
│   │   └── service.yaml
│   └── values.yaml
└── Dockerfile
# .helm/templates/deployment.yaml
spec:
  template:
    spec:
      containers:
        - name: backend
          image: {{ .Values.werf.image.backend }}   # Tag injecté par werf

Intégration CI/CD

GitLab CI

# .gitlab-ci.yml
include:
  - project: werf/werf
    file: /ci/templates/.gitlab-ci-simple.yaml

variables:
  WERF_ENV: production
  WERF_REPO: $CI_REGISTRY_IMAGE

GitHub Actions

# .github/workflows/deploy.yml
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0           # Requis par werf (historique Git complet)

      - name: Install werf
        uses: werf/actions/install@v2

      - name: Login registry
        run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin

      - name: Converge
        run: |
          werf converge \
            --repo ghcr.io/${{ github.repository }} \
            --env production
        env:
          WERF_KUBECONFIG_BASE64: ${{ secrets.KUBECONFIG_BASE64 }}

Nettoyage du registry

# Analyser les images à supprimer (dry-run)
werf cleanup --repo ghcr.io/org/my-app --dry-run

# Purger les images non référencées par les branches/tags actifs
werf cleanup --repo ghcr.io/org/my-app

Mise à jour

# Réexécuter le script d'installation
curl -sSL https://werf.io/install.sh | bash -s -- --version 2 --channel stable

Troubleshooting

# Vérifier la configuration werf.yaml
werf config list

# Lister les images buildées
werf build --report-path=report.json && cat report.json

# Voir le plan Helm avant deploy
werf render --repo ghcr.io/org/my-app --env production

# Logs détaillés
werf converge --repo ghcr.io/org/my-app --env production --log-color-mode=on --log-terminal-width=200

# Problème de cache : purger le cache local
werf purge

Ressources

Newsletter · 2 000+ abonnés

Reste au courant de ce qui bouge en prod

RudeOps veille devops hebdo, droit au but.

Gratuit · Sans spam · Désinscription en un clic