优化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