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
| Composant | Valeur |
|---|---|
| Build | Stapel (builder custom) ou Dockerfile standard |
| Tags images | Content-based (hash du contenu - reproductible) |
| Deploy | Helm 3 intégré |
| Config | werf.yaml (définition des images) |
| Nettoyage | Purge automatique des images obsolètes en registry |
| CI | GitLab CI, GitHub Actions, Jenkins, CircleCI |
Prérequis
| Ressource | Valeur |
|---|---|
| Docker | Engine ou Buildah pour le build |
| Kubernetes | Configuré avec kubeconfig pour le deploy |
| Registry | Docker Hub, GHCR, ECR, registry privée |
| Git | Dé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
- Site officiel : https://werf.io
- Documentation : https://werf.io/docs/
- GitHub : https://github.com/werf/werf
- Guides CI : https://werf.io/docs/reference/ci_cd_workflow_overview.html
- Releases : https://github.com/werf/werf/releases