Compilaciones Docker Multi-Etapa para Go
Los Dockerfiles multi-etapa compilan Go en una imagen SDK completa, luego copian solo el binario (y las raíces de confianza necesarias) en una etapa de tiempo de ejecución mínima.
Busca en todas las páginas de la documentación
Los Dockerfiles multi-etapa compilan Go en una imagen SDK completa, luego copian solo el binario (y las raíces de confianza necesarias) en una etapa de tiempo de ejecución mínima.
El resultado son imágenes pequeñas que se descargan rápidamente y con menos paquetes del sistema para parchear.
Los binarios estáticos de Go se combinan de forma natural con tiempos de ejecución distroless o scratch.
Una canalización típica utiliza una etapa de compilación golang, emite salida CGO_ENABLED=0 y copia el ejecutable en gcr.io/distroless/static o una imagen scratch personalizada con certificados CA.
Los clientes HTTPS necesitan el paquete de certificados del sistema a menos que incrustes las raíces de otra manera.
Las monturas de caché de BuildKit para go mod download reducen el tiempo de CI sin hinchar las capas.
Tarjeta de receta de referencia rápida, lista para copiar y pegar.
# syntax=docker/dockerfile:1
FROM golang:1.26-bookworm AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod \
go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -trimpath \
-ldflags="-s -w" -o /out/api ./cmd/api
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=build /out/api /api
USER nonroot:nonroot
EXPOSE 8080
ENTRYPOINT ["/api"]Cuándo usar esto:
Dockerfile orientado a producción con certificados CA para TLS saliente:
# syntax=docker/dockerfile:1
FROM golang:1.26-bookworm AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod \
go mod download
COPY . .
ARG VERSION=dev
ARG COMMIT=none
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath \
-ldflags="-s -w -X main.version=${VERSION} -X main.commit=${COMMIT}" \
-o /out/api ./cmd/api
FROM debian:bookworm-slim AS certs
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates \
&& update-ca-certificates
FROM gcr.io/distroless/base-debian12:nonroot
COPY --from=build /out/api /api
COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
USER nonroot:nonroot
EXPOSE 8080
ENTRYPOINT ["/api"]docker build \
--build-arg VERSION=1.0.0 \
--build-arg COMMIT=$(git rev-parse --short HEAD) \
-t myorg/api:1.0.0 .Lo que esto demuestra:
go mod download en CI.certs dedicada copia solo ca-certificates.crt en distroless.nonroot evita ejecutarse como UID 0 dentro del contenedor.COPY --from= aparecen en el historial de la imagen final.CGO_ENABLED=0 evita los requisitos del cargador dinámico de glibc en Linux amd64/arm64.| Base | Shell | libc | Certificados CA | Tamaño Típico |
|---|---|---|---|---|
| scratch | No | No | Manual | El más pequeño |
| distroless/static | No | No | No | ~2 MB + binario |
| distroless/base | No | Sí | Sí | ~20 MB + binario |
| alpine | Sí | musl | Sí | Más grande, libc diferente |
# Verifica que el binario sea estático antes de elegir scratch
CGO_ENABLED=0 go build -o api ./cmd/api
file api # espera "statically linked"
ldd api # espera "not a dynamic executable" en LinuxCGO_ENABLED=1; prefiere constructores de debian bookworm para cgo.-trimpath elimina $PWD de los binarios para auditorías de cadena de suministro.GOAMD64=v3 solo cuando controles la línea base de la CPU y quieras instrucciones SIMD más nuevas.RUN --mount=type=cache,target=/root/.cache/go-build \
CGO_ENABLED=0 go build -o /out/api ./cmd/apigolang:1.26-bookworm@sha256:....docker scout cves o tu escáner en la etiqueta de la etapa final, no en la del constructor.distroless/static fallan los handshakes TLS hasta que copias ca-certificates.crt.CGO_ENABLED=0./usr/share/zoneinfo; establece TZ o copia zoneinfo si los logs necesitan la hora local.kubectl exec en distroless; confía en logs, métricas y pods de depuración efímeros con herramientas.CAP_NET_BIND_SERVICE deliberadamente.Elige scratch cuando el binario no realiza HTTPS saliente y necesita la imagen más pequeña posible.
Elige distroless/base cuando necesites libc, comportamiento del resolvedor DNS y certificados CA sin mantener una disposición scratch personalizada.
Ejecuta apt-get install ca-certificates en una etapa de debian desechable, luego COPY --from=certs /etc/ssl/certs/ca-certificates.crt en distroless.
Nunca ejecutes apt en la etapa de tiempo de ejecución.
Es posible que estés etiquetando accidentalmente la etapa de compilación, o copiando fixtures de prueba y cachés de compilación.
Inspecciona con docker history myorg/api:tag y asegúrate de que la etiqueta publicada apunte a la etapa final.
Raramente para microservicios en la nube.
UPX puede activar falsos positivos de antivirus y añade un coste de descompresión al inicio.
Prefiere -ldflags="-s -w" y grafos de dependencias más pequeños primero.
Escucha en 8080 dentro del contenedor y deja que Ingress mapee el puerto 443/80.
Alternativamente, usa una configuración de capacidad sin root, pero los puertos altos son el patrón común de Kubernetes.
Versiones de Stack: Esta página fue escrita para Go 1.26.x (predeterminado Green Tea GC, go fix modernizers - verifica el parche en la compilación), chi (última versión - verifica en la compilación), gin (última versión - verifica en la compilación), echo (última versión - verifica en la compilación), google.golang.org/grpc (última versión - verifica en la compilación), sigs.k8s.io/controller-runtime (última versión - verifica en la compilación), kubebuilder (última versión - verifica en la compilación), tinygo (última versión - verifica los objetivos de placa en la compilación), wazero (última versión - verifica en la compilación) y golangci-lint (última versión - verifica el conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 16 jul 2026