top of page
  • Writer's pictureIvan Brko

Speeding Up Rust App Builds in Docker

Updated: Nov 14, 2023


Rust's emergence as a powerful language has challenges, particularly in build times. The language's requirement for dependencies to be compiled on the build machine can significantly slow down deployments, an issue in continuous integration and cloud environments where build time equates to cost. This blog discusses a method to speed up cloud builds of Rust Cargo workspace applications by utilizing a base build image. This image, preloaded with all necessary dependencies, streamlines the build process, reducing time and associated costs.


Rust Project used

This tutorial provides both the steps to build the Cargo project with just a single binary target, as well as building a binary project in a Cargo Workspace project. If you don’t know what Cargo Workspace is, take a look at Cargo Workspaces - The Rust Programming Language (rust-lang.org).


The approach

We will prepare a docker image that will contain all the dependencies of our project already prebuilt and we will push that image to our Docker repository. From now on we will refer to this image as build_base_image. We will trigger a build of the new version of this image when we introduce new dependencies or change the versions of the existing ones.

Then, in our actual build step of building a Docker image for our application (from now on, we’ll call this image application_image), we will use the build_base_image as the base image.

All the steps assume that the context of the docker build command is the root of your Rust project.


Building build_base_image

This is the dockerfile that will be used to build the build_base_image.

We copy the project to the /usr/src/app-build directory and build the release version there. This will also build all the dependencies.

After the build is complete, all the binaries (including the built dependencies) are contained in /usr/src/app-build/target/release/.

Later, when building the actual docker image for our application, we will do that under /usr/src/app directory, so as the last step of the Dockerfile for build_base_image image, we copy all the dependency-related artefacts we just built to that directory.

Store this file as base_build_image.Dockerfile in the root of your repository.



If you want to test this locally, run from the root of your repository:




Building our application_image

Now, when building our application, as the base image for the building phase we use the base_build_image that we created in the previous step. Note that, if you published the base_build_image to an image repository and you’re testing this in the cloud, you will have the change the name of the base image in the first step. The name provided here will work for the local test of the entire flow.

We store the following file as Dockerfile in the root of our repository:



Now, when you run the command to build the actual application image, you should notice that it’s fast as the dependencies are not getting built:




Conclusion

That’s it, this simple solution will greatly speed up the build of your Rust application Docker images by caching pre-built dependencies. Every time the dependencies change, make sure to rebuild the base_build_image and that’s all that’s needed, as our application Dockerfile depends on the latest version of the base_build_image.

92 views0 comments

Comments


bottom of page