有没有办法告诉Cargo安装和构建我的所有依赖项,但是没有尝试构建我的应用程序?
我想cargo install会这样做,但它实际上也一直在构建我的应用程序.我想进入一个状态,在那里cargo build可以找到所有依赖项,但无需触及/src目录.
我真正想要实现的目标:
我正在尝试为Rust应用程序构建Docker镜像,我想在其中执行以下步骤:
建立时间(docker build .):
运行时间(docker run ...):
我已经尝试了以下内容Dockerfile,但是指示的步骤也构建了我的应用程序(由于源目录尚未存在,当然会失败):
FROM jimmycuadra/rust
ADD Cargo.toml /source
ADD Cargo.lock /source
RUN cargo install # <-- failure here
ADD src /source/src
RUN cargo build
ENTRYPOINT cargo run
Run Code Online (Sandbox Code Playgroud)
我想将安装依赖项步骤与实际构建我的应用程序分开的原因是,如果我不更改依赖项,我希望Docker能够使用已安装和构建所有依赖项的缓存映像.因此,我不能ADD /src /source/src,直到后安装依赖条件,因为当我改变我自己的代码,将无效缓存图像.
据我所知,在Cargo中只构建依赖项没有原生支持.有一个未解决的问题.如果您可以向Cargo提交一些东西来完成它,或者可能创建第三方Cargo插件,我不会感到惊讶.我也想要这个功能cargo doc,当我自己的代码太破碎而无法编译时;-)
但是,我维护的Rust游乐场确实实现了您的最终目标.有一个基础Docker容器可以安装Rustup并复制到一个Cargo.toml包含所有可用于操场的板条箱.构建步骤创建一个空白项目(带有一个虚拟src/lib.rs),然后调用cargo build并cargo build --release编译包:
RUN cd / && \
cargo new playground
WORKDIR /playground
ADD Cargo.toml /playground/Cargo.toml
RUN cargo build
RUN cargo build --release
RUN rm src/*.rs
Run Code Online (Sandbox Code Playgroud)
所有下载的包装箱都存储在Docker镜像$HOME/.cargo目录中,所有构建的包装箱都存储在应用程序target/{debug,release}目录中.
稍后,使用现在编译的包装箱将真实的源文件复制到容器中并且cargo build/ cargo run可以再次执行.
如果您正在构建可执行项目,那么您也希望复制Cargo.lock.
如果您添加一个虚拟的 main 或 lib 文件,您可以使用cargo build来拉下依赖项。我目前正在将此解决方案用于我的基于 Docker 的项目:
COPY Cargo.toml .
RUN mkdir src \
&& echo "// dummy file" > src/lib.rs \
&& cargo build
Run Code Online (Sandbox Code Playgroud)
我正在使用--volumes,所以我在这一点上完成了。主机卷进来并吹走虚拟文件,当我稍后构建源代码时,cargo 使用缓存的依赖项。如果您想稍后添加COPY(或ADD)并使用缓存的依赖项,则此解决方案也能正常工作。
FROM rust:1.37
WORKDIR /usr/src
# Create blank project
RUN USER=root cargo new PROJ
# We want dependencies cached, so copy those first.
COPY Cargo.toml /usr/src/PROJ/
COPY Cargo.lock /usr/src/PROJ/
WORKDIR /usr/src/PROJ
# This is a dummy build to get the dependencies cached.
RUN cargo build --release
# Now copy in the rest of the sources
COPY MyPROJECT/src /usr/src/PROJ/src/
# This is the actual build.
RUN cargo build --release \
&& mv target/release/appname /bin \
&& rm -rf /usr/src/PROJ
WORKDIR /
EXPOSE 8888
CMD ["/bin/appname"]
Run Code Online (Sandbox Code Playgroud)
Cargo-Chef工具就是为了解决这个问题而设计的。以下是 README 中的示例,说明如何在 Dockerfile 中使用它:
FROM lukemathwalker/cargo-chef as planner
WORKDIR app
COPY . .
RUN cargo chef prepare --recipe-path recipe.json
FROM lukemathwalker/cargo-chef as cacher
WORKDIR app
COPY --from=planner /app/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json
FROM rust as builder
WORKDIR app
COPY . .
# Copy over the cached dependencies
COPY --from=cacher /app/target target
COPY --from=cacher $CARGO_HOME $CARGO_HOME
RUN cargo build --release --bin app
FROM rust as runtime
WORKDIR app
COPY --from=builder /app/target/release/app /usr/local/bin
ENTRYPOINT ["/usr/local/bin/app"]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2173 次 |
| 最近记录: |