优化Docker中的货物构建时间

Vig*_*ran 4 dependencies rust docker rust-cargo

我正在使用Rust开发API,并且正在管理环境,包括使用Docker的外部数据库.每次我对API代码进行更改时,货物都会重建,并且由于Docker没有缓存与将ADD目录复制到容器的语句有关的任何内容,因此它会重新下载所有包,这是相当冗长的因为我正在使用镍,因为镍似乎有很多依赖.

有没有办法在运行之前引入这些依赖项cargo build?至少这种方式,如果依赖项改变它将只安装所需的,类似于本地Cargo编译.

这是我目前使用的Dockerfile:

FROM ubuntu:xenial
RUN apt-get update && apt-get install curl build-essential ca-certificates file xutils-dev nmap -y
RUN mkdir /rust
WORKDIR /rust
RUN curl https://sh.rustup.rs -s >> rustup.sh
RUN chmod 755 /rust/rustup.sh
RUN ./rustup.sh -y
ENV PATH=/root/.cargo/bin:$PATH SSL_VERSION=1.0.2h
RUN rustup default 1.11.0
RUN curl https://www.openssl.org/source/openssl-$SSL_VERSION.tar.gz -O && \
    tar -xzf openssl-$SSL_VERSION.tar.gz && \
    cd openssl-$SSL_VERSION && ./config && make depend && make install && \
    cd .. && rm -rf openssl-$SSL_VERSION*
ENV OPENSSL_LIB_DIR=/usr/local/ssl/lib \
    OPENSSL_INCLUDE_DIR=/usr/local/ssl/include \
    OPENSSL_STATIC=1
RUN mkdir /app
WORKDIR /app
ADD . /app/
RUN cargo build
EXPOSE 20000
CMD ./target/debug/api
Run Code Online (Sandbox Code Playgroud)

这是我的Cargo.toml

[profile.dev]
debug = true

[package]
name = "api"
version = "0.0.1"
authors = ["Vignesh Sankaran <developer@ferndrop.com>"]

[dependencies]
nickel = "= 0.8.1"
mongodb = "= 0.1.6"
bson = "= 0.3.0"
uuid = { version = "= 0.3.1", features = ["v4"] }
Run Code Online (Sandbox Code Playgroud)

Elt*_*man 8

如果源没有改变,Docker会缓存从ADD(最好COPY)指令构建的层.您可以使用它并通过先复制Cargo.tomlin和进行构建来缓存依赖项.

但遗憾的是,您需要构建一些内容,因此您可以使用lib清单中的单个源文件和虚拟目标来执行此操作:

[lib]
name = "dummy"
path = "dummy.rs"
Run Code Online (Sandbox Code Playgroud)

在你的Dockerfile中分别构建虚拟:

COPY Cargo.toml /app/Cargo.toml
COPY dummy.rs /app/dummy.rs
RUN cargo build --lib
Run Code Online (Sandbox Code Playgroud)

将缓存此层的输出,并安装所有依赖项,然后您可以继续添加其余代码(在相同的位置Dockerfile):

COPY /src/ app/src/
RUN cargo build
Run Code Online (Sandbox Code Playgroud)

这些dummy东西很丑陋,但这意味着你的正常构建会很快,因为它来自缓存层,当你改变你的Cargo.tomlDocker中的依赖关系时,它会选择它并构建一个具有更新依赖关系的新层.

  • *首先复制`Cargo.toml`* - **和**Cargo.lock`! (2认同)
  • `COPY` 只是将文件/目录从上下文复制到图像层。`ADD` 也可以这样做,但它也可以使用 Web 地址作为源,如果源是压缩文件,它会将其解压缩到图像上。该功能并不总是预期的,所以除非你知道你需要它,否则你最好使用`COPY`。 (2认同)