Agent-almanac create-multistage-dockerfile
git clone https://github.com/pjt222/agent-almanac
T=$(mktemp -d) && git clone --depth=1 https://github.com/pjt222/agent-almanac "$T" && mkdir -p ~/.claude/skills && cp -r "$T/i18n/es/skills/create-multistage-dockerfile" ~/.claude/skills/pjt222-agent-almanac-create-multistage-dockerfile-03ea4a && rm -rf "$T"
i18n/es/skills/create-multistage-dockerfile/SKILL.mdCrear Dockerfile Multi-Etapa
Crear Dockerfiles multi-etapa para separar compilación de producción y obtener imágenes mínimas.
Cuándo Usar
- Las imágenes Docker de producción son demasiado grandes
- Necesitando separar herramientas de compilación de la imagen final
- Compilando binarios estáticos (Go, Rust) para imágenes minimales
- Ejecutando pruebas en la compilación sin incluirlas en producción
- Reduciendo la superficie de ataque eliminando herramientas innecesarias
Entradas
- Requerido: Código fuente de la aplicación
- Requerido: Proceso de compilación del proyecto
- Opcional: Suite de pruebas para ejecutar durante la compilación
- Opcional: Requisitos de imagen base para producción
Procedimiento
Paso 1: Diseñar las Etapas de Compilación
Identificar las etapas necesarias según el lenguaje.
# Patrón general de 3 etapas # Etapa 1: Dependencias # Etapa 2: Compilación # Etapa 3: Producción (imagen final)
Esperado: Separación clara entre etapas de compilación y producción.
En caso de fallo: Comenzar con 2 etapas (compilación + producción) y agregar más si es necesario.
Paso 2: Implementar para Lenguajes Compilados (Go)
# Etapa de compilación FROM golang:1.21-alpine AS builder RUN apk add --no-cache git ca-certificates WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /server . # Etapa de producción FROM scratch COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ COPY --from=builder /server /server ENTRYPOINT ["/server"]
Para Rust:
FROM rust:1.74-alpine AS builder WORKDIR /app COPY Cargo.toml Cargo.lock ./ RUN mkdir src && echo "fn main() {}" > src/main.rs RUN cargo build --release COPY src ./src RUN cargo build --release FROM alpine:3.18 COPY --from=builder /app/target/release/myapp /usr/local/bin/myapp CMD ["myapp"]
Esperado: La imagen final contiene solo el binario y dependencias mínimas de runtime.
En caso de fallo: Verificar que el binario es estáticamente enlazado (para
scratch), incluir certificados SSL si se necesita HTTPS.
Paso 3: Implementar para Lenguajes Interpretados (Node.js)
# Etapa de dependencias FROM node:20-alpine AS deps WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci --production # Etapa de compilación FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci COPY . . RUN npm run build # Etapa de producción FROM node:20-alpine RUN addgroup -S appgroup && adduser -S appuser -G appgroup WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY --from=builder /app/dist ./dist COPY package.json . USER appuser EXPOSE 3000 CMD ["node", "dist/index.js"]
Esperado: La imagen final no contiene devDependencies, archivos fuente ni herramientas de compilación.
En caso de fallo: Verificar que todos los archivos necesarios se copian desde las etapas correctas, probar la imagen final con todas las funcionalidades.
Paso 4: Agregar Etapa de Pruebas
FROM node:20-alpine AS builder WORKDIR /app COPY . . RUN npm ci RUN npm run build # Etapa de pruebas (no produce imagen, pero falla la compilación si las pruebas fallan) FROM builder AS tester RUN npm test # Etapa de producción (solo se alcanza si las pruebas pasan) FROM node:20-alpine COPY --from=builder /app/dist ./dist CMD ["node", "dist/index.js"]
# Compilar hasta la etapa de pruebas docker build --target tester -t mi-app:test . # Compilar imagen de producción (ejecuta pruebas automáticamente) docker build -t mi-app:latest .
Esperado: Las pruebas se ejecutan durante la compilación, la imagen de producción solo se crea si las pruebas pasan.
En caso de fallo: Usar
--target para compilar etapas individuales y depurar problemas.
Validación
- La imagen final es significativamente más pequeña que una compilación de una sola etapa
- No se incluyen herramientas de compilación en la imagen de producción
- Las pruebas se ejecutan durante la compilación
- La aplicación funciona correctamente en la imagen final
- Las capas de caché funcionan eficientemente entre etapas
Errores Comunes
- Copiar demasiado en la etapa final: Solo copiar artefactos necesarios con
.COPY --from= - No separar dependencias de compilación: Las devDependencies no deben estar en la imagen final.
- Olvidar certificados SSL: Las imágenes
no tienen certificados; copiarlos explícitamente.scratch - Caché de dependencias ineficiente: Copiar archivos de bloqueo antes del código fuente en cada etapa.
- No nombrar las etapas: Usar
para referencia clara en lugar de índices numéricos.AS nombre
Habilidades Relacionadas
- Patrones base de Dockerfilecreate-dockerfile
- Estrategias avanzadas de cachéoptimize-docker-build-cache
- Dockerfiles específicos para Rcreate-r-dockerfile