最近 cn-font-split 需要部署一个 Rust 服务器用于动态字体分包,所以想着用 Docker 构建部署,这样就不用管服务器 Linux 环境的事情了。网上一搜便有了结果,但是一试发现各种依赖问题,而且文章老久,就自己看着编写了一段 Dockerfile。
它能够支持
- 构建与部署分离,这样构建的产物小、纯净
- 使用 debian 和 Rust 国内源,国内开发下载超快
- 构建时 Docker 分层缓存,cargo 先装依赖再构建,不会动不动就重新下载依赖
建议使用 debain 为基础的容器,不要使用 alpine 等超级精简镜像。如果你的依赖中包含了 C、C++ 或者是 sys 的依赖,那么大概率会直接报错,导致构建或者运行的时候出错。
你可以调整 apt 的依赖安装保证适合你的环境。 如果你是 Rust 服务器项目,一定要安装 openssl 相关的依赖,否则编译不报错,但是运行起来就会有问题。
下面是我的 Dockerfile,特别注意,你需要写一份 .dockerignore 将 target 目录(本地 Rust 项目的缓存目录)放进去(代码在后面),不然 Docker 会拷贝这个目录。
####################################################################################################
## Builder
####################################################################################################
FROM rust:1.84.0-bullseye AS builder
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/' /etc/apt/sources.list
RUN apt update && apt install -y openssl build-essential pkg-config libssl-dev
RUN update-ca-certificates
WORKDIR /app
RUN mkdir /app/.cargo/
RUN echo '[source.crates-io] \nreplace-with = "rsproxy-sparse" \n[source.rsproxy-sparse] \nregistry = "sparse+https://rsproxy.cn/index/" \n[net] \ngit-fetch-with-cli = true' > /app/.cargo/config.toml
# 欺骗缓存 cargo 依赖
RUN mkdir ./src && touch ./src/main.rs
COPY ./Cargo.toml .
COPY ./Cargo.lock .
RUN cargo fetch
COPY ./ .
RUN cargo build --release
####################################################################################################
## Final image
####################################################################################################
FROM debian:bullseye-slim
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/group /etc/group
WORKDIR /app
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/' /etc/apt/sources.list
RUN apt update && apt install -y openssl ca-certificates
RUN update-ca-certificates
COPY --from=builder /app/target/release/server ./
EXPOSE 9000
CMD ["/app/server"]
target/
Dockerfile