The basic principle of the CattlePi project is that “we want to turn your pet projects into cattle projects”. This means that, ideally, you would keep zero state on the Raspberry Pi devices in your fleet and you would dynamically figure out what the Pi should be running either at boot time or periodically at runtime.
That’s how we envision you will be using CattlePi.

That being said there are times when you do want a stock Raspbian install and you do want to leverage Raspbian in exactly the same way you would if you were to write it to the SD card yourself.

Because, at the end of the day, we are pragmatic and we want to enable you to use your Pi however you want we’ve put together a recipe that allows you to write a Raspbian Lite Stock image directly on the SD card.

CattlePi will control the Pi only long enough to write the image and after that it will hand over the full control to the Stock Raspbian image. (via a reboot)
If you’ve used something like etcher in the past, you can think about this as etcher-on-the-fly

Recipe is: here
To build it: make raspbian_stock

See the PR that implemented this feature here.

The important bits are at the end.

For completeness, here is how is the stock raspbian we are laying down different from what you would get via something like etcher:

  • the root partition is not expanded (raspbian does this on first boot via a somewhat shady mechanism: it point the kernel init to the resize script). The init based script also assumes (reasonable assumption) that the rootfs partition is going to be the last partition. We don’t have this limitation
  • as mentioned before we install jq
  • we run the bootstrap script that allows us to inject the ssh keys (if any) and run the usercode (if any). So this way we can take control over the pi running the stock raspbian via the device boot configuration.

So you’ll get the same as stock raspbian with the 3 mentioned differences. You need the sd card to be in a compatible layout (compatible layout means at least 2 partitions, the first one being a FAT partition (type b), and the 2nd one being a linux partition (type 83) + the sdcard needs to have a dos mbr) or you need to associate the proper sdlayout to enable it. More on sdlayout in this previous tutorial

Also, here is an example of device boot target configuration configuration that uses this recipe:

  "bootcode": "",
  "config": {
    "autoupdate": true,
    "ssh": {
      "pi": {
        "authorized_keys": [
          "your ssh public key"
  "initfs": {
    "md5sum": "ab926ee004f75f95a74e248669b514ec",
    "url": ""
  "rootfs": {
    "md5sum": "beb384432a55688d82575df40c8daeed",
    "url": ""
  "usercode": ""

The decoded (valid in this case) sdlayout is:

label: dos
device: /dev/mmcblk0
unit: sectors

/dev/mmcblk0p1 : start=        2048, size=     8192000, type=b
/dev/mmcblk0p2 : start=     8194048, size=    18432000, type=83

Final note: inside a booted Pi that successfully wrote the stock raspbian to sd card and rebooted you will find a script /etc/cattlepi/ that you can use if you ever want to revert this Pi to being managed by CattlePi. Should you ever want to revert make sure you have an up-to-date device boot target config and run this script with root privileges.

Find the latest raspbian stock image info in the Images section.