FluffiLyn Lab2 Note

Lab2 将Rust程序封装为Docker镜像

Step1 编写Dockerfile

需要在项目根目录下创建一个Dockerfile文件,内容如下:


# Image pre-built from the official Rust image

# base on the Debian Bullseye slim image

FROM rust:1.83.0-slim-bullseye AS base

# Copy the source code and the Cargo.toml file

COPY ./Cargo.toml ./Cargo.toml

COPY ./src ./src

RUN cargo build --release

# Image to run the final binary

FROM debian:bullseye-slim

# It's usual to set the working directory to /app

WORKDIR /app

# Only copy the final binary from the build stage

# The binary is located at /app/target/release/my_webapp,

# since we are using the release profile.

COPY --from=base /target/release/my_webapp /app/my_webapp

# Finally, we run the binary

CMD ["./my_webapp"]

其中,my_webapp是我的软件的名称,需要根据实际情况修改。

Step2 构建Docker镜像

构建Docker镜像的命令是


docker buildx build [OPTIONS] PATH | URL | -

对于我的软件,则是


docker buildx build -t my_webapp:v0.1 .

(注意:这里的“.”表示当前目录,即Dockerfile所在的目录,容易漏掉)

Step3 运行Docker镜像


docker run -d -p 8888:8888 --name my_webapp my_webapp:v0.1

curl访问可正常输出

Step4 更多操作

1. 构建镜像的耗时优化

针对编译的优化

在Step1的Dockerfile中,每次构建镜像都会重新编译整个项目,这样会浪费很多时间。

根据链接https://depot.dev/blog/rust-dockerfile-best-practices,进行以下优化:

  • 使用 cargo-chef 缓存第三方依赖项

  • 使用 sccache 缓存 Rust 项目编译

  • 缓存 Cargo 注册表

从而做到利用未更改的部分,跳过步骤以加快构建速度。


# Image pre-built from the official Rust image

# base on the Debian Bullseye slim image

FROM rust:1.83.0-slim-bullseye AS base

# Install necessary dependencies

RUN apt-get update && apt-get install -y \

libssl-dev \

pkg-config

# Install sccache and cargo-chef

RUN cargo install sccache --version ^0.7

RUN cargo install cargo-chef --version ^0.1

# Set environment variables to use sccache as the RUSTC_WRAPPER

ENV RUSTC_WRAPPER=sccache SCCACHE_DIR=/sccache

# Set OPENSSL_DIR to the root directory containing include and lib

ENV OPENSSL_DIR=/usr

# Planner stage: Generate the cargo-chef recipe

FROM base AS planner

WORKDIR /app

COPY ./Cargo.toml ./Cargo.toml

COPY ./src ./src

# Use BuildKit to cache the sccache directory

RUN --mount=type=cache,target=$SCCACHE_DIR,sharing=locked \

cargo chef prepare --recipe-path recipe.json

# Builder stage: Build the project using the recipe

FROM base AS builder

WORKDIR /app

COPY --from=planner /app/recipe.json recipe.json

# Use BuildKit to cache the Cargo registry and sccache directories

RUN --mount=type=cache,target=/usr/local/cargo/registry \

--mount=type=cache,target=$SCCACHE_DIR,sharing=locked \

cargo chef cook --release --recipe-path recipe.json

COPY ./Cargo.toml ./Cargo.toml

COPY ./src ./src

# Use BuildKit to cache the Cargo registry and sccache directories for the final build

RUN --mount=type=cache,target=/usr/local/cargo/registry \

--mount=type=cache,target=$SCCACHE_DIR,sharing=locked \

cargo build --release

# Final runtime image based on debian:bullseye-slim

FROM debian:bullseye-slim

WORKDIR /app

COPY --from=builder /app/target/release/my_webapp /app/my_webapp

# Finally, we run the binary

CMD ["./my_webapp"]

针对下载的优化

镜像源或者挂代理。建议挂代理。

2. 更多运行参数

增加-d参数,使容器在后台运行,不影响终端的使用。

docker ps命令可以查看所有正在运行的容器的信息。

3. 容器网络互访

容器实例默认启动在 bridge 网络上,以下是我的两个容器的IP地址:


#my_webapp

$ docker inspect c01d82081904 | grep IPAddress

#输出

"SecondaryIPAddresses": null,

"IPAddress": "172.17.0.3",

#swagger_editor

$ docker inspect 6d697d21a3d9 | grep IPAddress

#输出

"SecondaryIPAddresses": null,

"IPAddress": "172.17.0.2",

通过bridge网络直接在swagger editor的容器内访问webapp容器的服务


$ docker exec -it 6d697d21a3d9 curl 172.17.0.3:8888/echo/fluffilyn

#输出

Hello, fluffilyn

1 个赞

:+1:

有没有对比一下在重复构建的情况下,优化/不优化的时间耗比多少?

尝试过,但好像没有明显差距,可能是项目不够大或者优化的方式出错了( :upside_down_face:

可以看看这个 XD

破案了,我没改源码

2 个赞