使用 Docker+alpine 构建 Rust 应用

对于前文 使用Rust+Rocket+Diesel+MySQL构建API应用 我构建的环境是 Mac. 然而,通常情况下,我们需要在linux服务器上运行我们的应用。然而跨平台编译需要各种各样的依赖,因此比较好的办法是在目标平台上编译应用,遇到的问题会相对少一些。

使用Docker构建镜像

构建的alpine镜像编译,需要 –target=x86_64-unknown-linux-musl

完整 Dockerfile 如下:

FROM rust:alpine3.19 AS builder
# 使用国内的 rsproxy.cn 的源,alpine需要设置 RUSTFLAGS 环境变量
ENV  RUSTUP_DIST_SERVER="https://rsproxy.cn" \
    RUSTUP_UPDATE_ROOT="https://rsproxy.cn/rustup" \
    RUSTFLAGS=-Ctarget-feature=-crt-static
# 安装编译需要的一些依赖
RUN sed -e 's/dl-cdn[.]alpinelinux.org/mirrors.aliyun.com/g' -i~ /etc/apk/repositories \
    && apk add --update --no-cache gcc clang-dev musl-dev yaml curl libmicrohttpd libuuid mariadb-connector-c-dev mariadb-dev
# 将 cargo 配置增加到 /root/.cargo
ADD .cargo /root/
# 增加 Rust 在 alpine 的编译依赖
RUN rustup target add x86_64-unknown-linux-musl

# 编译应用
WORKDIR /opt/app
COPY . .
RUN cargo build --release --target=x86_64-unknown-linux-musl
CMD [ "sh" ]

# 第二阶段 制作生产的应用镜像
FROM alpine:3.19
# 主要依赖于 mysql 的开发工具包
RUN sed -e 's/dl-cdn[.]alpinelinux.org/mirrors.aliyun.com/g' -i~ /etc/apk/repositories \
    && apk add --update --no-cache mariadb-connector-c-dev mariadb-dev && rm -rf /var/cache/apk/*
# 复制第一阶段编译好的应用及配置文件到本镜像
WORKDIR /opt/app
COPY --from=builder /opt/app/target/x86_64-unknown-linux-musl/release/web-hook-rs .
COPY ./Rocket.toml  ./web-hook-config.yml ./.env ./
CMD ["/opt/app/web-hook-rs"]

执行编译构建命令:

docker build -t demo:1.0.0 .

需要耐心等待一会儿,成功构建完成。

运行测试

docker run -it --rm -p 8000:8000 demo:1.0.0

然后浏览器访问: http://localhost:8000 即可。

注意事项

使用 diesel 需要安装 mysql 的开发库,在linux上尤其是需要 libmysqlclient.so 如果你使用的是 centos7 系统的话,使用 yum install mysql mysql-devel 即可。 如果安装成功后,依旧无法编译通过 diesel依赖的话,可以重启系统再次尝试。

参考文章