Docker et Rust : conteneurisation d'applications Rust

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : pourquoi Docker et Rust sont le duo parfait

Rust est un langage de programmation système moderne connu pour ses performances et sa sécurité mémoire. Cependant, pour livrer une application Rust à un utilisateur final ou dans le cloud, vous devez résoudre le problème d'environnement. C'est là que Docker vient à la rescousse. La conteneurisation vous permet d'empaqueter une application Rust avec toutes ses dépendances dans un conteneur léger et isolé. Dans cet article, nous allons explorer comment créer une image Docker efficace et minimale pour un projet Rust en utilisant les meilleures pratiques.



1. Les bases de Docker pour les développeurs Rust

Docker est une plateforme pour développer, livrer et exécuter des applications dans des conteneurs. Un conteneur inclut l'application elle-même et tout ce dont elle a besoin pour fonctionner : bibliothèques, utilitaires système et configurations. Pour Rust, cela est particulièrement pertinent car un binaire compilé ne dépend pas d'un environnement d'exécution (contrairement à Python ou Node.js), ce qui permet de créer des images très petites.

Les principaux composants dont vous aurez besoin :

  • Dockerfile — un fichier texte avec les instructions pour construire l'image.
  • .dockerignore — un fichier qui exclut les fichiers inutiles du contexte de build.
  • Docker Compose (optionnel) — pour orchestrer plusieurs conteneurs.

Avant de commencer, assurez-vous d'avoir installé Docker Desktop ou Docker Engine.



2. Création d'un Dockerfile pour une application Rust

Considérons un exemple simple de serveur web en Rust utilisant le framework actix-web. Notre fichier principal main.rs ressemble à ceci :

use actix_web::{web, App, HttpServer, Responder};

async fn index() -> impl Responder { "Bonjour, Docker et Rust !"}

#[actix_web::main]async fn main() -> std::io::Result<()> { HttpServer::new(|| { App::new().route("/", web::get().to(index)) }) .bind("0.0.0.0:8080")? .run() .await}

Créons maintenant un Dockerfile. La technique la plus importante ici est la construction multi-étapes. Elle permet d'abord de construire l'application dans un environnement avec l'ensemble des outils Rust, puis de copier le binaire fini dans une image finale minimale.

// ---- Première étape : construction ----FROM rust:1.75 as builder

WORKDIR /app

// Copier les manifestes pour la mise en cache des dépendancesCOPY Cargo.toml Cargo.lock ./

// Créer un main.rs vide pour construire les dépendancesRUN mkdir src && echo "fn main() {}" > src/main.rsRUN cargo build --release 2>/dev/null || true

// Copier maintenant le code source réelCOPY src ./src

// Construire le binaire final (le cache des dépendances existe déjà)RUN cargo build --release

// ---- Deuxième étape : image finale ----FROM debian:bookworm-slim

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

WORKDIR /app

// Copier le binaire depuis la première étapeCOPY --from=builder /app/target/release/my_rust_app .

EXPOSE 8080

CMD ["./my_rust_app"]

Remarquez l'astuce avec le main.rs vide. Cela permet à Docker de mettre en cache les dépendances compilées (crates) et de ne pas les reconstruire à chaque fois que vous modifiez uniquement le code source. Cela accélère considérablement les constructions ultérieures.



2.1. Optimisation de la taille de l'image

L'image finale basée sur debian:bookworm-slim pèse environ 80-100 Mo. Cependant, si vous voulez une image vraiment minimale, vous pouvez utiliser scratch (une image vide) ou alpine. Pour les applications Rust compilées statiquement, c'est l'option idéale. Pour ce faire, vous devez modifier la cible de construction :

// Dans la première étape (builder) :RUN rustup target add x86_64-                

Blogs

Book Recommendations