Rust

O que Todo Dev Deve Saber sobre Deploy de Aplicações Rust em VPS com Docker e Nginx

6 min de leitura

O que Todo Dev Deve Saber sobre Deploy de Aplicações Rust em VPS com Docker e Nginx

Preparando sua Aplicação Rust para Produção Antes de fazer deploy, sua aplicação Rust precisa estar otimizada. O modo release é obrigatório em produção, pois oferece performance significativamente superior ao modo debug. Configure seu com perfis adequados para garantir binários eficientes e tempos de inicialização rápidos. Compile sua aplicação com . Isso gera um executável otimizado em . Para aplicações web, recomendo usar frameworks como Axum ou Actix-web. Aqui está um exemplo simples com Axum que funciona perfeitamente em produção: Adicione ao seu : e . Containerizando com Docker Docker garante que sua aplicação rode identicamente em qualquer VPS. Um bom Dockerfile usa multistage build para reduzir o tamanho final da imagem, eliminando dependências de compilação desnecessárias. Este Dockerfile reduz a imagem final de ~2GB para ~100MB aproximadamente. O primeiro estágio compila tudo, enquanto o segundo estágio contém apenas o binário e dependências mínimas. Crie um para acelerar o build: Configurando Nginx como Reverse Proxy O Nginx atua como intermediário entre

<h2>Preparando sua Aplicação Rust para Produção</h2>

<p>Antes de fazer deploy, sua aplicação Rust precisa estar otimizada. O modo release é obrigatório em produção, pois oferece performance significativamente superior ao modo debug. Configure seu <code>Cargo.toml</code> com perfis adequados para garantir binários eficientes e tempos de inicialização rápidos.</p>

<pre><code class="language-toml">[profile.release]

opt-level = 3

lto = true

codegen-units = 1

strip = true</code></pre>

<p>Compile sua aplicação com <code>cargo build --release</code>. Isso gera um executável otimizado em <code>target/release/seu_app</code>. Para aplicações web, recomendo usar frameworks como Axum ou Actix-web. Aqui está um exemplo simples com Axum que funciona perfeitamente em produção:</p>

<pre><code class="language-rust">use axum::{routing::get, Router};

use std::net::SocketAddr;

#[tokio::main]

async fn main() {

let app = Router::new()

.route(&quot;/&quot;, get( | | async { &quot;Deploy concluído!&quot; })) .route(&quot;/health&quot;, get(|| async { &quot;OK&quot; }));

let addr = SocketAddr::from(([0, 0, 0, 0], 3000));

let listener = tokio::net::TcpListener::bind(addr).await.unwrap();

axum::serve(listener, app).await.unwrap();

}</code></pre>

<p>Adicione ao seu <code>Cargo.toml</code>: <code>axum = &quot;0.7&quot;</code> e <code>tokio = { version = &quot;1&quot;, features = [&quot;full&quot;] }</code>.</p>

<h2>Containerizando com Docker</h2>

<p>Docker garante que sua aplicação rode identicamente em qualquer VPS. Um bom Dockerfile usa multistage build para reduzir o tamanho final da imagem, eliminando dependências de compilação desnecessárias.</p>

<pre><code class="language-dockerfile"># Stage 1: Build

FROM rust:latest as builder

WORKDIR /app

COPY . .

RUN cargo build --release

Stage 2: Runtime

FROM debian:bookworm-slim

RUN apt-get update &amp;&amp; apt-get install -y ca-certificates &amp;&amp; rm -rf /var/lib/apt/lists/*

WORKDIR /app

COPY --from=builder /app/target/release/seu_app .

EXPOSE 3000

CMD [&quot;./seu_app&quot;]</code></pre>

<p>Este Dockerfile reduz a imagem final de ~2GB para ~100MB aproximadamente. O primeiro estágio compila tudo, enquanto o segundo estágio contém apenas o binário e dependências mínimas. Crie um <code>.dockerignore</code> para acelerar o build:</p>

<pre><code>target/

.git/

.env

.env.local</code></pre>

<h2>Configurando Nginx como Reverse Proxy</h2>

<p>O Nginx atua como intermediário entre internet e sua aplicação, gerenciando SSL, compressão e roteamento. Sua aplicação Rust escuta internamente na porta 3000, enquanto o Nginx expõe as portas 80 e 443 publicamente.</p>

<p>Crie um arquivo <code>nginx.conf</code> na raiz do seu projeto:</p>

<pre><code class="language-nginx">upstream rust_app {

server app:3000;

}

server {

listen 80;

server_name seu_dominio.com www.seu_dominio.com;

location / {

proxy_pass http://rust_app;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Forwarded-Proto $scheme;

proxy_http_version 1.1;

proxy_set_header Connection &quot;&quot;;

}

location /health {

access_log off;

proxy_pass http://rust_app;

}

}</code></pre>

<p>Para HTTPS com Let&#039;s Encrypt, use Certbot via Docker ou acesse manualmente na VPS. O nome <code>app</code> refere-se ao serviço Docker definido no <code>docker-compose.yml</code>.</p>

<h2>Deploy em VPS com Docker Compose</h2>

<p>Docker Compose orquestra seus contêineres, simplificando gerenciamento em produção. Crie um <code>docker-compose.yml</code>:</p>

<pre><code class="language-yaml">version: &#039;3.8&#039;

services:

app:

build: .

container_name: rust_app

restart: always

networks:

  • app_network

healthcheck:

test: [&quot;CMD&quot;, &quot;curl&quot;, &quot;-f&quot;, &quot;http://localhost:3000/health&quot;]

interval: 30s

timeout: 10s

retries: 3

nginx:

image: nginx:alpine

container_name: nginx_proxy

restart: always

ports:

  • &quot;80:80&quot;
  • &quot;443:443&quot;

volumes:

  • ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
  • ./certs:/etc/nginx/certs:ro

depends_on:

  • app

networks:

  • app_network

networks:

app_network:

driver: bridge</code></pre>

<p>Na VPS, execute: <code>docker compose up -d</code>. O healthcheck garante que o Docker reinicie automático em caso de falha. Monitore com <code>docker compose logs -f app</code>.</p>

<p>Para atualizações futuras: <code>docker compose down &amp;&amp; docker compose up -d --build</code> reconstrói e reinicia tudo.</p>

<h2>Conclusão</h2>

<p>Você domina agora o pipeline completo de deploy: otimizar código Rust em release, containerizar com multistage Docker, configurar Nginx como reverse proxy profissional e orquestrar tudo com Docker Compose. A combinação garante segurança, performance e resiliência. Lembre-se que o healthcheck é crucial — sem ele, sua aplicação pode cair silenciosamente. Teste localmente com <code>docker compose up</code> antes de fazer push para produção.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://www.rust-lang.org/pt-BR/" target="_blank" rel="noopener noreferrer">Documentação Oficial Rust</a></li>

<li><a href="https://docs.docker.com/language/rust/" target="_blank" rel="noopener noreferrer">Docker Best Practices for Rust</a></li>

<li><a href="https://github.com/tokio-rs/axum" target="_blank" rel="noopener noreferrer">Axum Web Framework</a></li>

<li><a href="https://nginx.org/en/docs/" target="_blank" rel="noopener noreferrer">Nginx Official Documentation</a></li>

<li><a href="https://docs.docker.com/compose/compose-file/" target="_blank" rel="noopener noreferrer">Docker Compose Reference</a></li>

</ul>

Comentários

Mais em Rust

O que Todo Dev Deve Saber sobre WebAssembly com Rust: Compilando para o Navegador com wasm-pack
O que Todo Dev Deve Saber sobre WebAssembly com Rust: Compilando para o Navegador com wasm-pack

Introdução ao WebAssembly com Rust WebAssembly (WASM) é um formato binário qu...

Guia Completo de Vec<T> em Rust: O Array Dinâmico da Biblioteca Padrão
Guia Completo de Vec<T> em Rust: O Array Dinâmico da Biblioteca Padrão

Vec : Entendendo o Array Dinâmico Fundamental Vec é a estrutura de dados mais...

Dominando Slices em Rust: Referências para Partes de Coleções em Projetos Reais
Dominando Slices em Rust: Referências para Partes de Coleções em Projetos Reais

Entendendo Slices em Rust Um slice é uma referência a uma parte contígua de u...