Dockerize Rust: Getting Started and Private Crate (P1)

Dockerize Rust: Getting Started and Private Crate (P1)
Photo by Ian Taylor / Unsplash

There are many ways to deliver software to the world. If you want simplicity, you can upload your code and run it on-premise or in the cloud. If you want to isolate your application’s runtime environment, you can use VMware or Docker, depending on the level of isolation you require. Nowadays, modern cloud software seems to be using Docker and Kubernetes to deliver their projects. I also use docker to deliver my rust projects and face with many challenges. I want to share with you.

In this post, we will checkout:

  • How to create a dockerfile for Rust Project.
  • Using Private Crate (Non published crate or In house crate)

A simple Dockerfile

Let start simple, we've a project - called "rodgers".

To quickly create a Rust project, you can use the following bash command:

$ mkdir rodgers && cd rodgers
$ cargo init . 
$ cargo check

Add a Dockerfile to build the container.


FROM rust:1.70

WORKDIR /app
ADD src /app/src
ADD Cargo.toml /app/
ADD Cargo.lock /app/

RUN RUST_BACKTRACE=1 cargo build --release

# Build Complete, Do some thing you want like expose port, etc.

CMD ["./rodgers"]

Dockerfile

Now, you can build docker container for your project by using command:
docker build . -t rodgers:dev.

[+] Building 19.1s (11/11) FINISHED                                          ...
...
 => => naming to docker.io/library/rodgers:dev  

Use Private (in-house) Crate in Rust Project

Imagine that your company has some private crates that you don’t want to publish on crates.io for security reasons. You want to use these crates in your project, but the Dockerfile above cannot fetch the crate to build it.

Given that you have a in-house crate that is called "private-rodgers". It's awesome lib but you don't want to publish into the public github or crate.
According to rust docs, you need to setup like this in your Cargo.toml file.

...
private-rodgers = { git = "ssh://[email protected]/cptrodgers/private-rodgers", tag = "0.1.0"  } # You can use tag, revision (commit hash), or branch.
...

Cargo will fetch and install "[email protected]" into your project without published work for "[email protected]".

In this scenario, the primary challenge of dockerizing your project lies in transforming your SSH key into the Docker build environment, ensuring that the Docker engine has the correct permissions to fetch and build the private crate. To achieve this, you must enable Docker's experimental mode by adding "#syntax=docker/dockerfile:experimental" at the beginning of the Dockerfile. Then, utilize the command "docker build --ssh default . -t rust-base:test" to incorporate your SSH agent information into the Docker build process. This step enables seamless integration and allows the Docker engine to access and build the private crate with the necessary permissions.

Your new Dockerfile.

# syntax=docker/dockerfile:experimental
FROM rust:1.70

WORKDIR /app
ADD src /app/src
ADD Cargo.toml /app/
ADD Cargo.lock /app/

RUN RUST_BACKTRACE=1 cargo build --release

# Build Complete, Do some thing you want like expose port, etc.

CMD ["./rodgers"]

After enabling Docker's experimental mode and incorporating your SSH agent information into the Docker build process, the bash command to build the Docker image is as follows:

$ DOCKER_BUILDKIT=1 docker build --ssh default . -t rodgers:dev

This command initiates the Docker build process with the specified SSH agent information and tags the resulting image as "rust-base:test". The period at the end of the command indicates that the build context is the current directory. Adjust the tag and other parameters as needed for your specific requirements.


Thanks for reading this post. In the next post of #dockerize-rust, I will solve the building time problem of Rust.