How To: Build Mender-compatible system images with Rugpi

This guide describes how you can use Rugpi to build Mender-compatible system images based on Debian (and Raspberry Pi OS). While Rugpi supports more devices, this guide focuses on building images that work on EFI-compatible systems (most modern commodity hardware) and on Raspberry Pi 4 and 5 (using the tryboot feature of Raspberry Pi’s firmware).

What is Rugpi? Rugpi is an open-source tool (MIT/Apache 2.0) providing three core features: (1) A workflow to build customized system images (similar to edi and debos), (2) a robust OTA update mechanism (similar to Mender standalone), and (3) state management inspired by Docker. The goal of Rugpi is to make it dead simple to build devices around customized Linux distributions. Rugpi strives to be easy-to-use and to cover common functionality needed when building a device (image creation, OTA update mechanism, state management, and maybe more in the future). For instance, Rugpi provides out-of-the-box support for factory resets.

Why Rugpi? While many excellent tools are already available for building images, updating systems, and managing state, integrating them into a robust setup can be challenging. Rugpi strives to simplify this process by bundling all essential functionalities into a cohesive package, allowing you to focus on what matters most to you and your users. We believe that building innovative devices shouldn’t be as complicated as it often is today. Although Rugpi may currently offer less flexibility and configurability than standalone solutions, it excels at delivering a robust base for your device right out of the box.

:warning: Disclaimer: While being compatible with Mender’s cloud offering, update server, and update client, the actual update is handled by Rugpi’s own update mechanism. Hence, the update artifacts cannot be used with existing Mender setups but can be deployed via Mender on systems using Rugpi. When using Rugpi, Mender effectively serves as a frontend for Rugpi. I still think that Rugpi may be interesting for this community, which is why I am posting this here. I also would like to point out that Rugpi is a young and evolving project. So, changes to the image building pipeline, CLIs, and APIs are expected. Nevertheless, as hundreds of devices are running Rugpi in production already, we are committed to maintaining backwards compatibility for updates.

How-To Guide

To get started quickly, we provide a GitHub template. This template includes:

  • Pre-defined images for Raspberry Pi 4 and 5 (ARM64 only).
  • Pre-defined images for EFI-compatible systems (ARM64 and AMD64).
  • Pre-defined images for VMs (e.g., QEMU).
  • Ready-to-use Mender integration (you just need your tenant token).
  • Ready-to-use GitHub Actions workflow for building images and Mender artifacts.
  • An example for including a simple static website in an image.

You can find the template here: GitHub - silitics/rugpi-template-mender: Template for building customized system images with Rugpi and Mender integration. The template also comes with a README with up-to-date information for how to use it.

The Basics

Rugpi consists of two tools, Rugpi Bakery and Rugpi Ctrl. Rugpi Bakery is for building customized system images while Rugpi Ctrl is for managing a system’s state at runtime and installing system updates. Rugpi Bakery allows you to specify multiple images while sharing customizations between them. This is useful, for instance, if you want to build different variants of an image for different devices. Every image is based on a layer. Most importantly, a layer provides the root filesystem and kernel for an image. Furthermore, it may also contain additional configuration files, e.g., for booting. Each layer consists of recipes that correspond to customizations that should be made. For instance, a recipe may install a web server and configure it to serve a static site. Layers and recipes are defined in the layers and recipes directories, respectively. The file rugpi-bakery.toml is the main configuration file in which images are defined.

The template ships with five layers:

  • efi-debian: Debian-based images for EFI-compatible systems.
  • rpi-debian: Debian-based images for Raspberry Pi.
  • rpi-debian-pi4: Debian-based images including a firmware update for Raspberry Pi 4 which is necessary for the tryboot mechanism to work.
  • rpi-raspios: Raspberry Pi OS-based images.
  • rpi-raspios-pi4: Raspberry Pi OS-based images including a firmware update for Raspberry Pi 4 which is necessary for the tryboot mechanism to work.

The template ships with two recipes:

  • mender: Installs and configures Mender.
  • hello-world: Installs Nginx and a static website.

Note that additional recipes are pulled in via Rugpi’s repository feature. Repositories allow for easy sharing of recipes and layers within the community.

1. Setup

First, obtain a local copy of the template, either directly via GitHub or by downloading the latest version. Rugpi Bakery, the tool to build images, is designed to run within a Docker container. To use it, you need to have a working Docker installation. Rugpi Bakery ships as a small shell script (run-bakery) that is included in the template. You can execute it as usual with:

./run-bakery

This should pull the latest Docker image and print usage instructions.

Note that the script works as-is on Linux and MacOS (provided Docker is set up correctly). On Windows, you can simply run Rugpi Bakery in WSL.

To build images for foreign architectures, you need to set up binfmt. The easiest way (and as we are using Docker anyway) is to run the following command:

docker run --privileged --rm tonistiigi/binfmt --install all

2. Configuration

To configure Mender, you need your Mender tenant/organization token. Note that this token, as any secret, should not be committed to Git. For this reason, we use a .env file for secrets. To configure the token, copy the env.template file to .env and replace the placeholder with your actual token. In addition, you may need to change the Mender server URL in the mender.conf configuration file that you find in the directory recipes/mender/files. If you want to be able to connect via SSH, put your public SSH key in the layer configuration files.

3. Building Images

To build an image for Raspberry Pi 4, including the necessary firmware update:

./run-bakery bake image rpi-raspios-pi4

To build an image for Raspberry Pi 5 or 4, without the firmware update:

./run-bakery bake image rpi-raspios

To create a Mender artifact from the produced rpi-raspios image:

VERSION=$(date +'%Y%m%d.%H%M')
mender-artifact write module-image \
    -n "Image ${VERSION}" \
    -t raspberrypi4 \
    -T rugpi-image \
    -f build/images/rpi-raspios.img \
    -o build/${VERSION}.mender \
    --software-name "Rugpi Image" \
    --software-version "${VERSION}"

To build an image for an AMD64 EFI-compatible system:

./run-bakery bake image efi-debian-amd64

To build an image that is directly usable with a VM (e.g., QEMU):

./run-bakery bake image efi-debian-amd64-vm

You can flash the images directly to an SD card or other storage medium.

More Information

If you like to learn more about Rugpi and how to use it, checkout Rugpi’s documentation.

If you have any questions, feel free to ask here or start a discussion on GitHub.

2 Likes