Imagens Docker Mínimas
Serviços Rust se encaixam em contêineres pequenos: builds multi-stage compilam em uma imagem "gorda", depois copiam um único binário para distroless ou scratch (com certificados CA se usar HTTPS).
Receita
# syntax=docker/dockerfile:1
FROM rust:1.97-bookworm AS builder
WORKDIR /app
COPY . .
RUN cargo build --release --locked
FROM gcr.io/distroless/cc-debian12
COPY --from=builder /app/target/release/my-service /my-service
USER nonroot:nonroot
ENTRYPOINT ["/my-service"]Quando usar isso:
- Implantações de produção no Kubernetes
- Redução da superfície de ataque e tempo de pull da imagem
- Requisitos de conformidade que proíbem shells em imagens de runtime
Exemplo de Trabalho
FROM rust:1.97-bookworm AS builder
WORKDIR /app
# Cache de dependências
COPY Cargo.toml Cargo.lock ./
RUN mkdir src && echo "fn main() {}" > src/main.rs
RUN cargo build --release && rm -rf src
COPY . .
RUN cargo build --release --locked
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/my-service /usr/local/bin/my-service
EXPOSE 8080
ENTRYPOINT ["/usr/local/bin/my-service"]O que isso demonstra:
- O cache de camadas de dependência acelera as reconstruções
- A imagem de runtime tem apenas o binário mais o bundle de CA
- Usuário não root na variante distroless
Mergulho Profundo
Alavancas de Tamanho da Imagem
| Técnica | Economia |
|---|---|
| Multi-stage | Sem toolchain Rust no runtime |
strip = true no perfil de release | Binário menor |
Binário estático musl + scratch | Sem camada libc |
LTO lto = "thin" | Binário menor, compilação mais lenta |
HTTPS a partir do Distroless
Variantes cc ou static do Distroless incluem raízes de CA; scratch puro requer cópia manual de ca-certificates.
Armadilhas
- Executando como root - impacto de escape do contêiner. Correção:
USER nonrootou distroless nonroot. - Falta de
ca-certificates- TLS falha misteriosamente. Correção: copiar certificados ou usar distroless cc. - Compilando no estágio de runtime - imagens enormes. Correção: separação estrita multi-stage.
- Sem shell para depuração - inspeção ad-hoc mais difícil. Correção: pods de depuração efêmeros com imagem de toolkit.
Cargo.lockdesatualizado no Docker - builds não reproduzíveis. Correção:--lockede commit do lockfile.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
wolfi / chainguard | Base mínima reforçada | Equipe padronizada em distroless |
debian:slim completo + shell | Ops quer depuração com docker exec | Política mínima estrita |
kaniko / buildkit em CI | Sem daemon Docker no runner | Fluxos de trabalho apenas locais |
FAQs
scratch vs distroless?
scratch está vazio; você deve fornecer certificados e o linker dinâmico se não for totalmente estático. Distroless inclui libc.
Qual o tamanho da imagem?
Binários Axum de serviço único geralmente ficam entre 15-40 MB comprimidos com bases slim; poucos MB com musl+scratch.
Builds de Workspace no Docker?
Copie o workspace completo; cargo build -p my-service --release a partir da raiz.
Distroless e glibc?
Combine a versão Debian do builder com a tag distroless para evitar incompatibilidades de glibc.
Relacionados
- Noções básicas de implantação
- musl e linkagem estática
- CI/CD para Rust
- Configuração e segredos em produção
Versões da Stack: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4 e Polars 0.46+.