Mar*_*ark 3 compilation docker rust-cargo docker-volume
我正在Docker(rust:1.33.0
)中构建一个Rust程序。
每次代码更改时,它都会重新编译(良好),同时也重新下载所有依赖项(不良)。
我以为我可以通过添加来缓存依赖项VOLUME ["/usr/local/cargo"]
。编辑我也尝试过CARGO_HOME
没有运气这个目录。
我认为将其作为卷可以保留下载的依赖项,这些依赖项似乎位于此目录中。
但这没有用,每次仍会下载它们。为什么?
Docker文件
FROM rust:1.33.0
VOLUME ["/output", "/usr/local/cargo"]
RUN rustup default nightly-2019-01-29
COPY Cargo.toml .
COPY src/ ./src/
RUN ["cargo", "build", "-Z", "unstable-options", "--out-dir", "/output"]
Run Code Online (Sandbox Code Playgroud)
刚建docker build .
。
货代
[package]
name = "mwe"
version = "0.1.0"
[dependencies]
log = { version = "0.4.6" }
Run Code Online (Sandbox Code Playgroud)
代码:你好世界
更改后第二次运行的输出main.rs
:
...
Step 4/6 : COPY Cargo.toml .
---> Using cache
---> 97f180cb6ce2
Step 5/6 : COPY src/ ./src/
---> 835be1ea0541
Step 6/6 : RUN ["cargo", "build", "-Z", "unstable-options", "--out-dir", "/output"]
---> Running in 551299a42907
Updating crates.io index
Downloading crates ...
Downloaded log v0.4.6
Downloaded cfg-if v0.1.6
Compiling cfg-if v0.1.6
Compiling log v0.4.6
Compiling mwe v0.1.0 (/)
Finished dev [unoptimized + debuginfo] target(s) in 17.43s
Removing intermediate container 551299a42907
---> e4626da13204
Successfully built e4626da13204
Run Code Online (Sandbox Code Playgroud)
Dockerfile中的一个卷在这里适得其反。这将在每个构建步骤以及运行容器时再次安装一个匿名卷。完成该步骤后,将在每个构建步骤中丢弃该卷,这意味着对于需要这些依赖项的任何其他步骤,您将需要再次下载全部内容。
为此的标准模型是分4个步骤复制您的依赖项规范,运行依赖项下载,复制您的代码,然后编译或运行您的代码。这样,泊坞窗就可以高效地缓存图层。我对铁锈或货物不甚了解,但我相信这样会:
FROM rust:1.33.0
RUN rustup default nightly-2019-01-29
COPY Cargo.toml .
RUN cargo fetch # this should download dependencies
COPY src/ ./src/
RUN ["cargo", "build", "-Z", "unstable-options", "--out-dir", "/output"]
Run Code Online (Sandbox Code Playgroud)
另一个选择是使用BuildKit(在18.09中可用)打开一些实验性功能,以便Docker将这些依赖项保存为类似于构建的命名卷的内容。该目录可以在各个版本之间重用,但永远不会添加到映像本身,从而使其对于诸如下载缓存之类的事情很有用。
# syntax=docker/dockerfile:experimental
FROM rust:1.33.0
VOLUME ["/output", "/usr/local/cargo"]
RUN rustup default nightly-2019-01-29
COPY Cargo.toml .
COPY src/ ./src/
RUN --mount=type=cache,target=/root/.cargo \
["cargo", "build", "-Z", "unstable-options", "--out-dir", "/output"]
Run Code Online (Sandbox Code Playgroud)
请注意,以上假设货物在/root/.cargo中缓存文件。您需要对此进行验证并进行适当调整。我也没有将mount语法与json exec语法混合在一起以了解该部分是否有效。您可以在此处阅读有关BuildKit实验功能的更多信息:https : //github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md
从18.09和更高版本中打开BuildKit就像export DOCKER_BUILDKIT=1
从该shell运行构建一样简单。
我会说,更好的解决方案是使用 docker多阶段构建,就像这里和那里所指出的那样
通过这种方式,您可以为自己创建第一个映像,这将构建您的应用程序和依赖项,然后仅在第二个映像中使用第一个映像中的依赖项文件夹
这是受到您对@Jack Gore 的回答的评论以及上面链接的两个问题评论的启发。
FROM rust:1.33.0 as dependencies
WORKDIR /usr/src/app
COPY Cargo.toml .
RUN rustup default nightly-2019-01-29 && \
mkdir -p src && \
echo "fn main() {}" > src/main.rs && \
cargo build -Z unstable-options --out-dir /output
FROM rust:1.33.0 as application
# Those are the lines instructing this image to reuse the files
# from the previous image that was aliased as "dependencies"
COPY --from=dependencies /usr/src/app/Cargo.toml .
COPY --from=dependencies /usr/local/cargo /usr/local/cargo
COPY src/ src/
VOLUME /output
RUN rustup default nightly-2019-01-29 && \
cargo build -Z unstable-options --out-dir /output
Run Code Online (Sandbox Code Playgroud)
PS:只运行一次会减少你生成的层数;更多信息在这里
归档时间: |
|
查看次数: |
719 次 |
最近记录: |