# How To: Build Mender-compatible system images with Rugpi

**URL:** <https://hub.mender.io/t/how-to-build-mender-compatible-system-images-with-rugpi/6958>\
**Category:** Debian family\
**Tags:** debian, rugpi\
**Created:** [June 17, 2024, 4:39pm UTC](https://hub.mender.io/t/how-to-build-mender-compatible-system-images-with-rugpi/6958 "2024-06-17T16:39:10Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![koehlma](https://yyz2.discourse-cdn.com/flex036/user_avatar/hub.mender.io/koehlma/32/1950_2.png) [@koehlma](https://hub.mender.io/u/koehlma)\
**Post date:** [June 17, 2024, 4:39pm UTC](https://hub.mender.io/t/how-to-build-mender-compatible-system-images-with-rugpi/6958/1 "2024-06-17T16:39:10Z")

</div>

This guide describes how you can use [Rugpi](https://rugpi.io) 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](https://www.raspberrypi.com/documentation/computers/config_txt.html#example-update-flow-for-ab-booting)).

**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](https://www.get-edi.io) and [debos](https://github.com/go-debos/debos)), (2) a robust OTA update mechanism (similar to [Mender standalone](https://docs.mender.io/artifact-creation/standalone-deployment)), 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.

**⚠ 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.](https://github.com/silitics/rugpi-template-mender/) 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](https://github.com/silitics/rugpi-template-mender/archive/refs/heads/main.zip). 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:

```auto
./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:

```auto
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`](https://github.com/silitics/rugpi-template-mender/blob/main/recipes/mender/files/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:

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

```

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

```bash
./run-bakery bake image rpi-raspios

```

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

```bash
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:

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

```

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

```bash
./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](https://rugpi.io/docs).

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