I am on Archlinux and am executing a simple docker build for a rust project that has a target
directory of 12GB.
Due to this problem, I have moved the /var/lib/docker
directory to /data/arch/var/lib/docker
with: rsync -avg /var/lib/docker /data/arch/var/lib/
and rm -rf /var/lib/docker
and ln -s /data/arch/var/lib/docker /var/lib/docker
The problem still persisted as the build reaches over 30GB which is all the free space I have on the data partition.
Inside the /data/arch/var/lib/docker
directory, the tmp
directory will grow to 12GB. Then the overlay2
will have at least 2 sub-directories grow with each having a diff
directory and a merged
directory both containing an app/target
that will contain 12GB.
/data/arch/var/lib/docker
/tmp -> 12GB
/overlay2
/dirXXX1
/merged/app/target -> 12GB
/diff/app/target -> 12GB
/dirXXX2
/merged/app/target -> 12GB
/diff/app/target -> 12GB
However, the dirXXX2 directory doesn’t actually get to 24GB as the build will run out of space and kill the whole process.
This seems overly excessive to me and wondering if something can be reconfigured here.
UPDATE:
I have also added to /etc/docker/daemon.json
:
{
"storage-driver": "devicemapper",
"log-driver": "local",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
Dockerfile:
FROM rust:1.72.0
WORKDIR /app
RUN apt update && apt install lld clang -y
COPY . .
RUN cargo build --release
ENTRYPOINT ["./target/release/zero2prod"]
2
Answers
Your current docker image includes not only the final build, but all source files leading to that, which are not required in the image
I’d consider using multi-stage builds to keep your image size smaller
For example, you could do something like:
(note: I haven’t tested this, but it should give you a general idea)
Reference: https://www.docker.com/blog/simplify-your-deployments-using-the-rust-official-image/
Add the
target
directory to a.dockerignore
file in your project, otherwise:target
directory from the host (if present) needs to be sent to the Docker daemon, which takes a while when it’s several gigabytes big; andCOPY . .
command in yourDockerfile
copies thetarget
directory from the host into the layer for that command.(In general, you probably want to keep your
.dockerignore
in sync with your.gitignore
/.hgignore
/etc., but for Rust projects, thetarget
directory is especially important.)