有没有一种方法可以告诉Cargo安装并构建我的所有依赖项,但不尝试构建我的应用程序?
我原以为cargo install
会做到这一点,但实际上它也一直在构建我的应用程序。我希望达到这样一种状态,即cargo build
会发现所有依赖项都已准备好使用,但不涉及/src
目录。
我真正想要实现的
我正在尝试为Rust应用程序构建Docker映像,我想在其中执行以下步骤:
构建时间(docker build .
):
1.导入安装了Ruster工具Docker映像
1.添加我的Cargo.toml和Cargo.lock文件
1.下载并生成所有依赖项
1.添加我的源目录到这图象
1.生成我的源代码
运行时间(docker run ...
):
1.运行应用程序
我已经尝试了下面的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
我之所以想把依赖项的安装步骤和实际构建应用程序分开,是因为如果我不修改依赖项,我希望Docker能够使用一个缓存映像,并且所有依赖项都已经安装和构建好了。因此,我不能ADD /src /source/src
,直到安装依赖项 * 之后 *,因为这会在我修改自己的代码时使缓存映像无效。
6条答案
按热度按时间wwtsj6pe1#
据我所知,Cargo中没有对构建依赖项的本地支持。有an open issue for it。如果您可以向Cargo提交一些东西来完成它,或者创建一个第三方Cargo插件,我不会感到惊讶。我也希望
cargo doc
具有此功能,因为我自己的代码太过破碎而无法编译; -)但是,我维护的Rust playground确实实现了您的最终目标。有一个base Docker container,它安装了Rustup,并在一个
Cargo.toml
中复制了所有可用于Playground的板条箱。构建步骤创建一个空白项目(使用一个虚拟的src/lib.rs
),然后调用cargo build
和cargo build --release
来编译板条箱:所有下载的板条箱存储在Docker映像的
$HOME/.cargo
目录中,所有构建的板条箱存储在应用程序的target/{debug,release}
目录中。稍后,真正的源文件被复制到容器中,并且可以使用现在编译好的crates再次执行
cargo build
/cargo run
。如果您正在构建一个可执行项目,那么您还需要在Cargo. lock中进行复制。
busg9geu2#
如果你添加一个虚拟的main或lib文件,你可以使用
cargo build
来下拉依赖项。我目前正在使用这个解决方案来处理我的基于Docker的项目:我使用的是
--volumes
,所以我已经完成了这一步。主机卷进入并删除了虚拟文件,当我稍后构建源代码时,cargo使用缓存的依赖项。如果您稍后想添加COPY
(或ADD
)并使用缓存的依赖项,这个解决方案也同样有效。pepwfjgg3#
基于GitHub评论
nhhxz33t4#
cargo-chef工具就是为了解决这个问题而设计的。下面是README中的一个例子,告诉你如何在Dockerfile中使用它:
mpbci0fu5#
我只是想把这个贴在这里,这样其他人就可以看到它的发展。我刚刚开始使用Docker的一个实验工具,叫做Cargo-Wharf(https://github.com/denzp/cargo-wharf/tree/master/cargo-wharf-frontend)。它是一个Docker BuildKit前端,为您缓存构建的货物依赖项。如果您只更改了一个源文件,这是当你调用
docker build
时唯一被重建的东西。你可以通过注解你的Cargo.toml文件来使用它,然后将Docker指向你的Cargo.toml而不是Docker文件。去看看吧,这正是我想要的。(我与这个项目毫无关系。)5lhxktic6#
可以通过
cargo init
、cargo build
和cargo install
来完成。例如,对于名为foo
的项目,定义以下Dockerfile
:在这里,
cargo init
创建Cargo所需的占位符文件,cargo build
构建在Cargo.toml
中指定的依赖项,cargo install
创建foo
二进制文件。Docker继续构建由cargo init foo
创建的默认项目。以上通过追加// force Cargo cache invalidation
强制更新main.rs
解决了此问题。若要避免由于生成上下文和层较大而导致生成速度较慢,请确保通过
.dockerignore
忽略不重要的文件夹(如target
)。例如,定义以下.dockerignore
: