Docker 与 Rust:Rust 应用的容器化

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么 Docker 和 Rust 是理想组合

Rust 是一种现代系统编程语言,以其高性能和内存安全性而闻名。然而,要将 Rust 应用程序交付给最终用户或部署到云端,必须解决环境问题。这正是 Docker 发挥作用的地方。容器化技术允许将 Rust 应用程序及其所有依赖项打包到一个轻量级、隔离的容器中。在本文中,我们将探讨如何利用最佳实践,为 Rust 项目构建一个高效且最小的 Docker 镜像。

1. Rust 开发者的 Docker 基础

Docker 是一个用于开发、交付和运行应用程序的平台。容器包含应用程序本身及其运行所需的一切:库、系统工具和配置。这对 Rust 尤其重要,因为编译后的二进制文件不依赖于运行时(与 Python 或 Node.js 不同),从而可以创建非常小的镜像。

您需要了解的主要组件:

  • Dockerfile — 包含构建镜像指令的文本文件。
  • .dockerignore — 用于从构建上下文中排除不需要文件的文件。
  • Docker Compose(可选)— 用于编排多个容器。

开始之前,请确保您已安装 Docker Desktop 或 Docker Engine。

2. 为 Rust 应用程序创建 Dockerfile

让我们看一个使用 actix-web 框架的简单 Rust Web 服务器示例。我们的主文件 main.rs 如下所示:

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

async fn index() -> impl Responder {
    "Hello, Docker and 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
}

现在我们来创建 Dockerfile。这里最重要的技术是 多阶段构建 (multi-stage build)。它允许我们首先在包含完整 Rust 工具集的环境中构建应用程序,然后将编译好的二进制文件复制到最小的最终镜像中。

// ---- 第一阶段:构建 ----
FROM rust:1.75 as builder

WORKDIR /app

// 复制清单文件以缓存依赖项
COPY Cargo.toml Cargo.lock ./

// 创建一个空的 main.rs 来构建依赖项
RUN mkdir src && echo "fn main() {}" > src/main.rs
RUN cargo build --release 2>/dev/null || true

// 现在复制实际的源代码
COPY src ./src

// 构建最终的二进制文件(依赖项已缓存)
RUN cargo build --release

// ---- 第二阶段:最终镜像 ----
FROM debian:bookworm-slim

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

WORKDIR /app

// 从第一阶段复制二进制文件
COPY --from=builder /app/target/release/my_rust_app .

EXPOSE 8080

CMD ["./my_rust_app"]

请注意使用空 main.rs 的技巧。这允许 Docker 缓存已编译的依赖项(crates),并且仅在您更改源代码时才重新构建它们。这大大加快了重复构建的速度。

2.1. 优化镜像大小

基于 debian:bookworm-slim 的最终镜像大小约为 80-100 MB。但是,如果您想要一个真正最小的镜像,可以使用 scratch(空镜像)或 alpine。对于静态编译的 Rust 应用程序来说,这是理想的选择。为此,您需要更改构建目标:

// 在第一阶段(builder)中:
RUN rustup target add x86_64-                

博客

书籍推荐