I have hello world web project in Rust + Actix-web. I have several problems. First is every change in code causes recompiling whole project including downloading and compiling every crate. I'd like to work like in normal development - it means cache compiled crates and only recompile my codebase. Second problem is it doesn't expose my my app. It's unreachable via web browser
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"
Seems like you are not alone in your endeavor to cache rust dependencies via the docker build process. Here is a great article that helps you along the way.
The gist of it is you need a dummy.rs
and your Cargo.toml
first, then build it to cache the dependencies and then copy your application source later in order to not invalidate the cache with every build.
Dockerfile
FROM rust
WORKDIR /var/www/app
COPY dummy.rs .
COPY Cargo.toml .
RUN sed -i 's#src/main.rs#dummy.rs#' Cargo.toml
RUN cargo build --release
RUN sed -i 's#dummy.rs#src/main.rs#' Cargo.toml
COPY . .
RUN cargo build --release
CMD ["target/release/app"]
CMD application name "app" is based on what you have specified in your Cargo.toml for your binary.
dummy.rs
fn main() {}
Cargo.toml
[package]
name = "app"
version = "0.1.0"
authors = ["..."]
[[bin]]
name = "app"
path = "src/main.rs"
[dependencies]
actix-web = "1.0.0"
src/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()
}