为何Heroku每次都要重新构建我的Docker容器?

11
我正在使用Rocket.rs在Docker容器中部署一个Rust应用到Heroku。每次我进行一点小改动,就必须推送整个容器。这需要重新下载所有的rust组件(rustc、rust-std、cargo等),重新下载所有依赖项,并重新推送层。特别是有一个1.02GB的层,每次都要推送,需要大约30分钟的时间。每次都要如此。如何避免:
  • 每次重新下载rustc、rust-std、cargo和rust-docs
  • 每次重新下载相同的未更改的依赖项
  • 每次重新推送1.02GB的层
这里是具有所有相关文件的Gist:https://gist.github.com/vcapra1/0a857aac8f05277e65ea5d86e8e4e239
顺便提一下,我的代码非常简单:(这是唯一的.rs文件)
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use] extern crate rocket;

use std::fs;

#[get("/")]
fn index() -> &'static str {
    "Hello from Rust!"
}

fn main() {
    rocket::ignite().mount("/", routes![index]).launch();
}

如果不是所有的问题都能解决,那么这将解决哪个要点? - vcapra1
至少前两点。我从未使用过Heroku,所以无法对第三点发表评论。 - Boiethios
2
你能把你的 Dockerfile 添加到问题中吗?有一些相当标准的技巧。(一个单独的1 GB层对于一个非常小的程序来说有点不寻常。) - David Maze
还有@Boiethios,抱歉我对Docker还比较新-我该如何在Dockerfile中完成这个操作? - vcapra1
@vcapra1 我是在 Gitlab CI 中完成的,所以无法针对你的情况进行说明。 - Boiethios
显示剩余2条评论
1个回答

1
每次重新下载 rustc、rust-std、cargo 和 rust-docs。 每次重新下载相同的、未更改的依赖项。
你应该缓存这些步骤。
每次重新推送一个 1.02 GB 的层。
你不需要任何 Rust 工具链来运行编译后的二进制应用程序,因此可以使用 debian:8-slim 或甚至 alpine 来运行它。
这将减小镜像大小为 84.4MB:
FROM rust:1.31 as build

RUN USER=root cargo new --bin my-app
WORKDIR /my-app

# Copy manifest and build it to cache your dependencies.
# If you will change these files, then this step will rebuild
COPY rust-toolchain Cargo.lock Cargo.toml ./
RUN cargo build --release && \
    rm src/*.rs && \
    rm ./target/release/deps/my_app*

# Copy your source files and build them.
COPY ./src ./src
COPY ./run ./
RUN cargo build --release

# Use this image to reduce the final size
FROM debian:8-slim

COPY --from=build /my-app/run ./
COPY --from=build /my-app/target/release/my-app ./target/release/my-app

CMD ["./run"]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接