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"
_
(まだ実験的な)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
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"]
これは私がすることです、そしてそれはビルドスクリプトと互換性があります。これは多段ビルドですので、小さな画像が発生しますが、最初のイメージに組み込まれた依存関係をキャッシュします。
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>
_
問題はあなたの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
にあると仮定していることを想定していることに注意してください。そのため、使用する可能性が高いです。