Building with Docker

Intro

Client engineers, embedded systems engineers, and other engineers who never worked with the backend can still benefit significantly from using containers. In this piece, I would like to share how I structure nearly all of my side proje…


This content originally appeared on DEV Community 👩‍💻👨‍💻 and was authored by Nikita Katchik

Intro

Client engineers, embedded systems engineers, and other engineers who never worked with the backend can still benefit significantly from using containers. In this piece, I would like to share how I structure nearly all of my side projects so that they can be built on any machine that has make and docker installed.

Motivation

Environment guarantee. Multiple employees and the continuous integration server (CI) can be confident they are building in exactly the same environment.

Environment versioning. Every team member does not have to build the builder images locally. Docker Registry can be used to store and version the images.

Easy workstation/build agent setup. As mentioned above, the only tools required to build such a project are make and docker.

Make is not used here as the project build system but rather as a convenient tool to wrap lengthy docker commands. For the scope of the article, we will assume a Rust project located at $(ROOT_DIR)/main using cargo build system.

Linux target

Let us start simple. Docker is always Linux, so the easiest way target platform to build for is Linux. This also works perfect for unit testing if you are writing a Linux or platform-independent application.

Makefile
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
SOURCE_DIR := $(ROOT_DIR)/main

IMAGE_BUILDER_LINUX := rust:1.61.0

build_linux: builder_linux
    @docker run \
    --rm \
    -v $(SOURCE_DIR):/src \
    $(IMAGE_BUILDER_LINUX) \
    sh -c 'cd /src && cargo build'

test_linux: builder_linux
    @docker run \
    --rm \
    -v $(SOURCE_DIR):/src \
    $(IMAGE_TESTER_LINUX) \
    sh -c 'cd /src && cargo test'

builder_linux:
    @docker pull $(IMAGE_BUILDER_LINUX)

Now a simple make build_linux and make test_linux should

  1. Make sure the builder Docker image is pulled
  2. Run build/test using the image

Custom builders

It is most likely that, eventually, you will need to customize the builder image. That would imply creating a Dockerfile and building an image using it instead of pulling the image as we did above.

Assuming the Dockerfile is located at $(ROOT_DIR)/image/x:

ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
SOURCE_DIR := $(ROOT_DIR)/main
PROJECT_NAME := $(shell basename $(ROOT_DIR))

IMAGE_BUILDER_X := $(PROJECT_NAME)-builder-x

builder_x:
    @docker build -t $(IMAGE_BUILDER_X) $(ROOT_DIR)/image/x

WebAssembly

Let me use this opportunity to share some scripts to build Rust code into WebAssembly and run the unit tests.

Makefile
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
SOURCE_DIR := $(ROOT_DIR)/main
PROJECT_NAME := $(shell basename $(ROOT_DIR))

RUST_TARGET_WEB := wasm32-unknown-unknown

IMAGE_BUILDER_WEB := $(PROJECT_NAME)-builder-web

build_web: builder_web
    @docker run \
    --rm \
    -v $(SOURCE_DIR):/src \
    $(IMAGE_BUILDER_WEB) \
    sh -c 'cd /src && cargo build --target $(RUST_TARGET_WEB)'

test_web: builder_web
    @docker run \
    --rm \
    -v $(SOURCE_DIR):/src \
    $(IMAGE_BUILDER_WEB) \
    sh -c 'cd /src && CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER=wasmtime_test_runner.sh cargo test --target $(RUST_TARGET_WEB)'

builder_web:
    @docker build -t $(IMAGE_BUILDER_WEB) $(ROOT_DIR)/image/web
image/web/Dockerfile
FROM rust:1.61.0

RUN \
rustup toolchain install '1.61.0-x86_64-unknown-linux-gnu' \
--target 'wasm32-unknown-unknown' \
--component 'rust-std'

RUN curl https://wasmtime.dev/install.sh -sSf | bash

COPY wasmtime_test_runner.sh /usr/bin

VOLUME ["/usr/local/cargo/registry"]
image/web/wasmtime_test_runner.sh
#!/bin/sh

/root/.wasmtime/bin/wasmtime "$@" --invoke main 0 0

It is relatively easy with Rust because rustup has a wasm32 toolchain ready to download, but with a more complicated cross-compiler setup, being able to make a Dockerfile describing the setup sequence is a lifesaver.

Thoughts

The more complicated the required build setup is, the more I recommend looking at the Docker-based building. Setting up a workstation to build a project requiring multiple cross compilers, especially when using certain toolchains that might require some user-fixing, can take up to a few hundred bash commands. That could theoretically be done without containers by a bash script, but that how numerous caveats, including:

  • State zero would have to be identical before running the script
  • Updating the build setup while keeping it identical between workstations
  • No environment guarantee
  • No switching between build setup versions


This content originally appeared on DEV Community 👩‍💻👨‍💻 and was authored by Nikita Katchik


Print Share Comment Cite Upload Translate Updates
APA

Nikita Katchik | Sciencx (2022-10-02T22:51:03+00:00) Building with Docker. Retrieved from https://www.scien.cx/2022/10/02/building-with-docker/

MLA
" » Building with Docker." Nikita Katchik | Sciencx - Sunday October 2, 2022, https://www.scien.cx/2022/10/02/building-with-docker/
HARVARD
Nikita Katchik | Sciencx Sunday October 2, 2022 » Building with Docker., viewed ,<https://www.scien.cx/2022/10/02/building-with-docker/>
VANCOUVER
Nikita Katchik | Sciencx - » Building with Docker. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/10/02/building-with-docker/
CHICAGO
" » Building with Docker." Nikita Katchik | Sciencx - Accessed . https://www.scien.cx/2022/10/02/building-with-docker/
IEEE
" » Building with Docker." Nikita Katchik | Sciencx [Online]. Available: https://www.scien.cx/2022/10/02/building-with-docker/. [Accessed: ]
rf:citation
» Building with Docker | Nikita Katchik | Sciencx | https://www.scien.cx/2022/10/02/building-with-docker/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.