Skip to content

doc: add a guide on getting started using configuration files#207

Open
johanehnberg wants to merge 10 commits into
raspberrypi:masterfrom
johanehnberg:doc/gettingstarted
Open

doc: add a guide on getting started using configuration files#207
johanehnberg wants to merge 10 commits into
raspberrypi:masterfrom
johanehnberg:doc/gettingstarted

Conversation

@johanehnberg
Copy link
Copy Markdown

@johanehnberg johanehnberg commented Mar 12, 2026

WIP tasks

  • Set the file location and if in root add a link in README or in doc add it to the ToC accordingly
  • Augment the guide with something common and simple yet descriptive. For example defining a one-liner command in the config that runs on target to install camera/AP/sensor. Settled on SSH and wifi.
  • Fix code snippet definitions sh->yaml for yaml files
  • Test everything before removing WIP

Ideas for minimizing caveats and guide length outside the scope of this PR:

Closes: #206

@learmj
Copy link
Copy Markdown
Collaborator

learmj commented Mar 12, 2026

Hi @johanehnberg Let's just keep it all in one 'getting started' doc. Myself and others plus external / community will review it when it has content.

@johanehnberg
Copy link
Copy Markdown
Author

@learmj OK. If the general structure of the document sits well with the project, all I need is a good, common case to use in the example. Preferably something that helps people install their own app/assets/file and run a command, but the working example only needing one such line each.

@learmj
Copy link
Copy Markdown
Collaborator

learmj commented Mar 12, 2026

@learmj OK. If the general structure of the document sits well with the project, all I need is a good, common case to use in the example. Preferably something that helps people install their own app/assets/file and run a command, but the working example only needing one such line each.

Sounds good. If you're basing it on your own use / experience, that would serve others well.

@johanehnberg
Copy link
Copy Markdown
Author

I added wifi station config as the simplest use case that we also have. It seems to have been requested so this may work as a stop-gap solution at least until a layer may be created. Considering the simplicity, I created #208 to allow streamlining much of this.

@johanehnberg johanehnberg changed the title WIP: doc: add a guide on getting started using configuration files doc: add a guide on getting started using configuration files Mar 14, 2026
@johanehnberg johanehnberg marked this pull request as ready for review March 14, 2026 18:42
@johanehnberg
Copy link
Copy Markdown
Author

Ready for review. The guide is a bit longer than what I aimed for, but as the tool matures and built-in layers get added, it can be shortened. The contents are now such that would have saved me a lot of hours when I started.

Copy link
Copy Markdown

@jaysephjw jaysephjw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stumbled across this as I was looking at the project for the first time - and found it quite helpful!

Just a couple comments as I tried it.

Comment thread getting_started.adoc Outdated
Comment thread getting_started.adoc Outdated
Comment thread getting_started.adoc Outdated
@learmj
Copy link
Copy Markdown
Collaborator

learmj commented Mar 18, 2026

Hi @stu-spp @martinn-ronin
As users who have previously indicated a preference for some intro documentation, how does this look to you?

Hi @johanehnberg I'd prefer to wait on getting some user / community feedback before merging. Thanks again for your efforts.

@johanehnberg
Copy link
Copy Markdown
Author

Thanks @jaysephjw for the feedback! All fixed.

@stu-spp
Copy link
Copy Markdown

stu-spp commented Mar 18, 2026

This looks great! ❤️

Comment thread getting_started.adoc Outdated
Comment thread getting_started.adoc Outdated
Comment thread getting_started.adoc Outdated
Comment thread getting_started.adoc Outdated
Comment thread getting_started.adoc
Comment thread getting_started.adoc Outdated
Comment thread getting_started.adoc
@johanehnberg johanehnberg requested a review from learmj April 30, 2026 09:22
Comment thread getting_started.adoc Outdated
Copy link
Copy Markdown
Contributor

@devopsbob devopsbob left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mentions that it will override the timezone but not which timezone or how.

@martinn-ronin
Copy link
Copy Markdown

I truly appreciate all the work going into this tool and the effort to make it easier for more people to get started. The new getting started guide already helped me significantly compared to where I was before.

That said, I am still struggling to get my specific builds working and I find it difficult to understand how all the layers, suites, distributions, and device configurations are intended to fit together when moving beyond the provided examples.

I also feel the documentation and examples currently jump from simple concepts to more advanced compositions quite quickly without enough intermediate step-by-step guidance. As a new adopter, I often find myself unsure whether an issue is caused by my environment, my configuration, missing layer relationships, or unsupported combinations.

I really want to adopt this over my current system because the architecture and direction of the project look extremely promising, but at the moment the learning curve still feels quite steep for someone trying to build custom images outside of the exact provided examples.

@johanehnberg
Copy link
Copy Markdown
Author

@martinn-ronin thanks for your input! For the scope of this getting started document, would you say it works as a good second step after the README? Were there any issues that you stumbled upon? Is there a need to extend some aspect of it, so as to bridge the gap to the technical documentation in https://raspberrypi.github.io/rpi-image-gen/execution/index.html ?

@martinn-ronin
Copy link
Copy Markdown

@johanehnberg Honestly, I am still not entirely sure what I am doing wrong, or even fully sure I understand the intended workflow yet.

The new getting started guide definitely helped me get my environment set up correctly and helped me progress further than before, so it was absolutely useful. However, I still find there is a fairly large gap between getting the tool installed/running and understanding how to confidently build my own image configuration from scratch.

At the moment, I can build the provided examples successfully, but that was already roughly the point I had reached before. I still struggle to understand how to create a simple custom image for my own use case (for example a Trixie armhf image for an RPi4), or whether certain combinations are currently supported or expected to work differently.

Part of this is definitely my own experience level. I have limited Linux experience outside of basic bash scripting, and very little prior experience with image build systems. I also found a YouTube tutorial that helped explain some concepts well, but it was made before the recent restructuring of the project, so some workflows no longer seem to match the current structure of the tool.

I think what would help me most would be a slower, more incremental walkthrough aimed at users who are new to this style of image building. For example:

  • Build a very basic image successfully

  • Explain how device, distribution, suite, and image layers relate to each other

  • Then progressively extend the image step by step:

    • adding a user
    • adding Wi-Fi
    • adding packages
    • customising boot behaviour
    • slimming the image down
    • eventually adding OTA/update functionality

Right now I often find myself unsure whether an issue is caused by:

  • my environment
  • my configuration
  • unsupported layer combinations
  • or simply misunderstanding the intended workflow

I completely understand that documenting all of this thoroughly is a large amount of work, and I do not mean this as criticism. I mainly wanted to provide feedback from the perspective of someone who is very interested in adopting the tool, but is still early in the learning process.

@johanehnberg
Copy link
Copy Markdown
Author

Thanks for your detailed description. In many ways, your situation is very much the one I am trying to ease with this PR contribution. I am not affiliated with RPi, just giving back to a project of value to us, as I found myself in your shoes not long ago. Here are some thoughts of what you could try. Let me know what sticks, and I will consider if that can somehow be baked into the guide.

  1. Before working on your own configuration file, to "build a very basic image" (and as I've noted in many cases, to debug with minimal dependencies and other baggage): build with just some command line arguments. Something like this should already give you a bootable image:
    ./rpi-image-gen build -c ./config/trixie-minbase.yaml -- IGconf_device_layer=rpi4

  2. Build your first own config from the above arguments (or reducing the example to the minimum you can use to test). Add one configuration value at a time when iterating and testing.

  3. Use known good tagged releases rather than master. This project is still introducing breaking changes. Similarly, try new releases with a known good config.

  4. Write your customization scripts in a "non-rpi-image-gen" format, i.e. so you can test them easily on a stock image, where possible.

@johanehnberg
Copy link
Copy Markdown
Author

@martinn-ronin I saw you also mentioned armhf and #168 . We too have a use case for full armhf. Let me know if you find out how. Adding the below to the config did not suffice, even if trixie-minbase advertises armhf (it still installs arm64).

mmdebstrap:
  architectures:
    - armhf

I'll add it to the guide if solved.

@martinn-ronin
Copy link
Copy Markdown

@johanehnberg I have currently decided to move past the full armhf userspace requirement for now, as the only armhf component we specifically need is support for running an armhf .NET application. I am currently exploring whether the arm64 + armhf multiarch setup is sufficient for this use case, since from my understanding the arm64 armhf configuration provides armhf foreign architecture support rather than a fully native armhf userspace.

If this approach works, then my next goal is to move fully over to rpi-image-gen and replace our existing provisioning/setup script with fully reproducible baked images, which would be a much better long-term solution for us operationally.

Unfortunately I probably will not be able to help much with solving the pure armhf userspace side of things, as I am still very new to this ecosystem. My closest experience to image building before this has mostly been Docker images and Bash scripting.

@learmj
Copy link
Copy Markdown
Collaborator

learmj commented May 11, 2026

I must thank @johanehnberg again for the contribution, but also for the continued work to make sure it's scoped correctly to help onboard new users. I really appreciate the sustained effort.

@martinn-ronin I saw you also mentioned armhf and #168 . We too have a use case for full armhf. Let me know if you find out how. Adding the below to the config did not suffice, even if trixie-minbase advertises armhf (it still installs arm64).

mmdebstrap:
  architectures:
    - armhf

I don't know if conflating config file syntax with a layer only YAML key (mmdebstrap) was intentional here. If so, it isn't the first time I've both mentioned in the same context - they are not the same. From a usability and user feedback perspective, while the config parser will allow it, having...

mmdebstrap:
  architectures:
    - armhf

...in a config file won't do anything, so is essentially a silent fail. The syntax is layer file only:
See the bdebstrap man page.
I wonder if it's worth detecting mmdebstrap in the config parser and bailing out with an informative error.

While YAML is the unified file format for configuration files and layer files, the two are different and serve different purposes.

@johanehnberg
Copy link
Copy Markdown
Author

I believe the armhf question would be good to cover from both angles relevant here. After all, it is one of the three key properties of the official images, too (the two others being image content and release). As such, it is becoming clear to me what drives people to this tool rather than official images: to take control over those three basics.

The first angle would be the config validation, which already does similar sanity checks. The other would be the documentation, which I can do if you point me in the right direction. It seems building with just IGconf_layer_base=raspbian-trixie-armhf is not sufficient:

==> parameter_assembly

PARAM
CFG IGconf_device_layer=rpi3
CFG IGconf_layer_base=raspbian-trixie-armhf

ENV
<snip>
MMDEBSTRAP
Loaded rpi-boot-firmware
Loaded rpi-linux-v8
Loaded rpi-generic64
Loaded raspbian-trixie-armhf
<snip>
E: Unable to locate package linux-image-rpi-v8
<snip>
E: mmdebstrap failed to run

Is the tool currently capable of building armhf using the built-in layers?

@johanehnberg
Copy link
Copy Markdown
Author

For completeness, without device, the image generation does not work. Currently the device layer forces the architecture. Perhaps one approach would be to create architecture property for devices for conditional layer dependencies? Or just parallel device layers for armhf?

@martinn-ronin
Copy link
Copy Markdown

I just wanted to add some thoughts on how I personally see many users approaching and wanting to use this tool.

From my perspective, many people getting started with Raspberry Pi systems usually begin by selecting a device (Pi 4, Pi 5, CM4, etc.), combining it with off-the-shelf hardware, and then building a system around that. Even the official Raspberry Pi Imager follows a very similar workflow:

  1. Select device
  2. Select operating system/distribution
  3. Select architecture
  4. Configure initial setup/customization
  5. Flash and iterate from there

I think many users then eventually discover rpi-image-gen once they reach the point where they want:

  • reproducible systems
  • automated provisioning
  • reduced setup scripting
  • custom images
  • better long-term maintainability

However, I think the current learning curve is very high for users who are not already familiar with building fully custom Linux images or embedded systems. The technical documentation around layers is very detailed and powerful, but it appears more oriented toward users who already understand concepts like custom distributions, image composition, layered build systems, dependency graphs, and low-level Linux provisioning.

The technical documentation on using layers actually suggests what I think is the correct mental model already:

  • pick the device
  • pick the base image/distribution
  • add layers/features
  • configure variables
  • build

But in practice, I found it difficult to translate that into a real-world workflow when starting from scratch.

Personally, I think a workflow like the following would feel much more approachable to newer users:

  1. Select target hardware (Pi 4, Pi 5, etc.)
  2. Select architecture (arm64, armhf, multiarch, etc.)
  3. Select a base OS profile (minimal, desktop, lite, etc.)
  4. Add optional functionality layers:
    • desktop
    • VNC
    • Raspberry Pi Connect
    • SSH
    • networking customization
    • packages
    • provisioning
    • custom applications
  5. Configure deployment variables
  6. Build image

I think the examples currently available make the layering and composition model somewhat difficult to follow initially, especially for users coming from more common Raspberry Pi workflows rather than embedded Linux development backgrounds.

This is not criticism of the project itself — I actually think the architecture and long-term potential of rpi-image-gen is extremely powerful. One of the main reasons I want to persevere with learning it is because I can already see how much more maintainable and reproducible this workflow could become compared to backing up SSDs or relying heavily on post-install setup scripts.

If I can properly understand and adopt this workflow, I can see it becoming useful across many future projects where deterministic image generation makes far more sense than manually configuring systems after deployment. In many ways, I personally see this kind of layered image composition workflow as being as powerful for operating system images as Docker was for application deployment and containerization.

@learmj
Copy link
Copy Markdown
Collaborator

learmj commented May 12, 2026

@johanehnberg

Is the tool currently capable of building armhf using the built-in layers?

It is, but it looks as though you haven't included the layer which adds the RPi apt repo (eg this one). Since linux-image-rpi-v8 is hosted there, apt has no way to locate it, hence your error. Note that you won't find linux-image-rpi-v8 in the rpi armhf repo anyway - only linux-image-rpi-v6.

FWIW, in my own personal view, there is little need for the Raspbian repo nowadays, unless working with legacy devices. Even Pi3 can execute 64-bit.

Be careful generalising on 'armhf', though...

Some time ago, people were building images based on Debian armel, which is debian's armv6 soft float architecture. Using armv6 hard float resulted in a modest performance boost, but Debian's armhf architecture is armv7 and so not compatible with all devices at the time. Raspbian was started as a project to rebuild all of Debian armhf to be armv6hf and that's still what it hosts today. So while it is 'armhf', it's actually armv6hf so is compatible with all (RPi) devices.
See https://forums.raspberrypi.com/viewtopic.php?t=22090

These days, arm64 is the typical primary architecture and when listed first in the YAML under the architectures key, apt treats it as the native architecture [1]. Additional architectures can be specified after the primary and these are treated as foreign. You can boot a 64-bit kernel (eg linux-image-rpi-v8) on a device with an ARMv8 instruction set and still use 32-bit armv6hf userland with it, but I'm unsure how many actual use cases there are for such an environment these days (@martinn-ronin this is what you were describing in #168).

For completeness, without device, the image generation does not work.

The term 'image' can be ambiguous. rpi-image-gen can generate a filesystem as the input for a container 'image' file but it does not require a device layer to do so. If you're referring to using the tool to create a bootable disk image file for a device's storage media, then yes - it obviously needs a device layer for that.

Currently the device layer forces the architecture.

I suppose it does, but it doesn't have to. It's probably only that way due to the inter-dependency between layers. If the usage of X-Env-Layer-Requires [2] was tighter, the dep chain could resolve back to a 'Debian Base' and that could set the primary (ie native) architecture of the chroot. Actually, this is something I contemplated doing some time ago (and still might). It would be trivial enough to utilise X-Env-Layer-RequiresProvider to force a configuration that mandated a 'debian-base', therefore that would set the primary/native architecture of the chroot rather than the device, but it kind of seems sensible for the device layer to set the native architecture.

Also note that the rpi-debian-trixie layer does not force an architecture - it just inherits from what is set by apt (which may of course have been from upstream layers). It might surprise you that we build lots of packages for different architectures, including amd64.

@martinn-ronin Thanks very much for taking the time to write up your thoughts and views. It's greatly appreciated. That kind of feedback helps us understand the spectrum of users who are considering / trying to adopt using the tool. Ultimately, it helps us understand more about our target audience.

@johanehnberg
Copy link
Copy Markdown
Author

As a first and perhaps only requisite step, to me it sounds like a single working armv6hf native build - akin to the official 32-bit images - can cover all the remaining use cases:

  • Legacy devices (rpi0 rp1 rpi2)
  • Armhf userland
  • The raspbian-exclusive software and rasbbian-exclusive patched versions of common software

That would keep the effort required on "legacy" to a minimum. Beyond that, the demand can likely only be for more optimized (zram, armv7hf?) or specific (arm64 kernel + armhf userland, other storage types than SD) approaches for already covered use cases, so further effort have much diminished returns.

I started looking into that now. However, I could not find any way to build with the existing layers, so I created new ones to introduce a start on being able to create actual native armhf builds. I got to the point that the build creates an SD image that boots on armv7l rather than arm64. The boot stops on looking for init, and the build stops post-image on IDP validation. @learmj would you like a draft PR with this proof-of-concept or just an issue?

@learmj
Copy link
Copy Markdown
Collaborator

learmj commented May 12, 2026

I'm not really sure. My gut says no (thanks). I don't know how many users would legitimately expect to be able to use rpi-image-gen to create bootable images for their rpi0, rp1, or rpi2 devices. In all likelihood, if those devices are operational and serving a purpose today, there would be questionable benefit in effectively reflashing with a totally different image and setting it back up again.

@johanehnberg
Copy link
Copy Markdown
Author

The use cases go beyond legacy devices. And it also raises the question, why are the raspbian, kernel 6 - 7l and related resources already included in the repository?

In any case, planned obsolescence does not resonate well with us, while justified maintenance burden considerations do. rpi1 through rpi3 still beat rpi4 and rpi5 in low power ethernet environments, and I am sure there are other cases like industrial integrations. RPi stands out it the SBC world with its good support.

@learmj
Copy link
Copy Markdown
Collaborator

learmj commented May 12, 2026

I added the raspbian repo a long time ago to keep parity with pi-gen - the tool that generates the official RPiOS images. There is no kernel 6 support in the repo.

planned obsolescence does not resonate well with us

The practice of purposefully limiting the supply or durability of products in order to sell more (new) products is not the same as being [edit] unable to sustain high-volume manufacturing of a product.

Ref: [1] and [2]

You misunderstood my previous comment.

@johanehnberg
Copy link
Copy Markdown
Author

Thanks for the info. It is up to this project to decide on those strategic topics. For the current case, it is just about software support, not manufacturing. I will wait to hear the outcome of the decision.

In the meantime, here's a look at the PoC: https://github.com/raspberrypi/rpi-image-gen/compare/master...johanehnberg:rpi-image-gen:armhf-native?expand=1

It makes for a good guide case at least.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make learning curve more gentle (PR contribution offer)

6 participants