Docker e Rust: conteinerização de aplicações de nível avançado

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course
```html

Docker e Rust: conteinerização de aplicações de nível avançado



A conteinerização de aplicações Rust com Docker não é apenas empacotar código em uma imagem. Em nível avançado, é a arte de criar contêineres mínimos, rápidos e seguros que são ideais para ambientes de produção. Rust, como linguagem de programação de sistemas, compila para código nativo, o que oferece oportunidades únicas para otimizar imagens Docker. Neste artigo, exploraremos técnicas que vão além do básico docker build e mostraremos como criar contêineres eficientes para aplicações Rust.



1. Build multi-estágio (Multi-stage build) para Rust



O build multi-estágio é a pedra angular da conteinerização avançada em Rust. Ele permite separar o ambiente de build (com compilador, dependências e ferramentas) da imagem final, que contém apenas o arquivo binário compilado e as dependências de runtime necessárias.



Considere o exemplo de Dockerfile para um servidor web em actix-web:



# Estágio 1: BuildFROM rust:1.75-slim-bullseye AS builder

WORKDIR /app

# Copiamos apenas os arquivos de dependências para cache de camadasCOPY Cargo.toml Cargo.lock ./

# Criamos um main.rs vazio para compilar as dependênciasRUN mkdir src && echo "fn main() {}" > src/main.rsRUN cargo build --release 2>/dev/null || true

# Agora copiamos o código-fonte realCOPY src ./src

# Recompilamos apenas os arquivos alterados (cache de dependências intacto)RUN cargo build --release

# Estágio 2: Imagem finalFROM debian:bullseye-slim

RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ libssl1.1 \ && rm -rf /var/lib/apt/lists/*

COPY --from=builder /app/target/release/my_app /usr/local/bin/my_app

USER nobodyEXPOSE 8080

CMD ["/usr/local/bin/my_app"]


Otimizações principais:

  • Cache de dependências: Primeiro, apenas Cargo.toml e Cargo.lock são copiados, e então as dependências são compiladas. Isso permite que o Docker use o cache de camadas se os arquivos de manifesto não forem alterados.
  • Imagem final mínima: Usamos debian:bullseye-slim em vez da imagem completa do Rust. Isso reduz o tamanho de ~1.5 GB para ~150 MB.
  • Segurança: A aplicação é executada como usuário nobody, não como root.


2. Minimização do tamanho da imagem: do Alpine ao scratch



Aplicações Rust não exigem um ambiente de runtime como a máquina virtual Java ou o interpretador Python. Isso permite o uso de imagens base mínimas.



Opção com Alpine Linux:

FROM alpine:3.19 AS builderRUN apk add --no-cache musl-dev# ... build ...

FROM alpine:3.19RUN apk add --no-cache ca-certificatesCOPY --from=builder /app/target/release/my_app /my_appCMD ["/my_app"]


Opção com scratch (imagem vazia):

FROM alpine:3.19 AS builderRUN apk add --no-cache musl-dev# Build com linkagem estáticaRUN cargo build --release --target x86_64-unknown-linux-musl

FROM scratchCOPY --from=builder /app/target/x86_64-unknown-linux-musl/release/my_app /my_appCOPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/CMD ["/my_app"]


Comparação de tamanhos de imagens:

  • debian:bullseye-slim: ~80-150 MB (depende da quantidade de bibliotecas do sistema)
  • alpine:3.19: ~10-20 MB (usa musl libc em vez de glibc)
  • scratch: ~5-10 MB (apenas binário e certificados)


Importante: Ao usar scratch, é necessário garantir que sua aplicação não exija bibliotecas dinâmicas. Para isso, use linkagem estática com o alvo ```

Blogs

Book Recommendations