web-dev-qa-db-fra.com

Cache Rust Dépendances avec Docker Build

J'ai un projet Web World Hello World in Rust + Actix-Web. J'ai plusieurs problèmes. Tout d'abord, chaque changement de code provocait un projet entier, y compris le téléchargement et la compilation de chaque caisse. J'aimerais travailler. Comme dans le développement normal - cela signifie cache compilé des caisses et recompiler seulement mon codebase. Deuxième problème est qu'il n'expose pas mon application. C'est inaccessible via le navigateur Web

DockerFile:

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.

Tandis que electronix384128 La réponse est excellente. Je voudrais leur étendre en ajoutant du cache pour .cargo/git qui est nécessaire pour toute dépendance à l'aide de GIT et en ajoutant un exemple de docker à plusieurs étages.

Utilisation de la fonctionnalité de Builder Rust-Musl-Builder et Docker Buildkit, qui est maintenant par défaut dans Docker Desktop 2.4. Sur d'autres versions, vous devrez peut-être toujours l'activer via: DOCKER_BUILDKIT=1 docker build .

rusl-musl-builder Le répertoire de travail est /home/Rust/src
[.____] J'ai essayé de définir UID/GID sur --mount Mais n'a pas réussi à compiler Rust en raison d'un problème de permission dans la cible.

# 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

C'est ce que je fais et c'est compatible avec la construction de scripts. C'est une version à plusieurs étages afin qu'il entraîne une petite image, mais cache les dépendances construites dans la première image.

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

Je pense que le problème est votre définition volumes _ ne fait pas de mont de liaison. Je crois que votre configuration actuelle est la copie Host ./registry/ dans DOCKER /root/.cargo/registry/, Ecrire à DOCKER /root/.cargo/registry/, et jeter le contenu lorsque le conteneur est arrêté.

Au lieu de cela, vous voudrez spécifier le type bind sur le volume:

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

Cependant, gardez à l'esprit un /root/.cargo/.package-cache Le fichier est également créé, mais non gardé ici. Au lieu de cela, vous pouvez changer le source à ./.cargo et cible à /root/.cargo.


Pour moi (principalement cli) Rust projets, j'aime utiliser un remplacement de goutte que j'ai écrit pour cargo que j'ai Forfaits de caches confirmés entre les constructions, réduisant grandement la durée de construction. Cela peut être copié à /usr/local/bin à utiliser globalement ou couru comme ./cargo build Dans un seul projet. Mais gardez à l'esprit que ce script spécifique suppose que l'application est située à /usr/src/app Dans le conteneur, il aurait donc probablement besoin d'ajuster votre utilisation.

0
0b10011