Docker-compose

The compose file is not used at the moment by actual docker-compose, it is manually parsed and then fed to dagger.

Info

dagger does not support docker-compose at the time of writing.

There is also no existing docker-compose parser out there that we could use as off-the-shelf solution.

The custom parser implements only a limited feature-set out of the compose-file spec, just the bare-minimum needed to build the containers:

  • services
    • attach
    • build
    • blkio_config
    • ...
  • networks
  • volumes
  • configs
  • secrets

This way, we can have a single parametric Dockerfile for each item (coreboot, linux, edk2, ...) and introduce variation with scalable and maintainable single-file config.

Example

Example of compose.yaml file to build 2 versions of coreboot docker image:

services:
  coreboot_4.19:
    build:
      context: coreboot
      args:
        - COREBOOT_VERSION=4.19
  coreboot_4.20:
    build:
      context: coreboot
      args:
        - COREBOOT_VERSION=4.20

Multi-stage builds

We use multi-stage builds to minimize the final container / image.

Environment variables

In the dockerfiles, we heavily rely on use of environment variables and arguments.

This allows for the parametric nature.

Testing

Containers are also tested to verify that they were build successfully.

The tests are rather simple, consisting solely from happy path tests. This might change in the future.

Test is done by executing a shell script which builds firmware in some hello-world configuration example. Nothing too fancy.

The path to said shell script is stored in environment variable VERIFICATION_TEST.

Example of coreboot test

#!/usr/bin/env bash

set -Eeuo pipefail

# Environment variables
export BUILD_TIMELESS=1

declare -a PAYLOADS=(
	"seabios"
	"seabios_coreinfo"
	"seabios_nvramcui"
)

# Clone repo
git clone --branch "${VERIFICATION_TEST_COREBOOT_VERSION}" --depth 1 https://review.coreboot.org/coreboot
cd coreboot

# Make
for PAYLOAD in "${PAYLOADS[@]}"; do
	echo "TESTING: ${PAYLOAD}"
	make clean
	cp "/tests/coreboot_${VERIFICATION_TEST_COREBOOT_VERSION}/${PAYLOAD}.defconfig" "./${PAYLOAD}.defconfig"
	make defconfig KBUILD_DEFCONFIG="./${PAYLOAD}.defconfig"
	make -j "$(nproc)" || make
done

In addition, there might be VERIFICATION_TEST_* variables. These are used inside the test script and are rather use-case specific, however often used to store which version of firmware is being tested.

Adding new container

  • (optional) Add new Dockerfile into docker directory
  • Add new entry in docker/compose.yaml
  • Add new entry into strategy matrix in .github/workflows/docker-build-and-test.yml
  • (optional) Add new strategy matrix in .github/workflows/example.yml examples
    • this requires adding new configuration file in tests directory