web-dev-qa-db-ja.com

Cache Rust Dockerビルドとの依存関係

Rust + Actix-WebにHello World Webプロジェクトがあります。いくつかの問題があります。まず、コードのすべての変更により、各クレートのダウンロードとコンパイルなど、プロジェクト全体の再コンパイルが原因です。通常の開発のように機能したいです - キャッシュコンパイル済みの箱と私のコードベースのみを再コンパイルすることを意味します。 2番目の問題は私のアプリを公開しませんか。 Webブラウザを介してアクセスできません

ドッケルファイル:

_FROM Rust

WORKDIR /var/www/app

COPY . .

EXPOSE 8080

RUN cargo run
_

docker-compose.yml:

_version: "3"
services:
  app:
    container_name: hello-world
    build: .
    ports:
      - '8080:8080'
    volumes:
      - .:/var/www/app
      - registry:/root/.cargo/registry

volumes:
  registry:
    driver: local
_

main.rs:

_extern crate actix_web;

use actix_web::{web, App, HttpServer, Responder};

fn index() -> impl Responder {
    "Hello world"
}

fn main() -> std::io::Result<()> {
    HttpServer::new(|| App::new().service(web::resource("/").to(index)))
        .bind("0.0.0.0:8080")?
        .run()
}
_

Cargo.toml:

_[package]
name = "hello-world"
version = "0.1.0"
authors = []
edition = "2018"

[dependencies]
actix-web = "1.0"
_
12
Arek C.

(まだ実験的な)Docker Buildkitを使用すると、docker buildステップの間にビルドフォルダを正しくキャッシュできます。

DockerFile:

# syntax=docker/dockerfile:experimental
from Rust
ENV HOME=/home/root
WORKDIR $HOME/app
[...]
RUN --mount=type=cache,target=/usr/local/cargo/registry \
    --mount=type=cache,target=/home/root/app/target \
    cargo build --release

その後実行します。

DOCKER_BUILDKIT=1 docker build . --progress=plain

その後のDockerビルドは、キャッシュから貨物とターゲットフォルダを再利用し、したがってあなたのビルドを高速化します。

Dockerキャッシュマウントを消去するには:docker builder Prune --filter type=exec.cachemount

適切なキャッシングが表示されない場合:適切なキャッシュが表示されない場合は、必ずDockerイメージ内の貨物/レジストリとターゲットフォルダの場所を確認してください。

最小限の実施例: https://github.com/benmarten/sccache-docker-test/tree/no-sccache

1

Electronix384128 答えは優れています。 GITを使用した依存関係に必要な.cargo/gitのキャッシュを追加し、多段Dockerの例を追加することで、キャッシュを追加します。

Docker Desktop 2.4では、Rust-Musl-BuilderおよびDocker Buildkit機能を使用しています。他のバージョンでは、それでも有効にする必要があるかもしれません:DOCKER_BUILDKIT=1 docker build .

rusl-musl-builderの作業ディレクトリは/home/Rust/srcです。
[。] --mountでuid/gidを設定しようとしましたが、ターゲットの許可の問題のため、Rustのコンパイルに失敗しました。

# syntax=docker/dockerfile:experimental
FROM ekidd/Rust-musl-builder:stable AS builder

COPY . .
RUN --mount=type=cache,target=/home/Rust/.cargo/git \
    --mount=type=cache,target=/home/Rust/.cargo/registry \
    --mount=type=cache,target=/home/Rust/src/target \
    Sudo chown -R Rust: target /home/Rust/.cargo && \
    cargo build --release && \
    # Copy executable out of the cache so it is available in the final image.
    cp target/x86_64-unknown-linux-musl/release/my-executable ./my-executable

FROM Alpine
COPY --from=builder /home/Rust/src/my-executable .
USER 1000
CMD ["./my-executable"]
0
jetersen

これは私がすることです、そしてそれはビルドスクリプトと互換性があります。これは多段ビルドですので、小さな画像が発生しますが、最初のイメージに組み込まれた依存関係をキャッシュします。

FROM Rust:1.43 AS builder

RUN apt-get update
RUN cd /tmp && USER=root cargo new --bin <projectname>
WORKDIR /tmp/<projectname>

# cache Rust dependencies in docker layer
COPY Cargo.toml Cargo.lock ./
RUN touch build.rs && echo "fn main() {println!(\"cargo:rerun-if-changed=\\\"/tmp/<projectname>/build.rs\\\"\");}" >> build.rs
RUN cargo build --release

# build the real stuff and disable cache via the ADD
ADD "https://www.random.org/cgi-bin/randbyte?nbytes=10&format=h" skipcache
COPY ./build.rs ./build.rs

# force the build.rs script to run by modifying it
RUN echo " " >> build.rs
COPY ./src ./src
RUN cargo build --release

FROM Rust:1.43
WORKDIR /bin
COPY --from=builder /tmp/<projectname>/target/release/server /bin/<project binary>
RUN chmod +x ./<project binary>
CMD ./<project binary>
 _
0
Stephen Eckels

問題はあなたのvolumes定義がバインドマウントをしていないことです。現在の設定がHost ./registry/DOCKER /root/.cargo/registry/をコピーし、DOCKER /root/.cargo/registry/に書き込み、コンテナがシャットダウンされたときに内容を破棄していると思います。

代わりに、ボリューム上のbindタイプを指定する必要があります。

version: "3"
services:
  app:
    container_name: hello-world
    build: .
    environment:
      - CARGO_HOME=/var/www/
    ports:
      - '8080:8080'
    volumes:
      - .:/var/www/app
      - type: bind
        source: ./registry
        target: /root/.cargo/registry

ただし、/root/.cargo/.package-cacheファイルも作成し続けますが、ここでは保管されていません。代わりに、source./.cargoに変更し、ターゲットを/root/.cargoに変更できます。


自分の(ほとんどのCLI)Rustプロジェクトは、 cargo のために書かれたa(== --- ==)を使用します。ビルド間のキャッシュパッケージを確認しました。ビルド時間を大幅に削減しました。これは、/usr/local/binにコピーすることも、1つのプロジェクト内で./cargo buildとしてranを実行することもできます。しかし、この特定のスクリプトはコンテナ内の/usr/src/appにあると仮定していることを想定していることに注意してください。そのため、使用する可能性が高いです。

0
0b10011