Hi, following some online tutorials (multiple of them), I wrote my Dockerfile that builds dependencies as one layer and only after that build the application itself. But the app does not get recompiled without additional touch on the main.rs file. Do you have any idea what is wrong? Or is it somehow cached by design? It is not a big problem, I am just surprised, that it works for others (in tutorials) and does not work for me.
FROM rust:latest
RUN groupadd -r user && useradd --no-log-init -r -g user user
RUN USER=root cargo new /central-node
WORKDIR /central-node
COPY ./Cargo.lock ./Cargo.lock
COPY ./Cargo.toml ./Cargo.toml
RUN cargo build --release; \
rm -f src/*.rs target/release/central-node
COPY ./src ./src
RUN touch ./src/main.rs
RUN cargo build --release
USER user
EXPOSE 8080
CMD ["/central-node/target/release/central-node"]
You already compiled an application before removing it's source files, then when adding yours into the container, main.rs is probably older than the already built artifact, therefore cargo considers it unnecessary to recompile.
Yes, I realize now. But perhaps some intermediary files remain that cause cargo to think the target were up to date?
Therefore have you checked cargo build -v --release (or even -vv)? I think for debugging the issue this flag might come in handy.
edit
In a project of mine, I deleted the binary after building the project, cargo build --release does nothing. I do consider this a bug in cargo.
another edit
Cargo is not doing nothing, its recreated from another cached artifact, that is more current than src/main.rs. This is obviously not a bug in cargo. This is a bug in how we try to abuse it. Try to rm target/release/$BINARY_NAME target/release/$BINARY_NAME* instead.
Of course I'd prefer if cargo would provide an option to fetch and build dependencies separate from the actual project/workspace.
This would so much better integrate in most CI workflows…