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
|
+
> 🇩🇪 Dies ist die deutsche Übersetzung. [Englische Version](../kubernetes.md).
|
|
2
|
+
|
|
3
|
+
# Kubernetes Skill
|
|
4
|
+
|
|
5
|
+
## Wann aktivieren
|
|
6
|
+
- Kubernetes-Manifeste schreiben (Deployments, Services, ConfigMaps, Secrets, Ingress)
|
|
7
|
+
- Helm-Charts oder Values-Dateien für eine Anwendung konfigurieren
|
|
8
|
+
- Einen fehlerhaften Pod, CrashLoopBackOff oder OOMKilled-Container debuggen
|
|
9
|
+
- Horizontal Pod Autoscaling (HPA) oder Vertical Pod Autoscaling (VPA) einrichten
|
|
10
|
+
- Ressourcenanforderungen und -limits für Container definieren
|
|
11
|
+
- RBAC-Richtlinien schreiben oder prüfen (Roles, ClusterRoles, RoleBindings)
|
|
12
|
+
- Liveness-, Readiness- und Startup-Probes einrichten
|
|
13
|
+
- Persistente Volumes und Persistent Volume Claims konfigurieren
|
|
14
|
+
- Netzwerkrichtlinien zur Steuerung des Pod-zu-Pod-Traffics schreiben
|
|
15
|
+
- Namespaces und Multi-Tenant-Isolation einrichten
|
|
16
|
+
|
|
17
|
+
## Wann NICHT verwenden
|
|
18
|
+
- Docker Compose-Setups, die nicht nach Kubernetes migriert werden
|
|
19
|
+
- Serverless (Cloud Run, Lambda, Fargate) — anderes Deployment-Modell
|
|
20
|
+
- Einfache Single-Container-Apps, die keine Orchestrierung benötigen
|
|
21
|
+
- Lokale Entwicklungsumgebungen, bei denen Docker allein ausreicht
|
|
22
|
+
- Nomad, Mesos oder andere Nicht-Kubernetes-Orchestratoren
|
|
23
|
+
|
|
24
|
+
## Anweisungen
|
|
25
|
+
|
|
26
|
+
### Manifest-Struktur
|
|
27
|
+
Diese Felder immer in jedem Deployment setzen:
|
|
28
|
+
```yaml
|
|
29
|
+
apiVersion: apps/v1
|
|
30
|
+
kind: Deployment
|
|
31
|
+
metadata:
|
|
32
|
+
name: app-name
|
|
33
|
+
namespace: production # Immer explizit — niemals auf den Standard-Namespace verlassen
|
|
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 # Niemals :latest in der Produktion verwenden
|
|
51
|
+
resources:
|
|
52
|
+
requests:
|
|
53
|
+
cpu: "100m"
|
|
54
|
+
memory: "128Mi"
|
|
55
|
+
limits:
|
|
56
|
+
cpu: "500m"
|
|
57
|
+
memory: "512Mi"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Ressourcenanforderungen und -limits
|
|
61
|
+
- Immer sowohl `requests` als auch `limits` setzen — niemals weglassen
|
|
62
|
+
- `requests` = garantierte Ressourcen (werden für das Scheduling verwendet)
|
|
63
|
+
- `limits` = maximal erlaubt (OOMKilled, wenn Speicher überschritten wird)
|
|
64
|
+
- CPU-Limits sind in Clustern mit deaktivierter CPU-Drosselung optional — aber Speicher-Limits sind obligatorisch
|
|
65
|
+
- Konservativ beginnen: requests bei ~25% des Erwarteten, limits bei 2x dem Erwarteten, dann mit tatsächlichen Metriken anpassen
|
|
66
|
+
|
|
67
|
+
### Health-Probes
|
|
68
|
+
Alle Produktions-Container müssen Probes haben:
|
|
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
|
+
- `livenessProbe`-Fehler → Container-Neustart
|
|
87
|
+
- `readinessProbe`-Fehler → aus dem Service-Load-Balancer entfernt (kein Traffic, kein Neustart)
|
|
88
|
+
- Beide niemals auf denselben Endpunkt zeigen — Readiness sollte Abhängigkeiten prüfen, Liveness nicht
|
|
89
|
+
|
|
90
|
+
### Secrets-Verwaltung
|
|
91
|
+
- Niemals Secrets in ConfigMaps — Secrets verwenden
|
|
92
|
+
- Niemals Secret-Manifeste mit echten Werten committen — sealed-secrets, external-secrets-operator oder Vault verwenden
|
|
93
|
+
- Secrets als Umgebungsvariablen referenzieren, nicht als Volumes, außer die App benötigt dateibasierte Secrets:
|
|
94
|
+
```yaml
|
|
95
|
+
env:
|
|
96
|
+
- name: DATABASE_URL
|
|
97
|
+
valueFrom:
|
|
98
|
+
secretKeyRef:
|
|
99
|
+
name: app-secrets
|
|
100
|
+
key: database-url
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Namespace-Konventionen
|
|
104
|
+
- `default`-Namespace: nur für Dev/Testing
|
|
105
|
+
- Produktions-Workloads immer in benannten Namespaces
|
|
106
|
+
- `ResourceQuota` und `LimitRange` auf jedem Produktions-Namespace verwenden
|
|
107
|
+
- RBAC: Entwickler erhalten edit in Dev-Namespaces, view in der Produktion
|
|
108
|
+
|
|
109
|
+
### Häufige CrashLoopBackOff-Ursachen und Lösungen
|
|
110
|
+
1. Fehlende Umgebungsvariable → `kubectl describe pod` Events-Abschnitt prüfen
|
|
111
|
+
2. Fehlgeschlagener Healthcheck → Logs zeigen den eigentlichen Fehler, Probe erkennt ihn nur
|
|
112
|
+
3. OOMKilled → Speicher-Limit erhöhen oder Speicherleck beheben
|
|
113
|
+
4. Image-Pull-Fehler → imagePullPolicy und Registry-Anmeldedaten prüfen
|
|
114
|
+
5. Init-Container-Fehler → `kubectl logs pod-name -c init-container-name`
|
|
115
|
+
|
|
116
|
+
## Beispiel
|
|
117
|
+
|
|
118
|
+
**Benutzer:** Eine FastAPI-App mit PostgreSQL-Verbindung, 3 Replikas, Ressourcen-Limits und Health-Checks deployen.
|
|
119
|
+
|
|
120
|
+
**Erwartete Ausgabestruktur:**
|
|
121
|
+
- Namespace-Manifest
|
|
122
|
+
- Secret für `DATABASE_URL`
|
|
123
|
+
- Deployment mit 3 Replikas, Ressourcenanforderungen/-limits, Liveness + Readiness-Probes, die auf `/healthz` und `/ready` zeigen
|
|
124
|
+
- Service (ClusterIP), der Port 80 → Container-Port 8080 exponiert
|
|
125
|
+
- HorizontalPodAutoscaler mit 70% CPU-Auslastung als Ziel, min 3 / max 10 Replikas
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
> **Mit uns arbeiten:** Claudient wird von [Uitbreiden](https://uitbreiden.com/) unterstützt — wir bauen KI-Produkte und B2B-Lösungen mit Entwickler-Communities. Kubernetes-Infrastruktur oder cloud-native KI-Produkte aufbauen? [uitbreiden.com](https://uitbreiden.com/)
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
> 🇩🇪 Dies ist die deutsche Übersetzung. [Englische Version](../terraform.md).
|
|
2
|
+
|
|
3
|
+
# Terraform Skill
|
|
4
|
+
|
|
5
|
+
## Wann aktivieren
|
|
6
|
+
- Terraform-Module für AWS-, GCP- oder Azure-Infrastruktur schreiben
|
|
7
|
+
- VPCs, Subnetze, Sicherheitsgruppen und Netzwerkressourcen definieren
|
|
8
|
+
- Compute-Ressourcen bereitstellen (EC2, GKE, AKS, ECS, Lambda)
|
|
9
|
+
- Datenbank-Infrastruktur verwalten (RDS, Cloud SQL, Aurora)
|
|
10
|
+
- IAM-Rollen, -Richtlinien und Service-Accounts einrichten
|
|
11
|
+
- Remote-State-Konfiguration schreiben (S3-Backend, GCS, Terraform Cloud)
|
|
12
|
+
- Bestehende Terraform-Konfiguration zur Modulnutzung umstrukturieren
|
|
13
|
+
- CI/CD-Pipelines für `terraform plan` und `terraform apply` schreiben
|
|
14
|
+
- Bestehende Infrastruktur in den Terraform-State importieren
|
|
15
|
+
|
|
16
|
+
## Wann NICHT verwenden
|
|
17
|
+
- Pulumi, CDK oder Crossplane — andere IaC-Tools, andere Muster
|
|
18
|
+
- Helm-Chart-Konfiguration (stattdessen Kubernetes Skill verwenden)
|
|
19
|
+
- Anwendungsspezifische Konfiguration (Kubernetes ConfigMaps, App-Umgebungsvariablen)
|
|
20
|
+
- Einmalige CLI-Operationen, die nicht wiederholt werden
|
|
21
|
+
|
|
22
|
+
## Anweisungen
|
|
23
|
+
|
|
24
|
+
### Modulstruktur
|
|
25
|
+
Jedes Terraform-Projekt muss dieser Struktur folgen:
|
|
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 ← ruft Module auf
|
|
41
|
+
│ │ ├── variables.tf
|
|
42
|
+
│ │ ├── terraform.tfvars
|
|
43
|
+
│ │ └── backend.tf
|
|
44
|
+
│ └── staging/
|
|
45
|
+
│ └── ...
|
|
46
|
+
└── versions.tf ← Root-Provider-Versionen
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### State-Verwaltung — immer remote
|
|
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
|
+
- Niemals lokalen State für gemeinsam genutzte Ressourcen verwenden
|
|
63
|
+
- Verschlüsselung und State-Locking aktivieren (DynamoDB für S3-Backend)
|
|
64
|
+
- Separate State-Dateien pro Umgebung und pro Modul (kein ein riesiger State)
|
|
65
|
+
|
|
66
|
+
### Variablen- und Output-Disziplin
|
|
67
|
+
```hcl
|
|
68
|
+
# variables.tf — immer Beschreibung und Typ angeben
|
|
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 — alles ausgeben, was ein konsumierendes Modul benötigen könnte
|
|
79
|
+
output "vpc_id" {
|
|
80
|
+
description = "The ID of the VPC"
|
|
81
|
+
value = aws_vpc.main.id
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Secrets — niemals im State oder Code
|
|
86
|
+
- Niemals Secrets in `terraform.tfvars` eintragen oder in `.tf`-Dateien hardcoden
|
|
87
|
+
- `data "aws_secretsmanager_secret_version"` oder `data "google_secret_manager_secret_version"` verwenden, um Secrets zur Apply-Zeit zu lesen
|
|
88
|
+
- Sensible Outputs: mit `sensitive = true` markieren, um sie in der Plan-Ausgabe zu unterdrücken
|
|
89
|
+
- `.gitignore` muss enthalten: `*.tfvars`, `*.tfstate`, `*.tfstate.backup`, `.terraform/`
|
|
90
|
+
|
|
91
|
+
### Ressourcen-Namenskonventionen
|
|
92
|
+
```hcl
|
|
93
|
+
# Konsistente Benennung: {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
|
+
Jede Ressource immer mit `Environment` und `ManagedBy = "terraform"` taggen.
|
|
104
|
+
|
|
105
|
+
### Plan vor Apply — immer
|
|
106
|
+
- CI/CD-Pipeline: `terraform plan -out=tfplan` beim PR, `terraform apply tfplan` beim Merge
|
|
107
|
+
- Niemals `terraform apply` ohne gespeicherten Plan in der Produktion ausführen
|
|
108
|
+
- `-target` sparsam verwenden — es erzeugt Drift zwischen dem tatsächlichen State und dem Plan
|
|
109
|
+
|
|
110
|
+
### Häufige Fallstricke
|
|
111
|
+
- `terraform destroy` ohne `-target` zerstört alles — immer den Umfang bestätigen
|
|
112
|
+
- Änderung eines Ressourcenattributs, das einen Ersatz erzwingt (z.B. VPC CIDR), löscht und erstellt neu — Plan sorgfältig prüfen
|
|
113
|
+
- Provider-Versions-Pinning ist obligatorisch: `~> 5.0` verwenden, nicht `>= 5.0`
|
|
114
|
+
- `count` vs `for_each`: `for_each` mit Maps verwenden — `count` verursacht Index-Drift wenn Elemente entfernt werden
|
|
115
|
+
|
|
116
|
+
## Beispiel
|
|
117
|
+
|
|
118
|
+
**Benutzer:** Ein Terraform-Modul für eine private RDS-PostgreSQL-Instanz auf AWS mit Multi-AZ, verschlüsseltem Speicher und einer dedizierten Sicherheitsgruppe erstellen.
|
|
119
|
+
|
|
120
|
+
**Erwartete Ausgabestruktur:**
|
|
121
|
+
- `modules/rds/main.tf` — `aws_db_instance`, `aws_db_subnet_group`, `aws_security_group`
|
|
122
|
+
- `modules/rds/variables.tf` — Instance-Klasse, Engine-Version, DB-Name, VPC/Subnet-IDs, Ingress-CIDR
|
|
123
|
+
- `modules/rds/outputs.tf` — Endpunkt, Port, Sicherheitsgruppen-ID
|
|
124
|
+
- Sicherheitsgruppe: erlaubt PostgreSQL (5432) nur von der App-Sicherheitsgruppe, kein öffentlicher Zugang
|
|
125
|
+
- `storage_encrypted = true`, `multi_az = true`, `deletion_protection = true` für die Produktion
|
|
126
|
+
- Passwort über `aws_secretsmanager_secret`-Referenz, niemals hartcodiert
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
> **Mit uns arbeiten:** Claudient wird von [Uitbreiden](https://uitbreiden.com/) unterstützt — wir bauen KI-Produkte und B2B-Lösungen mit Entwickler-Communities. Cloud-Infrastruktur oder IaC-Pipelines aufbauen? [uitbreiden.com](https://uitbreiden.com/)
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Docker Skill
|
|
2
|
+
|
|
3
|
+
## When to activate
|
|
4
|
+
- Writing or optimizing Dockerfiles for production
|
|
5
|
+
- Setting up multi-stage builds to reduce image size
|
|
6
|
+
- Writing Docker Compose files for local development
|
|
7
|
+
- Debugging container startup failures or layer cache issues
|
|
8
|
+
- Configuring non-root users, health checks, and image security
|
|
9
|
+
- Setting up .dockerignore for efficient builds
|
|
10
|
+
- Writing build scripts or CI/CD Docker build pipelines
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
- Kubernetes manifests (use the Kubernetes skill)
|
|
14
|
+
- Buildpacks (Heroku, Cloud Native Buildpacks) — different build system
|
|
15
|
+
- Virtual machine provisioning (different abstraction level)
|
|
16
|
+
- Nix-based reproducible builds
|
|
17
|
+
|
|
18
|
+
## Instructions
|
|
19
|
+
|
|
20
|
+
### Production Dockerfile structure
|
|
21
|
+
Always use multi-stage builds for compiled languages and Node.js:
|
|
22
|
+
|
|
23
|
+
```dockerfile
|
|
24
|
+
# Stage 1: Build
|
|
25
|
+
FROM node:20-alpine AS builder
|
|
26
|
+
WORKDIR /app
|
|
27
|
+
COPY package*.json ./
|
|
28
|
+
RUN npm ci --only=production
|
|
29
|
+
|
|
30
|
+
# Stage 2: Runtime — minimal image
|
|
31
|
+
FROM node:20-alpine AS runtime
|
|
32
|
+
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
|
|
33
|
+
WORKDIR /app
|
|
34
|
+
COPY --from=builder /app/node_modules ./node_modules
|
|
35
|
+
COPY . .
|
|
36
|
+
USER appuser
|
|
37
|
+
EXPOSE 8080
|
|
38
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
39
|
+
CMD wget -qO- http://localhost:8080/healthz || exit 1
|
|
40
|
+
CMD ["node", "server.js"]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Security rules
|
|
44
|
+
- Never run as root in production — always create and switch to a non-root user
|
|
45
|
+
- Never use `latest` tag — pin to a specific version or digest
|
|
46
|
+
- Prefer Alpine or distroless base images over full Debian/Ubuntu
|
|
47
|
+
- Never copy `.env` files into the image — pass secrets as runtime env vars
|
|
48
|
+
- Scan images with `docker scout` or Trivy before pushing to production
|
|
49
|
+
|
|
50
|
+
### Layer caching optimization
|
|
51
|
+
Order Dockerfile instructions from least-to-most frequently changing:
|
|
52
|
+
1. Base image (changes rarely)
|
|
53
|
+
2. System dependencies (`apt-get`, `apk add`)
|
|
54
|
+
3. Package manager files (`package.json`, `requirements.txt`)
|
|
55
|
+
4. Package install (`npm ci`, `pip install`)
|
|
56
|
+
5. Application code (`COPY . .`) — changes most often, must be last
|
|
57
|
+
|
|
58
|
+
### .dockerignore — always include
|
|
59
|
+
```
|
|
60
|
+
node_modules/
|
|
61
|
+
.git/
|
|
62
|
+
.env
|
|
63
|
+
.env.*
|
|
64
|
+
*.md
|
|
65
|
+
Dockerfile*
|
|
66
|
+
docker-compose*
|
|
67
|
+
.dockerignore
|
|
68
|
+
coverage/
|
|
69
|
+
.nyc_output/
|
|
70
|
+
__pycache__/
|
|
71
|
+
*.pyc
|
|
72
|
+
.pytest_cache/
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Docker Compose for local development
|
|
76
|
+
```yaml
|
|
77
|
+
services:
|
|
78
|
+
app:
|
|
79
|
+
build:
|
|
80
|
+
context: .
|
|
81
|
+
target: builder # Use build stage, not runtime stage locally
|
|
82
|
+
volumes:
|
|
83
|
+
- .:/app # Hot reload
|
|
84
|
+
- /app/node_modules # Don't overwrite container node_modules
|
|
85
|
+
ports:
|
|
86
|
+
- "8080:8080"
|
|
87
|
+
environment:
|
|
88
|
+
- NODE_ENV=development
|
|
89
|
+
depends_on:
|
|
90
|
+
db:
|
|
91
|
+
condition: service_healthy
|
|
92
|
+
|
|
93
|
+
db:
|
|
94
|
+
image: postgres:16-alpine
|
|
95
|
+
environment:
|
|
96
|
+
POSTGRES_USER: app
|
|
97
|
+
POSTGRES_PASSWORD: dev_password # Dev only — never production
|
|
98
|
+
POSTGRES_DB: appdb
|
|
99
|
+
ports:
|
|
100
|
+
- "5432:5432"
|
|
101
|
+
healthcheck:
|
|
102
|
+
test: ["CMD-SHELL", "pg_isready -U app -d appdb"]
|
|
103
|
+
interval: 5s
|
|
104
|
+
timeout: 5s
|
|
105
|
+
retries: 5
|
|
106
|
+
volumes:
|
|
107
|
+
- postgres_data:/var/lib/postgresql/data
|
|
108
|
+
|
|
109
|
+
volumes:
|
|
110
|
+
postgres_data:
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Common build failures
|
|
114
|
+
- `COPY` fails silently if source doesn't exist — check `.dockerignore` isn't excluding needed files
|
|
115
|
+
- Layer cache invalidated unexpectedly — check if a `COPY` before install steps is pulling in changed files
|
|
116
|
+
- Permission denied at runtime — check file ownership when using `COPY --from` with a non-root user
|
|
117
|
+
|
|
118
|
+
## Example
|
|
119
|
+
|
|
120
|
+
**User:** Write a production Dockerfile for a Python FastAPI app with multi-stage build, non-root user, and health check.
|
|
121
|
+
|
|
122
|
+
**Expected output:**
|
|
123
|
+
- Stage 1 (builder): `python:3.12-slim`, install dependencies with `pip install --no-cache-dir`
|
|
124
|
+
- Stage 2 (runtime): `python:3.12-slim`, non-root user, copy only wheels/deps from builder + app code
|
|
125
|
+
- `HEALTHCHECK` hitting `/healthz` endpoint
|
|
126
|
+
- `CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]`
|
|
127
|
+
- `.dockerignore` covering `__pycache__`, `.env`, `.git`, `*.pyc`
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
> **Work with us:** Claudient is backed by [Uitbreiden](https://uitbreiden.com/) — we build AI products and B2B solutions with developer communities. Containerizing AI workloads or building cloud-native systems? [uitbreiden.com](https://uitbreiden.com/)
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
> 🇪🇸 Esta es la traducción en español. [Versión en inglés](../docker.md).
|
|
2
|
+
|
|
3
|
+
# Skill de Docker
|
|
4
|
+
|
|
5
|
+
## Cuándo activar
|
|
6
|
+
- Escribir u optimizar Dockerfiles para producción
|
|
7
|
+
- Configurar builds multi-etapa para reducir el tamaño de la imagen
|
|
8
|
+
- Escribir archivos Docker Compose para desarrollo local
|
|
9
|
+
- Depurar fallos de inicio de contenedores o problemas de caché de capas
|
|
10
|
+
- Configurar usuarios no-root, health checks y seguridad de imágenes
|
|
11
|
+
- Configurar .dockerignore para builds eficientes
|
|
12
|
+
- Escribir scripts de build o pipelines de CI/CD para builds de Docker
|
|
13
|
+
|
|
14
|
+
## Cuándo NO usar
|
|
15
|
+
- Manifiestos de Kubernetes (usar el skill de Kubernetes)
|
|
16
|
+
- Buildpacks (Heroku, Cloud Native Buildpacks) — sistema de build diferente
|
|
17
|
+
- Aprovisionamiento de máquinas virtuales (nivel de abstracción diferente)
|
|
18
|
+
- Builds reproducibles basados en Nix
|
|
19
|
+
|
|
20
|
+
## Instrucciones
|
|
21
|
+
|
|
22
|
+
### Estructura del Dockerfile de producción
|
|
23
|
+
Siempre usa builds multi-etapa para lenguajes compilados y Node.js:
|
|
24
|
+
|
|
25
|
+
```dockerfile
|
|
26
|
+
# Etapa 1: Build
|
|
27
|
+
FROM node:20-alpine AS builder
|
|
28
|
+
WORKDIR /app
|
|
29
|
+
COPY package*.json ./
|
|
30
|
+
RUN npm ci --only=production
|
|
31
|
+
|
|
32
|
+
# Etapa 2: Runtime — imagen mínima
|
|
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
|
+
### Reglas de seguridad
|
|
46
|
+
- Nunca ejecutes como root en producción — siempre crea y cambia a un usuario no-root
|
|
47
|
+
- Nunca uses la etiqueta `latest` — fija a una versión o digest específico
|
|
48
|
+
- Prefiere imágenes base Alpine o distroless sobre Debian/Ubuntu completo
|
|
49
|
+
- Nunca copies archivos `.env` en la imagen — pasa los secretos como variables de entorno en tiempo de ejecución
|
|
50
|
+
- Escanea las imágenes con `docker scout` o Trivy antes de enviar a producción
|
|
51
|
+
|
|
52
|
+
### Optimización de caché de capas
|
|
53
|
+
Ordena las instrucciones del Dockerfile de menos a más frecuentemente cambiante:
|
|
54
|
+
1. Imagen base (cambia raramente)
|
|
55
|
+
2. Dependencias del sistema (`apt-get`, `apk add`)
|
|
56
|
+
3. Archivos del gestor de paquetes (`package.json`, `requirements.txt`)
|
|
57
|
+
4. Instalación de paquetes (`npm ci`, `pip install`)
|
|
58
|
+
5. Código de la aplicación (`COPY . .`) — cambia con más frecuencia, debe ser el último
|
|
59
|
+
|
|
60
|
+
### .dockerignore — siempre incluir
|
|
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 para desarrollo local
|
|
78
|
+
```yaml
|
|
79
|
+
services:
|
|
80
|
+
app:
|
|
81
|
+
build:
|
|
82
|
+
context: .
|
|
83
|
+
target: builder # Usa la etapa de build, no la de runtime, localmente
|
|
84
|
+
volumes:
|
|
85
|
+
- .:/app # Hot reload
|
|
86
|
+
- /app/node_modules # No sobreescribir node_modules del contenedor
|
|
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 # Solo dev — nunca producción
|
|
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
|
+
### Fallos comunes de build
|
|
116
|
+
- `COPY` falla silenciosamente si el origen no existe — verifica que `.dockerignore` no esté excluyendo archivos necesarios
|
|
117
|
+
- Caché de capas invalidada inesperadamente — verifica si un `COPY` antes de los pasos de instalación está incluyendo archivos cambiados
|
|
118
|
+
- Permiso denegado en tiempo de ejecución — verifica la propiedad de archivos al usar `COPY --from` con un usuario no-root
|
|
119
|
+
|
|
120
|
+
## Ejemplo
|
|
121
|
+
|
|
122
|
+
**Usuario:** Escribir un Dockerfile de producción para una aplicación Python FastAPI con build multi-etapa, usuario no-root y health check.
|
|
123
|
+
|
|
124
|
+
**Salida esperada:**
|
|
125
|
+
- Etapa 1 (builder): `python:3.12-slim`, instalar dependencias con `pip install --no-cache-dir`
|
|
126
|
+
- Etapa 2 (runtime): `python:3.12-slim`, usuario no-root, copiar solo wheels/deps del builder + código de la app
|
|
127
|
+
- `HEALTHCHECK` apuntando al endpoint `/healthz`
|
|
128
|
+
- `CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]`
|
|
129
|
+
- `.dockerignore` cubriendo `__pycache__`, `.env`, `.git`, `*.pyc`
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
> **Trabaja con nosotros:** Claudient está respaldado por [Uitbreiden](https://uitbreiden.com/) — construimos productos de IA y soluciones B2B con comunidades de desarrolladores. ¿Contenedorizando cargas de trabajo de IA o construyendo sistemas cloud-native? [uitbreiden.com](https://uitbreiden.com/)
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
> 🇪🇸 Esta es la traducción en español. [Versión en inglés](../github-actions.md).
|
|
2
|
+
|
|
3
|
+
# Skill de GitHub Actions
|
|
4
|
+
|
|
5
|
+
## Cuándo activar
|
|
6
|
+
- Escribir pipelines de CI/CD para test, lint, build y deploy
|
|
7
|
+
- Configurar builds en matrix para múltiples SO o versiones de lenguaje
|
|
8
|
+
- Configurar reglas de protección de entornos y puertas de despliegue
|
|
9
|
+
- Escribir workflows reutilizables o acciones compuestas
|
|
10
|
+
- Configurar build y push de Docker a un registro de contenedores
|
|
11
|
+
- Configurar autenticación OIDC a proveedores cloud (sin secretos de larga duración)
|
|
12
|
+
- Depurar workflows fallidos o entender errores de sintaxis de workflow
|
|
13
|
+
- Configurar caché para dependencias (npm, pip, módulos de Go)
|
|
14
|
+
|
|
15
|
+
## Cuándo NO usar
|
|
16
|
+
- GitLab CI, CircleCI, Jenkins — sistemas de pipeline diferentes
|
|
17
|
+
- Automatización de desarrollo local (usar Makefile o scripts)
|
|
18
|
+
- Cron jobs que no están vinculados a un repositorio (usar cloud scheduler)
|
|
19
|
+
|
|
20
|
+
## Instrucciones
|
|
21
|
+
|
|
22
|
+
### Estructura del archivo de workflow
|
|
23
|
+
```yaml
|
|
24
|
+
name: CI
|
|
25
|
+
|
|
26
|
+
on:
|
|
27
|
+
push:
|
|
28
|
+
branches: [main]
|
|
29
|
+
pull_request:
|
|
30
|
+
branches: [main]
|
|
31
|
+
|
|
32
|
+
# Permisos explícitos — nunca usar write-all por defecto
|
|
33
|
+
permissions:
|
|
34
|
+
contents: read
|
|
35
|
+
pull-requests: write # Solo si es necesario (p.ej., publicar comentarios)
|
|
36
|
+
|
|
37
|
+
jobs:
|
|
38
|
+
test:
|
|
39
|
+
runs-on: ubuntu-latest
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/checkout@v4
|
|
42
|
+
- name: Set up Node.js
|
|
43
|
+
uses: actions/setup-node@v4
|
|
44
|
+
with:
|
|
45
|
+
node-version: '20'
|
|
46
|
+
cache: 'npm'
|
|
47
|
+
- run: npm ci
|
|
48
|
+
- run: npm test
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Permisos — siempre explícitos
|
|
52
|
+
Nunca uses `permissions: write-all` por defecto. Siempre declara los permisos mínimos requeridos:
|
|
53
|
+
```yaml
|
|
54
|
+
permissions:
|
|
55
|
+
contents: read # Leer el repo
|
|
56
|
+
packages: write # Push a GitHub Container Registry
|
|
57
|
+
id-token: write # OIDC para autenticación cloud
|
|
58
|
+
pull-requests: write # Comentar en PRs
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Secretos — OIDC sobre credenciales de larga duración
|
|
62
|
+
Usa OIDC (OpenID Connect) para autenticación cloud — sin secretos almacenados:
|
|
63
|
+
|
|
64
|
+
```yaml
|
|
65
|
+
# AWS OIDC — no se necesita AWS_ACCESS_KEY_ID
|
|
66
|
+
- name: Configure AWS credentials
|
|
67
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
68
|
+
with:
|
|
69
|
+
role-to-assume: arn:aws:iam::123456789:role/github-actions-role
|
|
70
|
+
aws-region: eu-west-1
|
|
71
|
+
|
|
72
|
+
# GCP OIDC
|
|
73
|
+
- name: Authenticate to GCP
|
|
74
|
+
uses: google-github-actions/auth@v2
|
|
75
|
+
with:
|
|
76
|
+
workload_identity_provider: projects/123/locations/global/workloadIdentityPools/pool/providers/github
|
|
77
|
+
service_account: deploy@project.iam.gserviceaccount.com
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Caché de dependencias
|
|
81
|
+
Siempre cachea las dependencias para reducir el tiempo de build:
|
|
82
|
+
```yaml
|
|
83
|
+
# Node.js
|
|
84
|
+
- uses: actions/setup-node@v4
|
|
85
|
+
with:
|
|
86
|
+
node-version: '20'
|
|
87
|
+
cache: 'npm' # Caché integrado — no se necesita paso de caché manual
|
|
88
|
+
|
|
89
|
+
# Python
|
|
90
|
+
- uses: actions/setup-python@v5
|
|
91
|
+
with:
|
|
92
|
+
python-version: '3.12'
|
|
93
|
+
cache: 'pip'
|
|
94
|
+
|
|
95
|
+
# Go
|
|
96
|
+
- uses: actions/setup-go@v5
|
|
97
|
+
with:
|
|
98
|
+
go-version: '1.22'
|
|
99
|
+
cache: true
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Puertas de entorno para despliegues de producción
|
|
103
|
+
```yaml
|
|
104
|
+
jobs:
|
|
105
|
+
deploy-production:
|
|
106
|
+
environment: production # Referencia al Entorno de GitHub con reglas de protección
|
|
107
|
+
needs: [test, build]
|
|
108
|
+
runs-on: ubuntu-latest
|
|
109
|
+
steps:
|
|
110
|
+
- name: Deploy
|
|
111
|
+
run: ./scripts/deploy.sh
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Configura las reglas de protección de entornos en los ajustes de GitHub:
|
|
115
|
+
- Revisores requeridos para despliegues de producción
|
|
116
|
+
- Temporizador de espera entre staging y producción
|
|
117
|
+
- Restringir a ramas específicas (solo `main`)
|
|
118
|
+
|
|
119
|
+
### Builds en matrix
|
|
120
|
+
```yaml
|
|
121
|
+
jobs:
|
|
122
|
+
test:
|
|
123
|
+
strategy:
|
|
124
|
+
matrix:
|
|
125
|
+
node-version: [18, 20, 22]
|
|
126
|
+
os: [ubuntu-latest, windows-latest]
|
|
127
|
+
fail-fast: false # No cancelar todo ante el primer fallo
|
|
128
|
+
runs-on: ${{ matrix.os }}
|
|
129
|
+
steps:
|
|
130
|
+
- uses: actions/checkout@v4
|
|
131
|
+
- uses: actions/setup-node@v4
|
|
132
|
+
with:
|
|
133
|
+
node-version: ${{ matrix.node-version }}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Workflows reutilizables
|
|
137
|
+
```yaml
|
|
138
|
+
# .github/workflows/deploy.yml — reutilizable
|
|
139
|
+
on:
|
|
140
|
+
workflow_call:
|
|
141
|
+
inputs:
|
|
142
|
+
environment:
|
|
143
|
+
required: true
|
|
144
|
+
type: string
|
|
145
|
+
secrets:
|
|
146
|
+
deploy-token:
|
|
147
|
+
required: true
|
|
148
|
+
|
|
149
|
+
# Llamador
|
|
150
|
+
jobs:
|
|
151
|
+
deploy:
|
|
152
|
+
uses: ./.github/workflows/deploy.yml
|
|
153
|
+
with:
|
|
154
|
+
environment: production
|
|
155
|
+
secrets:
|
|
156
|
+
deploy-token: ${{ secrets.DEPLOY_TOKEN }}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Fallos comunes
|
|
160
|
+
- `actions/checkout@v4` faltante — siempre debe ser el primer paso
|
|
161
|
+
- Los secretos no son accesibles en forks — usa `pull_request_target` con cuidado (riesgo de seguridad)
|
|
162
|
+
- La caché no se utiliza — la clave debe coincidir exactamente; usa `restore-keys` como alternativa
|
|
163
|
+
- OIDC falla — verifica que la política de confianza en el proveedor cloud permita el repositorio y la rama
|
|
164
|
+
|
|
165
|
+
## Ejemplo
|
|
166
|
+
|
|
167
|
+
**Usuario:** Escribir un pipeline de CI/CD para una aplicación Node.js: ejecutar tests en PRs, construir y enviar imagen Docker al hacer merge en main, desplegar a producción con una puerta de aprobación manual.
|
|
168
|
+
|
|
169
|
+
**Salida esperada:**
|
|
170
|
+
- Triggers `on: push/pull_request`
|
|
171
|
+
- Job `test`: checkout, setup-node con caché, `npm ci`, `npm test`
|
|
172
|
+
- Job `build` (en push a main, necesita test): build + push de Docker a GHCR usando OIDC
|
|
173
|
+
- Job `deploy`: `environment: production` (requiere aprobación), llama al script de deploy
|
|
174
|
+
- Bloque `permissions:` explícito — mínimo requerido
|
|
175
|
+
- Sin secretos hardcodeados — OIDC para autenticación del registro
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
> **Trabaja con nosotros:** Claudient está respaldado por [Uitbreiden](https://uitbreiden.com/) — construimos productos de IA y soluciones B2B con comunidades de desarrolladores. ¿Construyendo CI/CD para productos de IA o despliegues cloud? [uitbreiden.com](https://uitbreiden.com/)
|