Build and package Rust applications into minimum Dockers

Build and package Rust applications into minimum Dockers

Learn how to build and package your Rust application in a container using docker's multi-stage build feature.

Learning Rust has been on my personal backlog for a while now. As I started digging in, I decided to build a small web application as an exercise. Once I had an initial version of the app working, I wanted to package it up as a docker image so that I could later deploy it to a Kubernetes cluster.

In the Go world, it is common to use docker’s multi-stage build feature to produce the app’s docker image in two stages. The first stage uses the golang image and is where we build the application into a statically-linked binary. Once built, we copy the binary into a scratch container in the second stage. The result is a rather small image that has nothing other than the application.

I was looking to do the same thing for my Rust application. While I was at it, I also wanted to leverage the docker build cache to avoid having to download crates on every docker build.

After reading a couple of posts online, this is the Dockerfile that I ended up writing for my app:

# Dockerfile for creating a statically-linked Rust application using docker's
# multi-stage build feature. This also leverages the docker build cache to avoid
# re-downloading dependencies if they have not changed.
FROM rust:1.35.0 AS build
WORKDIR /usr/src

# Download the target for static linking.
RUN rustup target add x86_64-unknown-linux-musl

# Create a dummy project and build the app's dependencies.
# If the Cargo.toml or Cargo.lock files have not changed,
# we can use the docker build cache and skip these (typically slow) steps.
RUN USER=root cargo new url-shortener
WORKDIR /usr/src/url-shortener
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/url-shortener .
USER 1000
CMD ["./url-shortener"]

When it comes to building docker images, one of the best practices is to keep your images small. This reduces the number of “things” in your container, and thus reduces its attack surface. Furthermore, it reduces download times and disk usage.

With the Dockerfile above, the resulting docker image is 4.6 MB in size, compared to a whopping 2.15 GB if we were to use the rust image as the base layer. That is a big difference.

Thanks for reading !

rust docker

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Docker Explained: Docker Architecture | Docker Registries

Following the second video about Docker basics, in this video, I explain Docker architecture and explain the different building blocks of the docker engine; docker client, API, Docker Daemon. I also explain what a docker registry is and I finish the video with a demo explaining and illustrating how to use Docker hub.

Docker Tutorial for Beginners 8 - Build and Run C++ Applications in a Docker Container

Welcome to this on Docker Tutorial for Beginners. In this video provides an Introduction on C++ development with Docker containers. So we will see How to ship C++ Programs in Docker.

WordPress in Docker. Part 1: Dockerization

This entry-level guide will tell you why and how to Dockerize your WordPress projects.

Docker manifest - A peek into image's manifest.json files

The docker manifest command does not work independently to perform any action. In order to work with the docker manifest or manifest list, we use sub-commands along with it. This manifest sub-command can enable us to interact with the image manifests. Furthermore, it also gives information about the OS and the architecture, that a particular image was built for. The image manifest provides a configuration and a set of layers for a container image. This is an experimenta

List all containers in Docker(Docker command)

We can get a list of all containers in docker using `docker container list` or `docker ps` commands.