Migrate all repos into monorepo context folders
Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)
Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
---
|
||||
name: docker-build-db
|
||||
description: >
|
||||
Erstellt optimierte Dockerfiles und Docker-Compose-Konfigurationen für den DB-Konzern.
|
||||
Berücksichtigt DB-spezifische Anforderungen: Artifactory-Mirror statt Docker Hub,
|
||||
linux/amd64 Pflicht, non-root Security Context, OpenShift-Kompatibilität.
|
||||
Keywords: Dockerfile, Docker, Container, Image, docker-compose, Artifactory, bahnhub, OpenShift, non-root, multi-stage.
|
||||
compatibility: >
|
||||
Docker Desktop oder Podman. Zugang zu bahnhub.tech.rz.db.de (Artifactory).
|
||||
Für Push: API-Key über Artifactory-Profil.
|
||||
metadata:
|
||||
version: "1.0.0"
|
||||
author: "#Einfachbahn Lab"
|
||||
---
|
||||
|
||||
# Docker-Images für DB-Umgebung bauen
|
||||
|
||||
Skill für die Erstellung von Dockerfiles und Container-Images, die im DB-Konzern
|
||||
(Artifactory, OpenShift/DBCS) funktionieren.
|
||||
|
||||
## DB-spezifische Regeln (MUST)
|
||||
|
||||
1. **Immer `--platform linux/amd64`** — auch auf Apple Silicon / ARM
|
||||
2. **Base-Images aus Artifactory-Mirror** — kein direkter Docker-Hub-Zugriff im Cluster
|
||||
3. **Non-root** — Container laufen unter zufälliger UID (OpenShift `restricted` SCC)
|
||||
4. **Keine Secrets im Image** — nur über K8s-Secrets / Env-Vars zur Laufzeit
|
||||
5. **Feste Tags** — semantische Versionierung (`1.2.3`), kein `latest` für Deployments
|
||||
|
||||
## Ablauf
|
||||
|
||||
### Schritt 1: Kontext erfassen
|
||||
|
||||
1. **Sprache/Framework** — Python, Node.js, Java, Go, ...?
|
||||
2. **Artifactory-Repo** — Name des Docker-Repos (z. B. `einfachbahnlab-docker-stage-local`)
|
||||
3. **Braucht der Container Schreibzugriff?** — Falls ja: welche Pfade?
|
||||
4. **Health-Check-Endpoint** — Gibt es `/health` o. ä.?
|
||||
5. **Deployment-Ziel** — OpenShift (DBCS), lokal, AWS?
|
||||
|
||||
### Schritt 2: Dockerfile erstellen
|
||||
|
||||
## Dockerfile Patterns
|
||||
|
||||
### Python (Multi-Stage)
|
||||
```dockerfile
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM docker-hub-remote.bahnhub.tech.rz.db.de/python:3.14-slim AS builder
|
||||
|
||||
WORKDIR /build
|
||||
COPY pyproject.toml .
|
||||
COPY src/ src/
|
||||
RUN pip install --no-cache-dir --target=/install .
|
||||
|
||||
FROM docker-hub-remote.bahnhub.tech.rz.db.de/python:3.14-slim
|
||||
|
||||
# Non-root: OpenShift vergibt zufällige UID
|
||||
RUN useradd -r -u 1001 appuser
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=builder /install /usr/local/lib/python3.14/site-packages
|
||||
COPY src/ src/
|
||||
|
||||
# Schreibbare Verzeichnisse (falls nötig)
|
||||
RUN mkdir -p /app/data && chmod 777 /app/data
|
||||
|
||||
USER 1001
|
||||
EXPOSE 8000
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
|
||||
CMD python -c "import httpx; httpx.get('http://localhost:8000/health').raise_for_status()"
|
||||
|
||||
ENTRYPOINT ["python", "-m", "ai_orchestrator.cli"]
|
||||
```
|
||||
|
||||
### Node.js (Multi-Stage)
|
||||
```dockerfile
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM docker-hub-remote.bahnhub.tech.rz.db.de/node:22-slim AS builder
|
||||
|
||||
WORKDIR /build
|
||||
COPY package*.json ./
|
||||
RUN npm ci --omit=dev
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
FROM docker-hub-remote.bahnhub.tech.rz.db.de/node:22-slim
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=builder /build/dist ./dist
|
||||
COPY --from=builder /build/node_modules ./node_modules
|
||||
COPY package.json .
|
||||
|
||||
USER 1001
|
||||
EXPOSE 3000
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
|
||||
CMD node -e "fetch('http://localhost:3000/health').then(r=>{if(!r.ok)throw r})"
|
||||
|
||||
CMD ["node", "dist/index.js"]
|
||||
```
|
||||
|
||||
### Go (Scratch)
|
||||
```dockerfile
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM docker-hub-remote.bahnhub.tech.rz.db.de/golang:1.24 AS builder
|
||||
|
||||
WORKDIR /src
|
||||
COPY go.* ./
|
||||
RUN go mod download
|
||||
COPY . .
|
||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /app ./cmd/server
|
||||
|
||||
FROM scratch
|
||||
COPY --from=builder /app /app
|
||||
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
||||
|
||||
USER 65534
|
||||
EXPOSE 8080
|
||||
ENTRYPOINT ["/app"]
|
||||
```
|
||||
|
||||
## docker-compose.yml (Entwicklung)
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
platforms:
|
||||
- linux/amd64
|
||||
ports:
|
||||
- "8000:8000"
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- app-data:/app/data
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
volumes:
|
||||
app-data:
|
||||
```
|
||||
|
||||
## Build & Push Workflow
|
||||
|
||||
```bash
|
||||
# 1. Login ins Artifactory
|
||||
docker login einfachbahnlab-docker-stage-local.bahnhub.tech.rz.db.de
|
||||
# User: DeBi-Kürzel, Password: API-Key aus Artifactory-Profil
|
||||
|
||||
# 2. Build (IMMER mit platform!)
|
||||
docker build --platform linux/amd64 \
|
||||
-t einfachbahnlab-docker-stage-local.bahnhub.tech.rz.db.de/myapp:1.0.0 .
|
||||
|
||||
# 3. Push
|
||||
docker push einfachbahnlab-docker-stage-local.bahnhub.tech.rz.db.de/myapp:1.0.0
|
||||
```
|
||||
|
||||
## OpenShift-Kompatibilität Checkliste
|
||||
|
||||
- [ ] Base-Image aus `docker-hub-remote.bahnhub.tech.rz.db.de` (Mirror)
|
||||
- [ ] `USER 1001` (oder andere nicht-root UID) gesetzt
|
||||
- [ ] Keine `privileged`-Operationen (kein `apt-get` zur Laufzeit)
|
||||
- [ ] Schreibbare Pfade: `chmod 777` oder als Volume mounten
|
||||
- [ ] `HEALTHCHECK` definiert (wird für Liveness/Readiness-Probes genutzt)
|
||||
- [ ] Keine Secrets im Image — nur Env-Vars / K8s-Secrets
|
||||
- [ ] Festes Tag (semantisch), kein `:latest`
|
||||
- [ ] `--platform linux/amd64` beim Build
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Problem | Ursache | Lösung |
|
||||
|---------|---------|--------|
|
||||
| `exec format error` | Falsches Architektur | `--platform linux/amd64` beim Build |
|
||||
| `permission denied` auf Dateien | Non-root UID hat keinen Zugriff | `chmod 777` oder `chown 1001` |
|
||||
| `ImagePullBackOff` | Image nicht im Cluster erreichbar | Image-Pull-Secret prüfen, Registry-URL korrekt? |
|
||||
| `unauthorized` beim Push | Nicht eingeloggt oder kein Recht | `docker login` + API-Key prüfen, Repo existiert? |
|
||||
| Base-Image nicht gefunden | Docker-Hub-Mirror-Pfad falsch | `docker-hub-remote.bahnhub.tech.rz.db.de/<image>` |
|
||||
|
||||
## Best Practices
|
||||
|
||||
- **Multi-Stage Builds** — Build-Dependencies nicht im finalen Image
|
||||
- **`.dockerignore`** — `.git`, `__pycache__`, `node_modules`, `.env` ausschließen
|
||||
- **Reproducible Builds** — Lock-Files verwenden (`pip freeze`, `npm ci`)
|
||||
- **Kleine Images** — `slim` oder `alpine` Base-Images bevorzugen
|
||||
- **Layer-Caching** — Dependencies vor Source-Code kopieren
|
||||
- **SBOM** — Image-SBOM mit Syft generieren (pipeship macht das automatisch)
|
||||
Reference in New Issue
Block a user