Agent-almanac create-dockerfile
install
source · Clone the upstream repo
git clone https://github.com/pjt222/agent-almanac
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/pjt222/agent-almanac "$T" && mkdir -p ~/.claude/skills && cp -r "$T/i18n/de/skills/create-dockerfile" ~/.claude/skills/pjt222-agent-almanac-create-dockerfile-6ff3d5 && rm -rf "$T"
manifest:
i18n/de/skills/create-dockerfile/SKILL.mdsource content
Dockerfile erstellen
Ein produktionsreifes Dockerfile fuer allgemeine Anwendungsprojekte schreiben.
Wann verwenden
- Containerisieren einer Node.js-, Python-, Go-, Rust- oder Java-Anwendung
- Erstellen einer konsistenten Build-/Laufzeitumgebung
- Vorbereiten einer Anwendung fuer Cloud-Deployment oder Docker Compose
- Kein bestehendes Dockerfile im Projekt vorhanden
Eingaben
- Erforderlich: Projektsprache und Einstiegspunkt (z.B.
,npm start
)python app.py - Erforderlich: Abhaengigkeitsmanifest (package.json, requirements.txt, go.mod, Cargo.toml, pom.xml)
- Optional: Zielumgebung (Entwicklung oder Produktion)
- Optional: Freigegebene Ports
Vorgehensweise
Schritt 1: Basisimage waehlen
| Sprache | Entwicklungs-Image | Produktions-Image | Groesse |
|---|---|---|---|
| Node.js | | | ~200MB |
| Python | | | ~150MB |
| Go | | | ~2MB |
| Rust | | | ~80MB |
| Java | | | ~200MB |
Erwartet: Die slim/distroless-Variante fuer Produktions-Images auswaehlen.
Schritt 2: Dockerfile schreiben (nach Sprache)
Node.js
FROM node:22-bookworm-slim RUN groupadd -r appuser && useradd -r -g appuser -m appuser WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci --omit=dev COPY . . USER appuser EXPOSE 3000 CMD ["node", "src/index.js"]
Python
FROM python:3.12-slim-bookworm RUN groupadd -r appuser && useradd -r -g appuser -m appuser WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . USER appuser EXPOSE 8000 CMD ["python", "app.py"]
Go
FROM golang:1.23-bookworm AS builder WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 go build -o /app/server ./cmd/server FROM gcr.io/distroless/static COPY --from=builder /app/server /server EXPOSE 8080 ENTRYPOINT ["/server"]
Rust
FROM rust:1.82-bookworm AS builder WORKDIR /src COPY Cargo.toml Cargo.lock ./ RUN mkdir src && echo "fn main() {}" > src/main.rs && cargo build --release && rm -rf src COPY . . RUN touch src/main.rs && cargo build --release FROM debian:bookworm-slim RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/* COPY --from=builder /src/target/release/myapp /usr/local/bin/myapp EXPOSE 8080 ENTRYPOINT ["myapp"]
Java (Maven)
FROM eclipse-temurin:21-jdk AS builder WORKDIR /src COPY pom.xml . RUN mvn dependency:go-offline -B COPY src ./src RUN mvn package -DskipTests FROM eclipse-temurin:21-jre COPY --from=builder /src/target/*.jar /app/app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "/app/app.jar"]
Erwartet:
docker build -t myapp . wird fehlerfrei abgeschlossen.
Bei Fehler: Verfuegbarkeit des Basisimages und Abhaengigkeitsinstallationsbefehle pruefen.
Schritt 3: ENTRYPOINT vs CMD
| Direktive | Zweck | Ueberschreiben |
|---|---|---|
| Feste ausfuehrbare Datei | Ueberschreiben mit |
| Standardargumente | Ueberschreiben mit nachfolgenden Argumenten |
| Beide | + Standardargumente ueber | Argumente ueberschreiben nur CMD |
ENTRYPOINT fuer kompilierte Binaerdateien mit einem einzigen Zweck verwenden. CMD fuer interpretierte Sprachen verwenden, bei denen man evtl. docker run myapp bash ausfuehren moechte.
Schritt 4: .dockerignore erstellen
.git .gitignore node_modules __pycache__ *.pyc target/ .env .env.* *.md !README.md .vscode .idea Dockerfile docker-compose*.yml
Erwartet: Build-Kontext schliesst Entwicklungsartefakte aus.
Schritt 5: Nicht-Root-Benutzer hinzufuegen
In Produktion immer als Nicht-Root ausfuehren:
RUN groupadd -r appuser && useradd -r -g appuser -m appuser USER appuser
Fuer distroless-Images den eingebauten nonroot-Benutzer verwenden:
FROM gcr.io/distroless/static:nonroot USER nonroot
Schritt 6: Bauen und Ueberpruefen
docker build -t myapp:latest . docker run --rm myapp:latest docker image inspect myapp:latest --format '{{.Size}}'
Erwartet: Container startet, antwortet auf dem erwarteten Port, laeuft als Nicht-Root.
Bei Fehler: Logs mit
docker logs pruefen. WORKDIR, COPY-Pfade und freigegebene Ports ueberpruefen.
Validierung
-
wird fehlerfrei abgeschlossendocker build - Container startet und Anwendung antwortet
-
schliesst unnoetige Dateien aus.dockerignore - Anwendung laeuft als Nicht-Root-Benutzer
- Abhaengigkeiten werden vor dem Quellcode kopiert (Cache-Effizienz)
- Keine Secrets oder
-Dateien im Image eingebacken.env
Haeufige Fehler
- COPY vor Abhaengigkeitsinstallation: Invalidiert den Abhaengigkeits-Cache bei jeder Code-Aenderung. Immer zuerst die Manifestdatei kopieren.
- Als Root ausfuehren: Standard-Docker-Benutzer ist Root. Fuer Produktion immer einen Nicht-Root-Benutzer hinzufuegen.
- Fehlende .dockerignore: Das Senden von
odernode_modules
in den Build-Kontext verschwendet Zeit und Speicherplatz..git
-Tag fuer Basisimages verwenden: Auf bestimmte Versionen pinnen (z.B.latest
) fuer Reproduzierbarkeit.node:22.11.0
vergessen: Python--no-cache-dir
cached Pakete standardmaessig und blaeht das Image auf.pip- ADD vs COPY:
verwenden, es sei denn, URL-Download oder Tar-Extraktion wird benoetigt (COPY
extrahiert automatisch).ADD
Verwandte Skills
- R-spezifisches Dockerfile mit rocker-Imagescreate-r-dockerfile
- Multi-Stage-Muster fuer minimale Produktions-Imagescreate-multistage-dockerfile
- Erweiterte Caching-Strategienoptimize-docker-build-cache
- Die containerisierte App mit anderen Diensten orchestrierensetup-compose-stack