a rust rookie here, I'm trying to generate a smaller docker images for a rust projects. I want to be able to do code changes from a shared volume to make development and reload of these projects much faster or automated. I followed a couple of the guides but got errors. Is there a working guide on how to create such images?
yes that's correct, I have multiple projects that I want to create containers for and manage them with a docker-compose file. This is my docker file, I'm using a demo app to make this work first:
FROM rust AS build
WORKDIR /usr/src
# Download the target for static linking.
RUN rustup target add x86_64-unknown-linux-musl
RUN USER=root cargo new my-app
WORKDIR /usr/src/my-app
COPY Cargo.toml Cargo.lock ./
RUN cargo build --release
# Copy the source and build the application.
COPY src ./src
RUN cargo install --target x86_64-unknown-linux-musl --path .
# Copy the statically-linked binary into a scratch container.
FROM scratch
COPY --from=build /usr/local/cargo/bin/my-app .
USER 1000
CMD ["./my-app"]
the result:
build failed
The command '/bin/sh -c cargo install --target x86_64-unknown-linux-musl --path .' returned a non-zero code: 101
I'm using my MacBook as a dev machine. I don't have a linux box. I have docker desktop installed with Kubernetes enabled and a VMware image running for the docker machine.
I'm now trying to test creating two rust containers. Trying to figure out how the workflow of dev / build / publish to Kubernetes works!!
I can always run VMware and install docker on the linux virtual to do the development if that resolve some issues. Would that be more ideal?
I thought you want to build inside of docker, so the Mac is irrelevant... Also you are already running docker in a virtualized Linux, that's how docker on Mac and Windows works for non Mac/Windows containers...
Note that the last step removes apt files that are not necessary after installation in order to reduce image size. Although, I wouldn’t worry about image size until after you have a working container.
you can achieve relatively small image with dynamic binary when using alpine
for static builds, especially if you have dependencies on C/C++ libraries alpine is better because it has all libraries compiled with Muslim
cargo install command is probably additional, just install musl target with rust up and then cargo build with musl target. Or use alpine as noted above cause musl is default target there.
I thought the project gets outputted as one binary that would need to be copied to that directory!! isn't that the case? I was following the guide I saw online from a couple of posts!
When you run cargo build (or run/test/bench), the project is built in ./target, and all results sit there.
You never need to call cargo install to build a project, unless you want to actually install the produced binary as a system-wide developer tool living in Cargo's bin directory.
If your project is a library, then cargo install doesn't make any sense and serves no purpose.
If you want to deploy the binary on the server, then copying from ./target to some other "deployment" destination OK-ish. cargo install does basically the same thing.
For slightly better deployment, if you use Debian/Ubuntu, I suggest running cargo deb or cargo deb --install, which will properly install the binary on the system.