claudient 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +42 -0
- package/CONTEXT.md +58 -0
- package/README.md +165 -0
- package/agents/build-resolvers/de/python-resolver.md +64 -0
- package/agents/build-resolvers/de/typescript-resolver.md +65 -0
- package/agents/build-resolvers/es/python-resolver.md +64 -0
- package/agents/build-resolvers/es/typescript-resolver.md +65 -0
- package/agents/build-resolvers/fr/python-resolver.md +64 -0
- package/agents/build-resolvers/fr/typescript-resolver.md +65 -0
- package/agents/build-resolvers/nl/python-resolver.md +64 -0
- package/agents/build-resolvers/nl/typescript-resolver.md +65 -0
- package/agents/build-resolvers/python-resolver.md +62 -0
- package/agents/build-resolvers/typescript-resolver.md +63 -0
- package/agents/core/architect.md +64 -0
- package/agents/core/code-reviewer.md +78 -0
- package/agents/core/de/architect.md +66 -0
- package/agents/core/de/code-reviewer.md +80 -0
- package/agents/core/de/planner.md +63 -0
- package/agents/core/de/security-reviewer.md +93 -0
- package/agents/core/es/architect.md +66 -0
- package/agents/core/es/code-reviewer.md +80 -0
- package/agents/core/es/planner.md +63 -0
- package/agents/core/es/security-reviewer.md +93 -0
- package/agents/core/fr/architect.md +66 -0
- package/agents/core/fr/code-reviewer.md +80 -0
- package/agents/core/fr/planner.md +63 -0
- package/agents/core/fr/security-reviewer.md +93 -0
- package/agents/core/nl/architect.md +66 -0
- package/agents/core/nl/code-reviewer.md +80 -0
- package/agents/core/nl/planner.md +63 -0
- package/agents/core/nl/security-reviewer.md +93 -0
- package/agents/core/planner.md +61 -0
- package/agents/core/security-reviewer.md +91 -0
- package/guides/agent-orchestration.md +231 -0
- package/guides/de/agent-orchestration.md +174 -0
- package/guides/de/getting-started.md +164 -0
- package/guides/de/hooks-cookbook.md +160 -0
- package/guides/de/memory-management.md +153 -0
- package/guides/de/security.md +180 -0
- package/guides/de/skill-authoring.md +214 -0
- package/guides/de/token-optimization.md +156 -0
- package/guides/es/agent-orchestration.md +174 -0
- package/guides/es/getting-started.md +164 -0
- package/guides/es/hooks-cookbook.md +160 -0
- package/guides/es/memory-management.md +153 -0
- package/guides/es/security.md +180 -0
- package/guides/es/skill-authoring.md +214 -0
- package/guides/es/token-optimization.md +156 -0
- package/guides/fr/agent-orchestration.md +174 -0
- package/guides/fr/getting-started.md +164 -0
- package/guides/fr/hooks-cookbook.md +227 -0
- package/guides/fr/memory-management.md +169 -0
- package/guides/fr/security.md +180 -0
- package/guides/fr/skill-authoring.md +214 -0
- package/guides/fr/token-optimization.md +158 -0
- package/guides/getting-started.md +164 -0
- package/guides/hooks-cookbook.md +423 -0
- package/guides/memory-management.md +192 -0
- package/guides/nl/agent-orchestration.md +174 -0
- package/guides/nl/getting-started.md +164 -0
- package/guides/nl/hooks-cookbook.md +160 -0
- package/guides/nl/memory-management.md +153 -0
- package/guides/nl/security.md +180 -0
- package/guides/nl/skill-authoring.md +214 -0
- package/guides/nl/token-optimization.md +156 -0
- package/guides/security.md +229 -0
- package/guides/skill-authoring.md +226 -0
- package/guides/token-optimization.md +169 -0
- package/hooks/lifecycle/cost-tracker.md +49 -0
- package/hooks/lifecycle/cost-tracker.sh +59 -0
- package/hooks/lifecycle/pre-compact-save.md +56 -0
- package/hooks/lifecycle/pre-compact-save.sh +37 -0
- package/hooks/lifecycle/session-start.md +50 -0
- package/hooks/lifecycle/session-start.sh +47 -0
- package/hooks/post-tool-use/audit-log.md +53 -0
- package/hooks/post-tool-use/audit-log.sh +53 -0
- package/hooks/post-tool-use/prettier.md +53 -0
- package/hooks/post-tool-use/prettier.sh +49 -0
- package/hooks/pre-tool-use/block-dangerous.md +48 -0
- package/hooks/pre-tool-use/block-dangerous.sh +76 -0
- package/hooks/pre-tool-use/git-push-confirm.md +46 -0
- package/hooks/pre-tool-use/git-push-confirm.sh +36 -0
- package/mcp/configs/github.json +11 -0
- package/mcp/configs/postgres.json +11 -0
- package/mcp/de/recommended-servers.md +170 -0
- package/mcp/es/recommended-servers.md +170 -0
- package/mcp/fr/recommended-servers.md +170 -0
- package/mcp/nl/recommended-servers.md +170 -0
- package/mcp/recommended-servers.md +168 -0
- package/package.json +45 -0
- package/prompts/project-starters/de/fastapi-project.md +62 -0
- package/prompts/project-starters/de/nextjs-project.md +82 -0
- package/prompts/project-starters/es/fastapi-project.md +62 -0
- package/prompts/project-starters/es/nextjs-project.md +82 -0
- package/prompts/project-starters/fastapi-project.md +60 -0
- package/prompts/project-starters/fr/fastapi-project.md +62 -0
- package/prompts/project-starters/fr/nextjs-project.md +82 -0
- package/prompts/project-starters/nextjs-project.md +80 -0
- package/prompts/project-starters/nl/fastapi-project.md +62 -0
- package/prompts/project-starters/nl/nextjs-project.md +82 -0
- package/prompts/system-prompts/ai-product.md +80 -0
- package/prompts/system-prompts/data-pipeline.md +76 -0
- package/prompts/system-prompts/de/ai-product.md +82 -0
- package/prompts/system-prompts/de/data-pipeline.md +78 -0
- package/prompts/system-prompts/de/saas-backend.md +71 -0
- package/prompts/system-prompts/es/ai-product.md +82 -0
- package/prompts/system-prompts/es/data-pipeline.md +78 -0
- package/prompts/system-prompts/es/saas-backend.md +71 -0
- package/prompts/system-prompts/fr/ai-product.md +82 -0
- package/prompts/system-prompts/fr/data-pipeline.md +78 -0
- package/prompts/system-prompts/fr/saas-backend.md +71 -0
- package/prompts/system-prompts/nl/ai-product.md +82 -0
- package/prompts/system-prompts/nl/data-pipeline.md +78 -0
- package/prompts/system-prompts/nl/saas-backend.md +71 -0
- package/prompts/system-prompts/saas-backend.md +69 -0
- package/prompts/task-specific/changelog.md +81 -0
- package/prompts/task-specific/de/changelog.md +83 -0
- package/prompts/task-specific/de/debugging.md +78 -0
- package/prompts/task-specific/de/pr-description.md +69 -0
- package/prompts/task-specific/debugging.md +76 -0
- package/prompts/task-specific/es/changelog.md +83 -0
- package/prompts/task-specific/es/debugging.md +78 -0
- package/prompts/task-specific/es/pr-description.md +69 -0
- package/prompts/task-specific/fr/changelog.md +83 -0
- package/prompts/task-specific/fr/debugging.md +78 -0
- package/prompts/task-specific/fr/pr-description.md +69 -0
- package/prompts/task-specific/nl/changelog.md +83 -0
- package/prompts/task-specific/nl/debugging.md +78 -0
- package/prompts/task-specific/nl/pr-description.md +69 -0
- package/prompts/task-specific/pr-description.md +67 -0
- package/rules/common/coding-style.md +45 -0
- package/rules/common/de/coding-style.md +47 -0
- package/rules/common/de/git.md +48 -0
- package/rules/common/de/performance.md +40 -0
- package/rules/common/de/security.md +45 -0
- package/rules/common/de/testing.md +45 -0
- package/rules/common/es/coding-style.md +47 -0
- package/rules/common/es/git.md +48 -0
- package/rules/common/es/performance.md +40 -0
- package/rules/common/es/security.md +45 -0
- package/rules/common/es/testing.md +45 -0
- package/rules/common/fr/coding-style.md +47 -0
- package/rules/common/fr/git.md +48 -0
- package/rules/common/fr/performance.md +40 -0
- package/rules/common/fr/security.md +45 -0
- package/rules/common/fr/testing.md +45 -0
- package/rules/common/git.md +46 -0
- package/rules/common/nl/coding-style.md +47 -0
- package/rules/common/nl/git.md +48 -0
- package/rules/common/nl/performance.md +40 -0
- package/rules/common/nl/security.md +45 -0
- package/rules/common/nl/testing.md +45 -0
- package/rules/common/performance.md +38 -0
- package/rules/common/security.md +43 -0
- package/rules/common/testing.md +43 -0
- package/rules/language-specific/de/go.md +48 -0
- package/rules/language-specific/de/python.md +38 -0
- package/rules/language-specific/de/typescript.md +51 -0
- package/rules/language-specific/es/go.md +48 -0
- package/rules/language-specific/es/python.md +38 -0
- package/rules/language-specific/es/typescript.md +51 -0
- package/rules/language-specific/fr/go.md +48 -0
- package/rules/language-specific/fr/python.md +38 -0
- package/rules/language-specific/fr/typescript.md +51 -0
- package/rules/language-specific/go.md +46 -0
- package/rules/language-specific/nl/go.md +48 -0
- package/rules/language-specific/nl/python.md +38 -0
- package/rules/language-specific/nl/typescript.md +51 -0
- package/rules/language-specific/python.md +36 -0
- package/rules/language-specific/typescript.md +49 -0
- package/scripts/cli.js +161 -0
- package/scripts/link-skills.sh +35 -0
- package/scripts/list-skills.sh +34 -0
- package/skills/ai-engineering/agent-construction.md +285 -0
- package/skills/ai-engineering/claude-api.md +248 -0
- package/skills/ai-engineering/de/agent-construction.md +287 -0
- package/skills/ai-engineering/de/claude-api.md +250 -0
- package/skills/ai-engineering/es/agent-construction.md +287 -0
- package/skills/ai-engineering/es/claude-api.md +250 -0
- package/skills/ai-engineering/fr/agent-construction.md +287 -0
- package/skills/ai-engineering/fr/claude-api.md +250 -0
- package/skills/ai-engineering/nl/agent-construction.md +287 -0
- package/skills/ai-engineering/nl/claude-api.md +250 -0
- package/skills/backend/dotnet/csharp.md +304 -0
- package/skills/backend/dotnet/de/csharp.md +306 -0
- package/skills/backend/dotnet/es/csharp.md +306 -0
- package/skills/backend/dotnet/fr/csharp.md +306 -0
- package/skills/backend/dotnet/nl/csharp.md +306 -0
- package/skills/backend/go/de/go.md +307 -0
- package/skills/backend/go/es/go.md +307 -0
- package/skills/backend/go/fr/go.md +307 -0
- package/skills/backend/go/go.md +305 -0
- package/skills/backend/go/nl/go.md +307 -0
- package/skills/backend/nodejs/de/nestjs.md +274 -0
- package/skills/backend/nodejs/de/nextjs.md +222 -0
- package/skills/backend/nodejs/es/nestjs.md +274 -0
- package/skills/backend/nodejs/es/nextjs.md +222 -0
- package/skills/backend/nodejs/fr/nestjs.md +274 -0
- package/skills/backend/nodejs/fr/nextjs.md +222 -0
- package/skills/backend/nodejs/nestjs.md +272 -0
- package/skills/backend/nodejs/nextjs.md +220 -0
- package/skills/backend/nodejs/nl/nestjs.md +274 -0
- package/skills/backend/nodejs/nl/nextjs.md +222 -0
- package/skills/backend/python/de/django.md +285 -0
- package/skills/backend/python/de/fastapi.md +244 -0
- package/skills/backend/python/django.md +283 -0
- package/skills/backend/python/es/django.md +285 -0
- package/skills/backend/python/es/fastapi.md +244 -0
- package/skills/backend/python/fastapi.md +242 -0
- package/skills/backend/python/fr/django.md +285 -0
- package/skills/backend/python/fr/fastapi.md +244 -0
- package/skills/backend/python/nl/django.md +285 -0
- package/skills/backend/python/nl/fastapi.md +244 -0
- package/skills/data-ml/dbt-data-pipelines.md +155 -0
- package/skills/data-ml/de/dbt-data-pipelines.md +157 -0
- package/skills/data-ml/de/pandas-polars.md +147 -0
- package/skills/data-ml/de/pytorch-tensorflow.md +171 -0
- package/skills/data-ml/es/dbt-data-pipelines.md +157 -0
- package/skills/data-ml/es/pandas-polars.md +147 -0
- package/skills/data-ml/es/pytorch-tensorflow.md +171 -0
- package/skills/data-ml/fr/dbt-data-pipelines.md +157 -0
- package/skills/data-ml/fr/pandas-polars.md +147 -0
- package/skills/data-ml/fr/pytorch-tensorflow.md +171 -0
- package/skills/data-ml/nl/dbt-data-pipelines.md +157 -0
- package/skills/data-ml/nl/pandas-polars.md +147 -0
- package/skills/data-ml/nl/pytorch-tensorflow.md +171 -0
- package/skills/data-ml/pandas-polars.md +145 -0
- package/skills/data-ml/pytorch-tensorflow.md +169 -0
- package/skills/database/de/graphql.md +181 -0
- package/skills/database/es/graphql.md +181 -0
- package/skills/database/fr/graphql.md +181 -0
- package/skills/database/graphql.md +179 -0
- package/skills/database/nl/graphql.md +181 -0
- package/skills/devops-infra/de/docker.md +133 -0
- package/skills/devops-infra/de/github-actions.md +179 -0
- package/skills/devops-infra/de/kubernetes.md +129 -0
- package/skills/devops-infra/de/terraform.md +130 -0
- package/skills/devops-infra/docker.md +131 -0
- package/skills/devops-infra/es/docker.md +133 -0
- package/skills/devops-infra/es/github-actions.md +179 -0
- package/skills/devops-infra/es/kubernetes.md +129 -0
- package/skills/devops-infra/es/terraform.md +130 -0
- package/skills/devops-infra/fr/docker.md +133 -0
- package/skills/devops-infra/fr/github-actions.md +179 -0
- package/skills/devops-infra/fr/kubernetes.md +129 -0
- package/skills/devops-infra/fr/terraform.md +130 -0
- package/skills/devops-infra/github-actions.md +177 -0
- package/skills/devops-infra/kubernetes.md +127 -0
- package/skills/devops-infra/nl/docker.md +133 -0
- package/skills/devops-infra/nl/github-actions.md +179 -0
- package/skills/devops-infra/nl/kubernetes.md +129 -0
- package/skills/devops-infra/nl/terraform.md +130 -0
- package/skills/devops-infra/terraform.md +128 -0
- package/skills/finance-payments/de/stripe.md +187 -0
- package/skills/finance-payments/es/stripe.md +187 -0
- package/skills/finance-payments/fr/stripe.md +187 -0
- package/skills/finance-payments/nl/stripe.md +187 -0
- package/skills/finance-payments/stripe.md +185 -0
- package/workflows/code-review.md +151 -0
- package/workflows/de/code-review.md +153 -0
- package/workflows/de/debugging-session.md +146 -0
- package/workflows/de/feature-development.md +155 -0
- package/workflows/de/new-project-bootstrap.md +175 -0
- package/workflows/de/refactor-safely.md +150 -0
- package/workflows/debugging-session.md +144 -0
- package/workflows/es/code-review.md +153 -0
- package/workflows/es/debugging-session.md +146 -0
- package/workflows/es/feature-development.md +155 -0
- package/workflows/es/new-project-bootstrap.md +175 -0
- package/workflows/es/refactor-safely.md +150 -0
- package/workflows/feature-development.md +153 -0
- package/workflows/fr/code-review.md +153 -0
- package/workflows/fr/debugging-session.md +146 -0
- package/workflows/fr/feature-development.md +155 -0
- package/workflows/fr/new-project-bootstrap.md +175 -0
- package/workflows/fr/refactor-safely.md +150 -0
- package/workflows/new-project-bootstrap.md +173 -0
- package/workflows/nl/code-review.md +153 -0
- package/workflows/nl/debugging-session.md +146 -0
- package/workflows/nl/feature-development.md +155 -0
- package/workflows/nl/new-project-bootstrap.md +175 -0
- package/workflows/nl/refactor-safely.md +150 -0
- package/workflows/refactor-safely.md +148 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
> 🇫🇷 This is the French translation. [English version](../kubernetes.md).
|
|
2
|
+
|
|
3
|
+
# Compétence Kubernetes
|
|
4
|
+
|
|
5
|
+
## Quand activer
|
|
6
|
+
- Rédiger des manifests Kubernetes (Deployments, Services, ConfigMaps, Secrets, Ingress)
|
|
7
|
+
- Configurer des charts Helm ou des fichiers de valeurs pour une application
|
|
8
|
+
- Déboguer un Pod en échec, CrashLoopBackOff, ou un conteneur OOMKilled
|
|
9
|
+
- Mettre en place un autoscaling horizontal (HPA) ou vertical (VPA) des pods
|
|
10
|
+
- Définir les requests et limits de ressources pour les conteneurs
|
|
11
|
+
- Rédiger ou réviser des politiques RBAC (Roles, ClusterRoles, RoleBindings)
|
|
12
|
+
- Configurer des sondes liveness, readiness et startup
|
|
13
|
+
- Configurer des volumes persistants et des revendications de volumes persistants
|
|
14
|
+
- Rédiger des politiques réseau pour contrôler le trafic entre pods
|
|
15
|
+
- Configurer des namespaces et l'isolation multi-tenant
|
|
16
|
+
|
|
17
|
+
## Quand NE PAS utiliser
|
|
18
|
+
- Configurations Docker Compose qui ne migrent pas vers Kubernetes
|
|
19
|
+
- Serverless (Cloud Run, Lambda, Fargate) — modèle de déploiement différent
|
|
20
|
+
- Applications mono-conteneur simples qui n'ont pas besoin d'orchestration
|
|
21
|
+
- Environnements de développement local où Docker seul suffit
|
|
22
|
+
- Nomad, Mesos, ou autres orchestrateurs non-Kubernetes
|
|
23
|
+
|
|
24
|
+
## Instructions
|
|
25
|
+
|
|
26
|
+
### Structure des manifests
|
|
27
|
+
Toujours définir ces champs dans chaque Deployment :
|
|
28
|
+
```yaml
|
|
29
|
+
apiVersion: apps/v1
|
|
30
|
+
kind: Deployment
|
|
31
|
+
metadata:
|
|
32
|
+
name: app-name
|
|
33
|
+
namespace: production # Toujours explicite — ne jamais se fier au namespace par défaut
|
|
34
|
+
labels:
|
|
35
|
+
app: app-name
|
|
36
|
+
version: "1.0.0"
|
|
37
|
+
spec:
|
|
38
|
+
replicas: 3
|
|
39
|
+
selector:
|
|
40
|
+
matchLabels:
|
|
41
|
+
app: app-name
|
|
42
|
+
template:
|
|
43
|
+
metadata:
|
|
44
|
+
labels:
|
|
45
|
+
app: app-name
|
|
46
|
+
version: "1.0.0"
|
|
47
|
+
spec:
|
|
48
|
+
containers:
|
|
49
|
+
- name: app-name
|
|
50
|
+
image: registry/app-name:tag # Ne jamais utiliser :latest en production
|
|
51
|
+
resources:
|
|
52
|
+
requests:
|
|
53
|
+
cpu: "100m"
|
|
54
|
+
memory: "128Mi"
|
|
55
|
+
limits:
|
|
56
|
+
cpu: "500m"
|
|
57
|
+
memory: "512Mi"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Requests et limits de ressources
|
|
61
|
+
- Toujours définir `requests` et `limits` — ne jamais les omettre
|
|
62
|
+
- `requests` = ressources garanties (utilisées pour la planification)
|
|
63
|
+
- `limits` = maximum autorisé (OOMKilled si la mémoire est dépassée)
|
|
64
|
+
- Les limites CPU sont optionnelles dans les clusters avec limitation CPU désactivée — mais les limites mémoire sont obligatoires
|
|
65
|
+
- Commencer prudemment : requests à ~25% de l'attendu, limits à 2x l'attendu, puis ajuster avec les métriques réelles
|
|
66
|
+
|
|
67
|
+
### Sondes de santé
|
|
68
|
+
Tous les conteneurs de production doivent avoir des sondes :
|
|
69
|
+
```yaml
|
|
70
|
+
livenessProbe:
|
|
71
|
+
httpGet:
|
|
72
|
+
path: /healthz
|
|
73
|
+
port: 8080
|
|
74
|
+
initialDelaySeconds: 15
|
|
75
|
+
periodSeconds: 20
|
|
76
|
+
failureThreshold: 3
|
|
77
|
+
|
|
78
|
+
readinessProbe:
|
|
79
|
+
httpGet:
|
|
80
|
+
path: /ready
|
|
81
|
+
port: 8080
|
|
82
|
+
initialDelaySeconds: 5
|
|
83
|
+
periodSeconds: 10
|
|
84
|
+
failureThreshold: 3
|
|
85
|
+
```
|
|
86
|
+
- Échec de `livenessProbe` → redémarrage du conteneur
|
|
87
|
+
- Échec de `readinessProbe` → retiré du load balancer du Service (pas de trafic, pas de redémarrage)
|
|
88
|
+
- Ne jamais pointer les deux vers le même endpoint — la readiness doit vérifier les dépendances, pas la liveness
|
|
89
|
+
|
|
90
|
+
### Gestion des secrets
|
|
91
|
+
- Ne jamais mettre des secrets dans des ConfigMaps — utiliser des Secrets
|
|
92
|
+
- Ne jamais committer des manifests Secret avec de vraies valeurs — utiliser sealed-secrets, external-secrets-operator, ou Vault
|
|
93
|
+
- Référencer les secrets comme variables d'environnement, pas comme volumes, sauf si l'application requiert spécifiquement des secrets basés sur des fichiers :
|
|
94
|
+
```yaml
|
|
95
|
+
env:
|
|
96
|
+
- name: DATABASE_URL
|
|
97
|
+
valueFrom:
|
|
98
|
+
secretKeyRef:
|
|
99
|
+
name: app-secrets
|
|
100
|
+
key: database-url
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Conventions des namespaces
|
|
104
|
+
- Namespace `default` : dev/test uniquement
|
|
105
|
+
- Les workloads de production toujours dans des namespaces nommés
|
|
106
|
+
- Utiliser `ResourceQuota` et `LimitRange` sur chaque namespace de production
|
|
107
|
+
- RBAC : les développeurs ont edit dans les namespaces dev, view en production
|
|
108
|
+
|
|
109
|
+
### Causes courantes de CrashLoopBackOff et corrections
|
|
110
|
+
1. Variable d'environnement manquante → vérifier la section Events de `kubectl describe pod`
|
|
111
|
+
2. Healthcheck échoué → les logs montrent la vraie erreur, la sonde la détecte seulement
|
|
112
|
+
3. OOMKilled → augmenter la limit mémoire ou corriger la fuite mémoire
|
|
113
|
+
4. Erreur de récupération d'image → vérifier imagePullPolicy et les credentials du registre
|
|
114
|
+
5. Échec d'un init container → `kubectl logs pod-name -c init-container-name`
|
|
115
|
+
|
|
116
|
+
## Exemple
|
|
117
|
+
|
|
118
|
+
**Utilisateur :** Déployer une application FastAPI avec une connexion PostgreSQL, 3 réplicas, des limits de ressources et des health checks.
|
|
119
|
+
|
|
120
|
+
**Structure de sortie attendue :**
|
|
121
|
+
- Manifest Namespace
|
|
122
|
+
- Secret pour `DATABASE_URL`
|
|
123
|
+
- Deployment avec 3 réplicas, requests/limits de ressources, sondes liveness + readiness pointant vers `/healthz` et `/ready`
|
|
124
|
+
- Service (ClusterIP) exposant le port 80 → port conteneur 8080
|
|
125
|
+
- HorizontalPodAutoscaler ciblant 70% d'utilisation CPU, min 3 / max 10 réplicas
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
> **Travaillez avec nous :** Claudient est soutenu par [Uitbreiden](https://uitbreiden.com/) — nous construisons des produits IA et des solutions B2B avec des communautés de développeurs. Vous construisez une infrastructure Kubernetes ou des produits IA cloud-native ? [uitbreiden.com](https://uitbreiden.com/)
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
> 🇫🇷 This is the French translation. [English version](../terraform.md).
|
|
2
|
+
|
|
3
|
+
# Compétence Terraform
|
|
4
|
+
|
|
5
|
+
## Quand activer
|
|
6
|
+
- Rédiger des modules Terraform pour l'infrastructure AWS, GCP, ou Azure
|
|
7
|
+
- Définir des VPCs, sous-réseaux, groupes de sécurité et ressources réseau
|
|
8
|
+
- Provisionner des ressources de calcul (EC2, GKE, AKS, ECS, Lambda)
|
|
9
|
+
- Gérer l'infrastructure de bases de données (RDS, Cloud SQL, Aurora)
|
|
10
|
+
- Configurer des rôles IAM, des politiques et des comptes de service
|
|
11
|
+
- Rédiger la configuration de l'état distant (backend S3, GCS, Terraform Cloud)
|
|
12
|
+
- Refactoriser du Terraform existant pour utiliser des modules
|
|
13
|
+
- Rédiger des pipelines CI/CD pour `terraform plan` et `terraform apply`
|
|
14
|
+
- Importer de l'infrastructure existante dans l'état Terraform
|
|
15
|
+
|
|
16
|
+
## Quand NE PAS utiliser
|
|
17
|
+
- Pulumi, CDK, ou Crossplane — outils IaC différents, patterns différents
|
|
18
|
+
- Configuration de charts Helm (utiliser la compétence Kubernetes à la place)
|
|
19
|
+
- Configuration au niveau applicatif (Kubernetes ConfigMaps, variables d'environnement d'app)
|
|
20
|
+
- Opérations CLI ponctuelles qui ne seront pas répétées
|
|
21
|
+
|
|
22
|
+
## Instructions
|
|
23
|
+
|
|
24
|
+
### Structure des modules
|
|
25
|
+
Chaque projet Terraform doit suivre cette structure :
|
|
26
|
+
```
|
|
27
|
+
infrastructure/
|
|
28
|
+
├── modules/
|
|
29
|
+
│ ├── networking/
|
|
30
|
+
│ │ ├── main.tf
|
|
31
|
+
│ │ ├── variables.tf
|
|
32
|
+
│ │ ├── outputs.tf
|
|
33
|
+
│ │ └── versions.tf
|
|
34
|
+
│ └── compute/
|
|
35
|
+
│ ├── main.tf
|
|
36
|
+
│ ├── variables.tf
|
|
37
|
+
│ └── outputs.tf
|
|
38
|
+
├── environments/
|
|
39
|
+
│ ├── production/
|
|
40
|
+
│ │ ├── main.tf ← appelle les modules
|
|
41
|
+
│ │ ├── variables.tf
|
|
42
|
+
│ │ ├── terraform.tfvars
|
|
43
|
+
│ │ └── backend.tf
|
|
44
|
+
│ └── staging/
|
|
45
|
+
│ └── ...
|
|
46
|
+
└── versions.tf ← versions des providers à la racine
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Gestion de l'état — toujours distant
|
|
50
|
+
```hcl
|
|
51
|
+
# backend.tf
|
|
52
|
+
terraform {
|
|
53
|
+
backend "s3" {
|
|
54
|
+
bucket = "company-terraform-state"
|
|
55
|
+
key = "production/networking/terraform.tfstate"
|
|
56
|
+
region = "eu-west-1"
|
|
57
|
+
encrypt = true
|
|
58
|
+
dynamodb_table = "terraform-state-lock"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
- Ne jamais utiliser l'état local pour quelque chose de partagé
|
|
63
|
+
- Activer le chiffrement et le verrouillage de l'état (DynamoDB pour le backend S3)
|
|
64
|
+
- Séparer les fichiers d'état par environnement et par module (pas un état géant unique)
|
|
65
|
+
|
|
66
|
+
### Discipline des variables et des outputs
|
|
67
|
+
```hcl
|
|
68
|
+
# variables.tf — toujours inclure description et type
|
|
69
|
+
variable "environment" {
|
|
70
|
+
description = "Deployment environment (production, staging, development)"
|
|
71
|
+
type = string
|
|
72
|
+
validation {
|
|
73
|
+
condition = contains(["production", "staging", "development"], var.environment)
|
|
74
|
+
error_message = "Environment must be production, staging, or development."
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
# outputs.tf — exporter tout ce qu'un module consommateur pourrait avoir besoin
|
|
79
|
+
output "vpc_id" {
|
|
80
|
+
description = "The ID of the VPC"
|
|
81
|
+
value = aws_vpc.main.id
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Secrets — jamais dans l'état ou le code
|
|
86
|
+
- Ne jamais mettre des secrets dans `terraform.tfvars` ou les coder en dur dans des fichiers `.tf`
|
|
87
|
+
- Utiliser `data "aws_secretsmanager_secret_version"` ou `data "google_secret_manager_secret_version"` pour lire les secrets au moment de l'application
|
|
88
|
+
- Outputs sensibles : marquer avec `sensitive = true` pour les supprimer de la sortie du plan
|
|
89
|
+
- `.gitignore` doit inclure : `*.tfvars`, `*.tfstate`, `*.tfstate.backup`, `.terraform/`
|
|
90
|
+
|
|
91
|
+
### Conventions de nommage des ressources
|
|
92
|
+
```hcl
|
|
93
|
+
# Nommage cohérent : {project}-{environment}-{resource}-{suffix}
|
|
94
|
+
resource "aws_vpc" "main" {
|
|
95
|
+
cidr_block = var.vpc_cidr
|
|
96
|
+
tags = {
|
|
97
|
+
Name = "${var.project}-${var.environment}-vpc"
|
|
98
|
+
Environment = var.environment
|
|
99
|
+
ManagedBy = "terraform"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
Toujours taguer chaque ressource avec `Environment` et `ManagedBy = "terraform"`.
|
|
104
|
+
|
|
105
|
+
### Planifier avant d'appliquer — toujours
|
|
106
|
+
- Pipeline CI/CD : `terraform plan -out=tfplan` sur PR, `terraform apply tfplan` lors de la fusion
|
|
107
|
+
- Ne jamais exécuter `terraform apply` sans plan sauvegardé en production
|
|
108
|
+
- Utiliser `-target` avec parcimonie — cela crée de la dérive entre l'état réel et le plan
|
|
109
|
+
|
|
110
|
+
### Pièges courants
|
|
111
|
+
- `terraform destroy` sans `-target` détruit tout — toujours confirmer la portée
|
|
112
|
+
- Changer un attribut de ressource qui force le remplacement (ex: CIDR VPC) supprime et recrée — vérifier attentivement le plan
|
|
113
|
+
- L'épinglage des versions de provider est obligatoire : utiliser `~> 5.0` et non `>= 5.0`
|
|
114
|
+
- `count` vs `for_each` : utiliser `for_each` avec des maps — `count` provoque une dérive d'index quand des éléments sont supprimés
|
|
115
|
+
|
|
116
|
+
## Exemple
|
|
117
|
+
|
|
118
|
+
**Utilisateur :** Créer un module Terraform pour une instance RDS PostgreSQL privée sur AWS avec Multi-AZ, stockage chiffré et un groupe de sécurité dédié.
|
|
119
|
+
|
|
120
|
+
**Structure de sortie attendue :**
|
|
121
|
+
- `modules/rds/main.tf` — `aws_db_instance`, `aws_db_subnet_group`, `aws_security_group`
|
|
122
|
+
- `modules/rds/variables.tf` — classe d'instance, version du moteur, nom de la DB, IDs VPC/sous-réseau, CIDR d'entrée
|
|
123
|
+
- `modules/rds/outputs.tf` — endpoint, port, ID du groupe de sécurité
|
|
124
|
+
- Groupe de sécurité : autorise PostgreSQL (5432) uniquement depuis le groupe de sécurité de l'app, pas d'accès public
|
|
125
|
+
- `storage_encrypted = true`, `multi_az = true`, `deletion_protection = true` pour la production
|
|
126
|
+
- Mot de passe via référence `aws_secretsmanager_secret`, jamais codé en dur
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
> **Travaillez avec nous :** Claudient est soutenu par [Uitbreiden](https://uitbreiden.com/) — nous construisons des produits IA et des solutions B2B avec des communautés de développeurs. Vous construisez de l'infrastructure cloud ou des pipelines IaC ? [uitbreiden.com](https://uitbreiden.com/)
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# GitHub Actions Skill
|
|
2
|
+
|
|
3
|
+
## When to activate
|
|
4
|
+
- Writing CI/CD pipelines for test, lint, build, and deploy
|
|
5
|
+
- Setting up matrix builds across multiple OS or language versions
|
|
6
|
+
- Configuring environment protection rules and deployment gates
|
|
7
|
+
- Writing reusable workflows or composite actions
|
|
8
|
+
- Setting up Docker build and push to a container registry
|
|
9
|
+
- Configuring OIDC authentication to cloud providers (no long-lived secrets)
|
|
10
|
+
- Debugging failing workflows or understanding workflow syntax errors
|
|
11
|
+
- Setting up caching for dependencies (npm, pip, Go modules)
|
|
12
|
+
|
|
13
|
+
## When NOT to use
|
|
14
|
+
- GitLab CI, CircleCI, Jenkins — different pipeline systems
|
|
15
|
+
- Local development automation (use Makefile or scripts)
|
|
16
|
+
- Cron jobs that aren't tied to a repository (use cloud scheduler)
|
|
17
|
+
|
|
18
|
+
## Instructions
|
|
19
|
+
|
|
20
|
+
### Workflow file structure
|
|
21
|
+
```yaml
|
|
22
|
+
name: CI
|
|
23
|
+
|
|
24
|
+
on:
|
|
25
|
+
push:
|
|
26
|
+
branches: [main]
|
|
27
|
+
pull_request:
|
|
28
|
+
branches: [main]
|
|
29
|
+
|
|
30
|
+
# Explicit permissions — never use default write-all
|
|
31
|
+
permissions:
|
|
32
|
+
contents: read
|
|
33
|
+
pull-requests: write # Only if needed (e.g., posting comments)
|
|
34
|
+
|
|
35
|
+
jobs:
|
|
36
|
+
test:
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v4
|
|
40
|
+
- name: Set up Node.js
|
|
41
|
+
uses: actions/setup-node@v4
|
|
42
|
+
with:
|
|
43
|
+
node-version: '20'
|
|
44
|
+
cache: 'npm'
|
|
45
|
+
- run: npm ci
|
|
46
|
+
- run: npm test
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Permissions — always explicit
|
|
50
|
+
Never use the default `permissions: write-all`. Always declare minimum required permissions:
|
|
51
|
+
```yaml
|
|
52
|
+
permissions:
|
|
53
|
+
contents: read # Read repo
|
|
54
|
+
packages: write # Push to GitHub Container Registry
|
|
55
|
+
id-token: write # OIDC for cloud auth
|
|
56
|
+
pull-requests: write # Comment on PRs
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Secrets — OIDC over long-lived credentials
|
|
60
|
+
Use OIDC (OpenID Connect) for cloud authentication — no stored secrets:
|
|
61
|
+
|
|
62
|
+
```yaml
|
|
63
|
+
# AWS OIDC — no AWS_ACCESS_KEY_ID needed
|
|
64
|
+
- name: Configure AWS credentials
|
|
65
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
66
|
+
with:
|
|
67
|
+
role-to-assume: arn:aws:iam::123456789:role/github-actions-role
|
|
68
|
+
aws-region: eu-west-1
|
|
69
|
+
|
|
70
|
+
# GCP OIDC
|
|
71
|
+
- name: Authenticate to GCP
|
|
72
|
+
uses: google-github-actions/auth@v2
|
|
73
|
+
with:
|
|
74
|
+
workload_identity_provider: projects/123/locations/global/workloadIdentityPools/pool/providers/github
|
|
75
|
+
service_account: deploy@project.iam.gserviceaccount.com
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Dependency caching
|
|
79
|
+
Always cache dependencies to cut build time:
|
|
80
|
+
```yaml
|
|
81
|
+
# Node.js
|
|
82
|
+
- uses: actions/setup-node@v4
|
|
83
|
+
with:
|
|
84
|
+
node-version: '20'
|
|
85
|
+
cache: 'npm' # Built-in cache — no manual cache step needed
|
|
86
|
+
|
|
87
|
+
# Python
|
|
88
|
+
- uses: actions/setup-python@v5
|
|
89
|
+
with:
|
|
90
|
+
python-version: '3.12'
|
|
91
|
+
cache: 'pip'
|
|
92
|
+
|
|
93
|
+
# Go
|
|
94
|
+
- uses: actions/setup-go@v5
|
|
95
|
+
with:
|
|
96
|
+
go-version: '1.22'
|
|
97
|
+
cache: true
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Environment gates for production deployments
|
|
101
|
+
```yaml
|
|
102
|
+
jobs:
|
|
103
|
+
deploy-production:
|
|
104
|
+
environment: production # References GitHub Environment with protection rules
|
|
105
|
+
needs: [test, build]
|
|
106
|
+
runs-on: ubuntu-latest
|
|
107
|
+
steps:
|
|
108
|
+
- name: Deploy
|
|
109
|
+
run: ./scripts/deploy.sh
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Set up Environment protection rules in GitHub Settings:
|
|
113
|
+
- Required reviewers for production deployments
|
|
114
|
+
- Wait timer between staging and production
|
|
115
|
+
- Restrict to specific branches (`main` only)
|
|
116
|
+
|
|
117
|
+
### Matrix builds
|
|
118
|
+
```yaml
|
|
119
|
+
jobs:
|
|
120
|
+
test:
|
|
121
|
+
strategy:
|
|
122
|
+
matrix:
|
|
123
|
+
node-version: [18, 20, 22]
|
|
124
|
+
os: [ubuntu-latest, windows-latest]
|
|
125
|
+
fail-fast: false # Don't cancel all on first failure
|
|
126
|
+
runs-on: ${{ matrix.os }}
|
|
127
|
+
steps:
|
|
128
|
+
- uses: actions/checkout@v4
|
|
129
|
+
- uses: actions/setup-node@v4
|
|
130
|
+
with:
|
|
131
|
+
node-version: ${{ matrix.node-version }}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Reusable workflows
|
|
135
|
+
```yaml
|
|
136
|
+
# .github/workflows/deploy.yml — reusable
|
|
137
|
+
on:
|
|
138
|
+
workflow_call:
|
|
139
|
+
inputs:
|
|
140
|
+
environment:
|
|
141
|
+
required: true
|
|
142
|
+
type: string
|
|
143
|
+
secrets:
|
|
144
|
+
deploy-token:
|
|
145
|
+
required: true
|
|
146
|
+
|
|
147
|
+
# Caller
|
|
148
|
+
jobs:
|
|
149
|
+
deploy:
|
|
150
|
+
uses: ./.github/workflows/deploy.yml
|
|
151
|
+
with:
|
|
152
|
+
environment: production
|
|
153
|
+
secrets:
|
|
154
|
+
deploy-token: ${{ secrets.DEPLOY_TOKEN }}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Common failures
|
|
158
|
+
- `actions/checkout@v4` missing — always the first step
|
|
159
|
+
- Secrets not accessible in forks — use `pull_request_target` carefully (security risk)
|
|
160
|
+
- Cache not hit — key must match exactly; use `restore-keys` for fallback
|
|
161
|
+
- OIDC fails — check trust policy on the cloud provider side allows the repo and branch
|
|
162
|
+
|
|
163
|
+
## Example
|
|
164
|
+
|
|
165
|
+
**User:** Write a CI/CD pipeline for a Node.js app: run tests on PRs, build and push Docker image on merge to main, deploy to production with a manual approval gate.
|
|
166
|
+
|
|
167
|
+
**Expected output:**
|
|
168
|
+
- `on: push/pull_request` triggers
|
|
169
|
+
- `test` job: checkout, setup-node with cache, `npm ci`, `npm test`
|
|
170
|
+
- `build` job (on push to main, needs test): Docker build + push to GHCR using OIDC
|
|
171
|
+
- `deploy` job: `environment: production` (requires approval), calls deploy script
|
|
172
|
+
- Explicit `permissions:` block — minimum required
|
|
173
|
+
- No hardcoded secrets — OIDC for registry auth
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
> **Work with us:** Claudient is backed by [Uitbreiden](https://uitbreiden.com/) — we build AI products and B2B solutions with developer communities. Building CI/CD for AI products or cloud deployments? [uitbreiden.com](https://uitbreiden.com/)
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Kubernetes Skill
|
|
2
|
+
|
|
3
|
+
## When to activate
|
|
4
|
+
- Writing Kubernetes manifests (Deployments, Services, ConfigMaps, Secrets, Ingress)
|
|
5
|
+
- Configuring Helm charts or values files for an application
|
|
6
|
+
- Debugging a failing Pod, CrashLoopBackOff, or OOMKilled container
|
|
7
|
+
- Setting up horizontal pod autoscaling (HPA) or vertical pod autoscaling (VPA)
|
|
8
|
+
- Defining resource requests and limits for containers
|
|
9
|
+
- Writing or reviewing RBAC policies (Roles, ClusterRoles, RoleBindings)
|
|
10
|
+
- Setting up liveness, readiness, and startup probes
|
|
11
|
+
- Configuring persistent volumes and persistent volume claims
|
|
12
|
+
- Writing network policies to control pod-to-pod traffic
|
|
13
|
+
- Setting up namespaces and multi-tenant isolation
|
|
14
|
+
|
|
15
|
+
## When NOT to use
|
|
16
|
+
- Docker Compose setups that aren't being migrated to Kubernetes
|
|
17
|
+
- Serverless (Cloud Run, Lambda, Fargate) — different deployment model
|
|
18
|
+
- Simple single-container apps that don't need orchestration
|
|
19
|
+
- Local development environments where Docker alone suffices
|
|
20
|
+
- Nomad, Mesos, or other non-Kubernetes orchestrators
|
|
21
|
+
|
|
22
|
+
## Instructions
|
|
23
|
+
|
|
24
|
+
### Manifest structure
|
|
25
|
+
Always set these fields in every Deployment:
|
|
26
|
+
```yaml
|
|
27
|
+
apiVersion: apps/v1
|
|
28
|
+
kind: Deployment
|
|
29
|
+
metadata:
|
|
30
|
+
name: app-name
|
|
31
|
+
namespace: production # Always explicit — never rely on default namespace
|
|
32
|
+
labels:
|
|
33
|
+
app: app-name
|
|
34
|
+
version: "1.0.0"
|
|
35
|
+
spec:
|
|
36
|
+
replicas: 3
|
|
37
|
+
selector:
|
|
38
|
+
matchLabels:
|
|
39
|
+
app: app-name
|
|
40
|
+
template:
|
|
41
|
+
metadata:
|
|
42
|
+
labels:
|
|
43
|
+
app: app-name
|
|
44
|
+
version: "1.0.0"
|
|
45
|
+
spec:
|
|
46
|
+
containers:
|
|
47
|
+
- name: app-name
|
|
48
|
+
image: registry/app-name:tag # Never use :latest in production
|
|
49
|
+
resources:
|
|
50
|
+
requests:
|
|
51
|
+
cpu: "100m"
|
|
52
|
+
memory: "128Mi"
|
|
53
|
+
limits:
|
|
54
|
+
cpu: "500m"
|
|
55
|
+
memory: "512Mi"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Resource requests and limits
|
|
59
|
+
- Always set both `requests` and `limits` — never omit
|
|
60
|
+
- `requests` = guaranteed resources (used for scheduling)
|
|
61
|
+
- `limits` = maximum allowed (OOMKilled if memory exceeded)
|
|
62
|
+
- CPU limits are optional in clusters with CPU throttling disabled — but memory limits are mandatory
|
|
63
|
+
- Start conservative: requests at ~25% of expected, limits at 2x expected, then tune with actual metrics
|
|
64
|
+
|
|
65
|
+
### Health probes
|
|
66
|
+
All production containers must have probes:
|
|
67
|
+
```yaml
|
|
68
|
+
livenessProbe:
|
|
69
|
+
httpGet:
|
|
70
|
+
path: /healthz
|
|
71
|
+
port: 8080
|
|
72
|
+
initialDelaySeconds: 15
|
|
73
|
+
periodSeconds: 20
|
|
74
|
+
failureThreshold: 3
|
|
75
|
+
|
|
76
|
+
readinessProbe:
|
|
77
|
+
httpGet:
|
|
78
|
+
path: /ready
|
|
79
|
+
port: 8080
|
|
80
|
+
initialDelaySeconds: 5
|
|
81
|
+
periodSeconds: 10
|
|
82
|
+
failureThreshold: 3
|
|
83
|
+
```
|
|
84
|
+
- `livenessProbe` failure → container restart
|
|
85
|
+
- `readinessProbe` failure → removed from Service load balancer (no traffic, no restart)
|
|
86
|
+
- Never point both at the same endpoint — readiness should check dependencies, liveness should not
|
|
87
|
+
|
|
88
|
+
### Secrets management
|
|
89
|
+
- Never put secrets in ConfigMaps — use Secrets
|
|
90
|
+
- Never commit Secret manifests with real values — use sealed-secrets, external-secrets-operator, or Vault
|
|
91
|
+
- Reference secrets as env vars, not volumes, unless the app specifically requires file-based secrets:
|
|
92
|
+
```yaml
|
|
93
|
+
env:
|
|
94
|
+
- name: DATABASE_URL
|
|
95
|
+
valueFrom:
|
|
96
|
+
secretKeyRef:
|
|
97
|
+
name: app-secrets
|
|
98
|
+
key: database-url
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Namespace conventions
|
|
102
|
+
- `default` namespace: dev/testing only
|
|
103
|
+
- Production workloads always in named namespaces
|
|
104
|
+
- Use `ResourceQuota` and `LimitRange` on every production namespace
|
|
105
|
+
- RBAC: developers get edit in dev namespaces, view in production
|
|
106
|
+
|
|
107
|
+
### Common CrashLoopBackOff causes and fixes
|
|
108
|
+
1. Missing env var → check `kubectl describe pod` Events section
|
|
109
|
+
2. Failed healthcheck → logs show the real error, probe just detects it
|
|
110
|
+
3. OOMKilled → increase memory limit or fix memory leak
|
|
111
|
+
4. Image pull error → check imagePullPolicy and registry credentials
|
|
112
|
+
5. Init container failure → `kubectl logs pod-name -c init-container-name`
|
|
113
|
+
|
|
114
|
+
## Example
|
|
115
|
+
|
|
116
|
+
**User:** Deploy a FastAPI app with PostgreSQL connection, 3 replicas, resource limits, and health checks.
|
|
117
|
+
|
|
118
|
+
**Expected output structure:**
|
|
119
|
+
- Namespace manifest
|
|
120
|
+
- Secret for `DATABASE_URL`
|
|
121
|
+
- Deployment with 3 replicas, resource requests/limits, liveness + readiness probes pointing to `/healthz` and `/ready`
|
|
122
|
+
- Service (ClusterIP) exposing port 80 → container port 8080
|
|
123
|
+
- HorizontalPodAutoscaler targeting 70% CPU utilization, min 3 / max 10 replicas
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
> **Work with us:** Claudient is backed by [Uitbreiden](https://uitbreiden.com/) — we build AI products and B2B solutions with developer communities. Building Kubernetes infrastructure or cloud-native AI products? [uitbreiden.com](https://uitbreiden.com/)
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
> 🇳🇱 Dit is de Nederlandse vertaling. [Engelse versie](../docker.md).
|
|
2
|
+
|
|
3
|
+
# Docker Skill
|
|
4
|
+
|
|
5
|
+
## Wanneer te activeren
|
|
6
|
+
- Dockerfiles schrijven of optimaliseren voor productie
|
|
7
|
+
- Multi-stage builds instellen om de image-grootte te verkleinen
|
|
8
|
+
- Docker Compose-bestanden schrijven voor lokale ontwikkeling
|
|
9
|
+
- Container-opstartfouten of layer cache-problemen debuggen
|
|
10
|
+
- Niet-root gebruikers, health checks en image-beveiliging configureren
|
|
11
|
+
- .dockerignore instellen voor efficiënte builds
|
|
12
|
+
- Build-scripts of CI/CD Docker build-pipelines schrijven
|
|
13
|
+
|
|
14
|
+
## Wanneer NIET te gebruiken
|
|
15
|
+
- Kubernetes-manifests (gebruik de Kubernetes skill)
|
|
16
|
+
- Buildpacks (Heroku, Cloud Native Buildpacks) — ander build-systeem
|
|
17
|
+
- Virtual machine-inrichting (ander abstractieniveau)
|
|
18
|
+
- Op Nix gebaseerde reproduceerbare builds
|
|
19
|
+
|
|
20
|
+
## Instructies
|
|
21
|
+
|
|
22
|
+
### Productie Dockerfile-structuur
|
|
23
|
+
Gebruik altijd multi-stage builds voor gecompileerde talen en Node.js:
|
|
24
|
+
|
|
25
|
+
```dockerfile
|
|
26
|
+
# Stage 1: Build
|
|
27
|
+
FROM node:20-alpine AS builder
|
|
28
|
+
WORKDIR /app
|
|
29
|
+
COPY package*.json ./
|
|
30
|
+
RUN npm ci --only=production
|
|
31
|
+
|
|
32
|
+
# Stage 2: Runtime — minimale image
|
|
33
|
+
FROM node:20-alpine AS runtime
|
|
34
|
+
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
|
|
35
|
+
WORKDIR /app
|
|
36
|
+
COPY --from=builder /app/node_modules ./node_modules
|
|
37
|
+
COPY . .
|
|
38
|
+
USER appuser
|
|
39
|
+
EXPOSE 8080
|
|
40
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
41
|
+
CMD wget -qO- http://localhost:8080/healthz || exit 1
|
|
42
|
+
CMD ["node", "server.js"]
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Beveiligingsregels
|
|
46
|
+
- Draai nooit als root in productie — maak altijd een niet-root gebruiker aan en schakel er naar over
|
|
47
|
+
- Gebruik nooit de `latest`-tag — pin op een specifieke versie of digest
|
|
48
|
+
- Geef de voorkeur aan Alpine- of distroless-basisimages boven volledige Debian/Ubuntu
|
|
49
|
+
- Kopieer nooit `.env`-bestanden in de image — geef secrets door als runtime-omgevingsvariabelen
|
|
50
|
+
- Scan images met `docker scout` of Trivy voordat ze naar productie worden gepusht
|
|
51
|
+
|
|
52
|
+
### Optimalisatie van layer-caching
|
|
53
|
+
Orden Dockerfile-instructies van minst-naar-meest frequent wisselend:
|
|
54
|
+
1. Basisimage (verandert zelden)
|
|
55
|
+
2. Systeemafhankelijkheden (`apt-get`, `apk add`)
|
|
56
|
+
3. Pakketbeheerderbestanden (`package.json`, `requirements.txt`)
|
|
57
|
+
4. Pakketinstallatie (`npm ci`, `pip install`)
|
|
58
|
+
5. Applicatiecode (`COPY . .`) — verandert het vaakst, moet als laatste staan
|
|
59
|
+
|
|
60
|
+
### .dockerignore — altijd opnemen
|
|
61
|
+
```
|
|
62
|
+
node_modules/
|
|
63
|
+
.git/
|
|
64
|
+
.env
|
|
65
|
+
.env.*
|
|
66
|
+
*.md
|
|
67
|
+
Dockerfile*
|
|
68
|
+
docker-compose*
|
|
69
|
+
.dockerignore
|
|
70
|
+
coverage/
|
|
71
|
+
.nyc_output/
|
|
72
|
+
__pycache__/
|
|
73
|
+
*.pyc
|
|
74
|
+
.pytest_cache/
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Docker Compose voor lokale ontwikkeling
|
|
78
|
+
```yaml
|
|
79
|
+
services:
|
|
80
|
+
app:
|
|
81
|
+
build:
|
|
82
|
+
context: .
|
|
83
|
+
target: builder # Gebruik build stage, niet runtime stage lokaal
|
|
84
|
+
volumes:
|
|
85
|
+
- .:/app # Hot reload
|
|
86
|
+
- /app/node_modules # Overschrijf container node_modules niet
|
|
87
|
+
ports:
|
|
88
|
+
- "8080:8080"
|
|
89
|
+
environment:
|
|
90
|
+
- NODE_ENV=development
|
|
91
|
+
depends_on:
|
|
92
|
+
db:
|
|
93
|
+
condition: service_healthy
|
|
94
|
+
|
|
95
|
+
db:
|
|
96
|
+
image: postgres:16-alpine
|
|
97
|
+
environment:
|
|
98
|
+
POSTGRES_USER: app
|
|
99
|
+
POSTGRES_PASSWORD: dev_password # Alleen dev — nooit productie
|
|
100
|
+
POSTGRES_DB: appdb
|
|
101
|
+
ports:
|
|
102
|
+
- "5432:5432"
|
|
103
|
+
healthcheck:
|
|
104
|
+
test: ["CMD-SHELL", "pg_isready -U app -d appdb"]
|
|
105
|
+
interval: 5s
|
|
106
|
+
timeout: 5s
|
|
107
|
+
retries: 5
|
|
108
|
+
volumes:
|
|
109
|
+
- postgres_data:/var/lib/postgresql/data
|
|
110
|
+
|
|
111
|
+
volumes:
|
|
112
|
+
postgres_data:
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Veelvoorkomende build-fouten
|
|
116
|
+
- `COPY` mislukt stilletjes als de bron niet bestaat — controleer of `.dockerignore` benodigde bestanden niet uitsluit
|
|
117
|
+
- Layer-cache onverwacht ongeldig — controleer of een `COPY` vóór installatiestappen gewijzigde bestanden meeneemt
|
|
118
|
+
- Toegang geweigerd tijdens runtime — controleer bestandseigendom bij gebruik van `COPY --from` met een niet-root gebruiker
|
|
119
|
+
|
|
120
|
+
## Voorbeeld
|
|
121
|
+
|
|
122
|
+
**Gebruiker:** Schrijf een productie-Dockerfile voor een Python FastAPI-app met multi-stage build, niet-root gebruiker en health check.
|
|
123
|
+
|
|
124
|
+
**Verwachte output:**
|
|
125
|
+
- Stage 1 (builder): `python:3.12-slim`, afhankelijkheden installeren met `pip install --no-cache-dir`
|
|
126
|
+
- Stage 2 (runtime): `python:3.12-slim`, niet-root gebruiker, alleen wheels/deps van builder + app-code kopiëren
|
|
127
|
+
- `HEALTHCHECK` die het `/healthz`-endpoint raakt
|
|
128
|
+
- `CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]`
|
|
129
|
+
- `.dockerignore` die `__pycache__`, `.env`, `.git`, `*.pyc` afdekt
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
> **Werk met ons:** Claudient wordt ondersteund door [Uitbreiden](https://uitbreiden.com/) — we bouwen AI-producten en B2B-oplossingen met ontwikkelaarsgemeenschappen. AI-workloads containeriseren of cloud-native systemen bouwen? [uitbreiden.com](https://uitbreiden.com/)
|