---
title: "Rust para DevOps: Ferramentas e CLI | Rust Brasil"
url: "https://rustlang.com.br/artigos/rust-para-devops/"
markdown_url: "https://rustlang.com.br/artigos/rust-para-devops.MD"
description: "Rust para DevOps: ferramentas CLI, containers, infrastructure as code e automação. Guia prático em português."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# Rust para DevOps: Ferramentas e CLI | Rust Brasil

Rust para DevOps: ferramentas CLI, containers, infrastructure as code e automação. Guia prático em português.


## Introdução

O mundo DevOps está sendo silenciosamente transformado por Rust. Enquanto [Go](https://golang.com.br) dominou a primeira onda de ferramentas cloud-native (Docker, Kubernetes, Terraform), uma nova geração de ferramentas de infraestrutura está sendo construída em Rust, aproveitando sua **performance superior**, **consumo mínimo de memória** e **segurança de memória**. Projetos como **Firecracker** (microVMs da AWS Lambda), **Bottlerocket** (OS para containers da Amazon), **Vector** (pipeline de observabilidade) e **Turbopack** (bundler da Vercel) demonstram que Rust é a escolha ideal para software de infraestrutura que precisa ser rápido, confiável e eficiente.

Para engenheiros DevOps e SRE, Rust também oferece vantagens práticas: binários estáticos sem dependências de runtime facilitam deployment, imagens Docker minúsculas reduzem tempo de pull e consumo de storage, e a ausência de garbage collector garante latência previsível — essencial para proxies, load balancers e agentes de monitoramento.

## Ferramentas de Infraestrutura Escritas em Rust

| Ferramenta | Categoria | Descrição |
|---|---|---|
| **Firecracker** | Virtualização | MicroVMs da AWS — motor por trás do Lambda e Fargate |
| **Bottlerocket** | Sistema Operacional | OS minimalista para containers, mantido pela Amazon |
| **Vector** | Observabilidade | Pipeline de dados unificado (logs, métricas, traces) |
| **Tikv** | Banco de dados | Key-value store distribuído (usado pelo PingCAP/TiDB) |
| **Linkerd2-proxy** | Service Mesh | Data plane do Linkerd, proxy ultrarrápido |
| **nushell** | Shell | Shell moderno com output estruturado |
| **just** | Build | Task runner (alternativa a Makefile) |
| **watchexec** | Automação | Executor de comandos baseado em file watchers |
| **delta** | Git | Visualizador de diffs com syntax highlighting |
| **gitoxide** | Git | Implementação de Git em Rust (usado pelo cargo) |

## Otimização de Imagens Docker para Rust

Uma das maiores vantagens de Rust para DevOps é a capacidade de criar imagens Docker extremamente pequenas. Veja como otimizar:

### Dockerfile Multi-Stage Otimizado

```dockerfile
# === Stage 1: Build ===
FROM rust:1.85-bookworm AS builder

# Criar projeto vazio para cache de dependências
WORKDIR /app
RUN cargo init --name meu-servico
COPY Cargo.toml Cargo.lock ./
RUN cargo build --release && rm -rf src

# Copiar código real e compilar
COPY src ./src
RUN touch src/main.rs && cargo build --release

# === Stage 2: Runtime ===
FROM debian:bookworm-slim

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

# Criar usuário não-root
RUN useradd --create-home --shell /bin/bash app
USER app

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

EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
    CMD curl -f http://localhost:8080/health || exit 1

ENTRYPOINT ["meu-servico"]
```

### Build Estático com musl (Imagem Scratch)

Para imagens ainda menores, compile com musl e use uma imagem `scratch` (vazia):

```dockerfile
FROM rust:1.85-bookworm AS builder
RUN rustup target add x86_64-unknown-linux-musl
RUN apt-get update && apt-get install -y musl-tools

WORKDIR /app
COPY . .
RUN cargo build --release --target x86_64-unknown-linux-musl

# Imagem final: apenas o binário, sem sistema operacional
FROM scratch
COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/meu-servico /
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

EXPOSE 8080
ENTRYPOINT ["/meu-servico"]
```

### Comparação de Tamanhos

| Abordagem | Tamanho da Imagem |
|---|---|
| `rust:1.85` (sem multi-stage) | ~1.5 GB |
| Debian slim + binário | ~80 MB |
| Alpine + binário musl | ~15 MB |
| Scratch + binário musl | ~5-10 MB |
| Distroless + binário | ~20 MB |

Compare com uma imagem Node.js típica (~300MB) ou Python (~400MB). Rust permite reduzir o tamanho em 95%.

## GitHub Actions para Projetos Rust

### Pipeline CI/CD Completo

```yaml
name: CI/CD Rust

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

env:
  CARGO_TERM_COLOR: always
  RUSTFLAGS: "-Dwarnings"

jobs:
  check:
    name: Verificação de Qualidade
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy

      - uses: Swatinem/rust-cache@v2

      - name: Verificar formatação
        run: cargo fmt --all -- --check

      - name: Executar Clippy (linter)
        run: cargo clippy --all-targets --all-features

  test:
    name: Testes
    runs-on: ubuntu-latest
    needs: check
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: teste
          POSTGRES_DB: app_teste
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2

      - name: Executar testes
        run: cargo test --all-features
        env:
          DATABASE_URL: postgres://postgres:teste@localhost:5432/app_teste

      - name: Testes de integração
        run: cargo test --test '*' -- --ignored
        env:
          DATABASE_URL: postgres://postgres:teste@localhost:5432/app_teste

  build-and-push:
    name: Build e Push Docker
    runs-on: ubuntu-latest
    needs: test
    if: github.ref == 'refs/heads/main'
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v4

      - name: Login no GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build e push
        uses: docker/build-push-action@v6
        with:
          push: true
          tags: |
            ghcr.io/${{ github.repository }}:latest
            ghcr.io/${{ github.repository }}:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
```

## Exemplo Prático: Ferramenta de Monitoramento de Infraestrutura

Vamos construir uma CLI que verifica a saúde de múltiplos serviços e exibe um dashboard no terminal.

```toml
[package]
name = "infra-monitor"
version = "0.1.0"
edition = "2021"

[dependencies]
tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.12", features = ["json"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
clap = { version = "4", features = ["derive"] }
colored = "2"
anyhow = "1"
chrono = "0.4"
```

```rust
use anyhow::Result;
use chrono::Local;
use clap::Parser;
use colored::*;
use serde::Deserialize;
use std::time::{Duration, Instant};

#[derive(Parser)]
#[command(name = "infra-monitor")]
#[command(about = "Monitor de saúde de infraestrutura")]
struct Cli {
    /// Arquivo de configuração com endpoints
    #[arg(short, long, default_value = "endpoints.json")]
    config: String,

    /// Intervalo entre verificações (segundos)
    #[arg(short, long, default_value_t = 30)]
    intervalo: u64,

    /// Executar uma vez e sair
    #[arg(short = '1', long)]
    uma_vez: bool,
}

#[derive(Debug, Deserialize)]
struct Endpoint {
    nome: String,
    url: String,
    #[serde(default = "timeout_padrao")]
    timeout_ms: u64,
    #[serde(default)]
    esperar_status: Option<u16>,
}

fn timeout_padrao() -> u64 {
    5000
}

#[derive(Debug)]
struct ResultadoVerificacao {
    nome: String,
    url: String,
    status: StatusVerificacao,
    latencia: Duration,
}

#[derive(Debug)]
enum StatusVerificacao {
    Ok(u16),
    StatusInesperado(u16),
    Timeout,
    Erro(String),
}

async fn verificar_endpoint(
    client: &reqwest::Client,
    endpoint: &Endpoint,
) -> ResultadoVerificacao {
    let inicio = Instant::now();

    let resultado = client
        .get(&endpoint.url)
        .timeout(Duration::from_millis(endpoint.timeout_ms))
        .send()
        .await;

    let latencia = inicio.elapsed();

    let status = match resultado {
        Ok(resp) => {
            let codigo = resp.status().as_u16();
            match endpoint.esperar_status {
                Some(esperado) if codigo != esperado => {
                    StatusVerificacao::StatusInesperado(codigo)
                }
                _ if codigo >= 200 && codigo < 400 => {
                    StatusVerificacao::Ok(codigo)
                }
                _ => StatusVerificacao::StatusInesperado(codigo),
            }
        }
        Err(e) if e.is_timeout() => StatusVerificacao::Timeout,
        Err(e) => StatusVerificacao::Erro(e.to_string()),
    };

    ResultadoVerificacao {
        nome: endpoint.nome.clone(),
        url: endpoint.url.clone(),
        status,
        latencia,
    }
}

fn exibir_resultados(resultados: &[ResultadoVerificacao]) {
    let agora = Local::now().format("%Y-%m-%d %H:%M:%S");
    println!("\n{}", format!("═══ Health Check — {} ═══", agora).bold().cyan());

    let mut ok_count = 0;
    let mut fail_count = 0;

    for r in resultados {
        let (icone, status_texto) = match &r.status {
            StatusVerificacao::Ok(codigo) => {
                ok_count += 1;
                ("OK".green().bold(), format!("{}", codigo).green())
            }
            StatusVerificacao::StatusInesperado(codigo) => {
                fail_count += 1;
                ("WARN".yellow().bold(), format!("{}", codigo).yellow())
            }
            StatusVerificacao::Timeout => {
                fail_count += 1;
                ("TIMEOUT".red().bold(), "timeout".red())
            }
            StatusVerificacao::Erro(msg) => {
                fail_count += 1;
                ("ERRO".red().bold(), msg.as_str().red())
            }
        };

        let latencia_texto = if r.latencia.as_millis() > 1000 {
            format!("{:.1}s", r.latencia.as_secs_f64()).red()
        } else if r.latencia.as_millis() > 300 {
            format!("{}ms", r.latencia.as_millis()).yellow()
        } else {
            format!("{}ms", r.latencia.as_millis()).green()
        };

        println!(
            "  [{}] {} — {} ({})",
            icone,
            r.nome.white().bold(),
            status_texto,
            latencia_texto
        );
    }

    println!(
        "\n  Resumo: {} {} | {} {}",
        ok_count.to_string().green().bold(),
        "saudáveis".green(),
        fail_count.to_string().red().bold(),
        "com problemas".red()
    );
}

#[tokio::main]
async fn main() -> Result<()> {
    let cli = Cli::parse();

    let config_conteudo = std::fs::read_to_string(&cli.config)?;
    let endpoints: Vec<Endpoint> = serde_json::from_str(&config_conteudo)?;

    let client = reqwest::Client::builder()
        .user_agent("infra-monitor/0.1.0")
        .build()?;

    loop {
        let mut handles = Vec::new();
        for endpoint in &endpoints {
            let client = client.clone();
            let endpoint_clone = Endpoint {
                nome: endpoint.nome.clone(),
                url: endpoint.url.clone(),
                timeout_ms: endpoint.timeout_ms,
                esperar_status: endpoint.esperar_status,
            };
            handles.push(tokio::spawn(async move {
                verificar_endpoint(&client, &endpoint_clone).await
            }));
        }

        let mut resultados = Vec::new();
        for handle in handles {
            resultados.push(handle.await?);
        }

        exibir_resultados(&resultados);

        if cli.uma_vez {
            break;
        }

        tokio::time::sleep(Duration::from_secs(cli.intervalo)).await;
    }

    Ok(())
}
```

### Arquivo de Configuração (endpoints.json)

```json
[
    {
        "nome": "API Principal",
        "url": "https://api.meusite.com.br/health",
        "timeout_ms": 3000,
        "esperar_status": 200
    },
    {
        "nome": "Frontend",
        "url": "https://meusite.com.br",
        "timeout_ms": 5000
    },
    {
        "nome": "Banco de Dados (proxy)",
        "url": "http://db-proxy:8080/health",
        "timeout_ms": 2000,
        "esperar_status": 200
    }
]
```

## Empresas Usando Rust em DevOps e Infraestrutura

- **Amazon Web Services**: Firecracker (Lambda, Fargate), Bottlerocket OS, S3 components, IAM services
- **Cloudflare**: Pingora (proxy HTTP que substitui o Nginx), Workers runtime, ferramentas de rede
- **Datadog**: Agent components para alta performance em coleta de métricas
- **Timber/Vector**: Pipeline unificado de observabilidade usado por milhares de empresas
- **Vercel**: Turbopack (bundler), turborepo components
- **1Password**: Infraestrutura de backend e criptografia
- **Fly.io**: Components do runtime de microVMs
- **Linkerd**: Data plane proxy do service mesh

## Como Começar

1. **Aprenda Rust**: [Tutorial de primeiros passos](/tutoriais/primeiros-passos/) e [tratamento de erros](/tutoriais/tratamento-de-erros/)
2. **Configure Docker**: Siga nosso [guia de Docker para Rust](/instalacao/docker/) para builds otimizados
3. **Configure CI/CD**: Use nosso [guia de GitHub Actions](/instalacao/github-actions/) para pipelines Rust
4. **Construa CLIs**: Muitas ferramentas DevOps começam como CLIs — veja [Rust para CLIs](/artigos/rust-para-cli/)
5. **Async Rust**: Essencial para ferramentas de networking — [receita de async/await](/receitas/async-await-basico/)
6. **HTTP requests**: Aprenda a fazer [requisições HTTP](/receitas/fazer-requisicao-http/) com reqwest

## Conclusão

Rust está se consolidando como a linguagem de escolha para a próxima geração de ferramentas de infraestrutura. Se Go trouxe Docker e Kubernetes, Rust está trazendo microVMs, proxies de alta performance, pipelines de observabilidade e sistemas operacionais para containers. Para engenheiros DevOps e SRE, aprender Rust é um investimento que se paga tanto em ferramentas melhores quanto em oportunidades profissionais crescentes.

---

## Veja Também

- [Guia: Docker para Rust](/instalacao/docker/) — Otimize suas imagens Docker
- [Guia: GitHub Actions para Rust](/instalacao/github-actions/) — Configure CI/CD profissional
- [Rust para CLI](/artigos/rust-para-cli/) — Construa ferramentas de linha de comando
- [Rust para Microsserviços](/artigos/rust-para-microsservicos/) — gRPC, filas e deploy em produção
- [Rust para Desenvolvimento Web](/artigos/rust-para-web/) — APIs e backends com Axum
- [Receita: Variáveis de Ambiente](/receitas/variaveis-ambiente/) — Configuração de aplicações
- [Receita: Fazer Requisição HTTP](/receitas/fazer-requisicao-http/) — Comunicação entre serviços
- [Go Brasil](https://golang.com.br) — Go continua sendo essencial no DevOps — conheça o ecossistema completo em português
