优化Docker中的货运生成时间

我正在使用Rust开发API,并且正在pipe理环境,包括使用Docker的外部数据库。 每次我改变API代码,货物重build,因为Docker不会caching任何与ADD语句相关的内容,将Rust目录复制到容器中,所以它会重新下载所有的包,这是一个公平的因为我使用镍,这似乎有一大堆的依赖。

有没有办法在运行cargo build之前将这些依赖关系? 至less在这种情况下,如果依赖关系发生改变,只会安装所需的东西,类似于在本地编译货物。

这里是我目前使用的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 

这是我的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"] } 

Docker会caching由ADD (最好是COPY )指令构build的图层,前提是源没有改变。 你可以利用这个,通过首先复制Cargo.toml来caching你的依赖,然后进行构build。

但不幸的是,你需要构build一些东西,所以你可以在你的清单中使用单个源文件和一个虚拟lib目标来实现:

 [lib] name = "dummy" path = "dummy.rs" 

在你的Dockerfile中分别build立一个dummy:

 COPY Cargo.toml /app/Cargo.toml COPY dummy.rs /app/dummy.rs RUN cargo build --lib 

这个层的输出将会被caching,并且所有的依赖都会被安装,然后你可以继续添加你的代码(在同一个Dockerfile ):

 COPY /src/ app/src/ RUN cargo build 

dummy东西很难看,但这意味着正常的构build将会很快,因为它来自于caching层,当你改变你的Cargo.toml依赖关系时,Docker会select它并构build一个更新的依赖关系的新层。

而不是添加一个虚拟文件,也可以让构build失败:

 RUN cargo build || true COPY ... RUN cargo build 

如果你想要优化构build,不要忘记添加 – --release到两个地方。

您可以创build一个中间图像,并从中build立最终的图像。 例如:

 FROM ubuntu:xenial RUN apt-get update && apt-get install curl build-essential ca-certificates file xutils-dev nmap -y RUN mkdir /rust ... 

使用docker build -t mybaseimage .

 FROM mybaseimage RUN mkdir /app WORKDIR /app ADD . /app/ RUN cargo build EXPOSE 20000 CMD ./target/debug/api 

docker build -t finalimage .

这样只有mybaseimage重build