This documents my experience running PiBuilder against an AMD64 image (.iso
file) of Debian Bullseye under Parallels on an Intel Mac. It may be useful if you are trying to run PiBuilder on:
- hardware that is not a Raspberry Pi; and/or
- an operating system that is not Raspberry Pi OS.
I wanted to mimic the Raspberry Pi experience as closely as possible. That implies "headless" connecting only via SSH, with no need for any of the Parallels "integration" such as the ability to drag-and-drop between macOS and the Debian guest system.
To get the OS running, I followed Installing Debian Linux on your Mac using Parallels Desktop, save for the following exceptions:
- At step 6, I chose "Install" rather than "Graphical Install".
- I did not proceed beyond step 10.
I named the system "testbian" and the default user "pi". The installation process also asks for a password for the "root" user, which is needed for the su
command below.
To complete step 9 of the Parallels process, I used SSH to connect to the guest system from macOS Terminal. That implies the need to accept SSH's TOFU (Trust on First Use) challenge:
$ ssh [email protected]
$ su
# apt-get clean
… other commands from step 9
While logged-in as "root", I also took the opportunity to give "pi" the ability to execute sudo
commands, and then finished with a reboot, which is step 10 of the Parallels instructions:
# /sbin/usermod -aG sudo pi
# echo "pi ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/pi
# /usr/sbin/reboot
After the reboot, I reconnected, installed Git, cloned PiBuilder and ran the first script:
$ ssh [email protected]
$ sudo apt install -y git
$ git clone https://github.com/Paraphraser/PiBuilder
$ ./PiBuilder/boot/scripts/01_setup.sh
The optional «newhostname» argument to the 01_setup.sh
script is ignored because it depends on raspi-config
which is not available. The same applies to:
- Pi camera options (
ENABLE_PI_CAMERA
) - 64-bit kernel option (
PREFER_64BIT_KERNEL
) ; and - Updating the Raspberry Pi EEPROM.
The remaining scripts can be completed in order, with reboots or logouts at the end of each script:
$ ./PiBuilder/boot/scripts/02_setup.sh
$ ./PiBuilder/boot/scripts/03_setup.sh
$ ./PiBuilder/boot/scripts/04_setup.sh
$ ./PiBuilder/boot/scripts/05_setup.sh
In the 02_setup.sh
script, the VM_SWAP
options are ignored.
Compared with a vanilla install of Raspberry Pi OS, I noticed the following omissions from a vanilla install of Debian:
- git (needs to be installed by hand if PiBuilder is to be cloned directly onto the new system)
- rsync (now installed by
01_setup.sh
) - tree (added to
03_setup.sh
)
There may be others.
Next, I ran iotstack_restore
to load a backup taken earlier in the day on my "live" Raspberry Pi:
$ iotstack_restore 2022-11-23_1100.iot-hub
I edited the just-restored docker-compose.yml
to:
-
Remove all containers except Portainer-CE, Mosquitto, InfluxDB, Node-RED and Grafana. I chose these as the classic MING stack and because, aside from Node-RED mentioned next, there are no hardware dependencies.
-
Deactivate the Node-RED device mappings as follows:
x-devices: - "/dev/ttyAMA0:/dev/ttyAMA0" - "/dev/vcio:/dev/vcio" - "/dev/gpiomem:/dev/gpiomem"
The
x-
prefix deactivates the entiredevices:
clause.Note:
- Any container with a
devices:
clause will need similar treatment if the host platform (physical or virtual) does not implement a left-hand-side device. - There are pull requests pending for IOTstack which will alert you to devices issues. Many containers with device dependencies will work if are able to supply the relevant
/dev
path on your target system.
- Any container with a
-
This MING stack doesn't contain any examples of "privileged" network ports (numbers less than 1024). Those might be a consideration if the host operating system limits access (eg macOS Docker Desktop).
Then I brought up the stack:
-
The images that were pulled (and, in the case of images with an
iotstack-
prefix, augmented locally via Dockerfiles):$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE iotstack-nodered latest 3dd2852b8468 10 seconds ago 538MB iotstack-mosquitto latest aaff81eb15db 52 seconds ago 16.8MB grafana/grafana latest eb4a939d5821 12 hours ago 342MB portainer/portainer-ce latest 5f11582196a4 2 days ago 287MB influxdb 1.8 064158037146 7 days ago 308MB
-
The architectures associated with those images:
$ for I in iotstack-nodered iotstack-mosquitto portainer/portainer-ce influxdb:1.8 grafana/grafana ; do echo -n "$I: " ; docker image inspect $I | jq .[0].Architecture ; done iotstack-nodered: "amd64" iotstack-mosquitto: "amd64" portainer/portainer-ce: "amd64" influxdb:1.8: "amd64" grafana/grafana: "amd64"
-
And, finally, running successfully (ie not in restart loops and, where a container has a health-check script, the script is returning "healthy"):
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e1c0ab944e7c grafana/grafana:latest "/run.sh" About a minute ago Up About a minute (healthy) 0.0.0.0:3000->3000/tcp grafana 78e47141789f iotstack-nodered "./entrypoint.sh" About a minute ago Up About a minute (healthy) 0.0.0.0:1880->1880/tcp nodered 820e15bed543 portainer/portainer-ce "/portainer" About a minute ago Up About a minute 0.0.0.0:8000->8000/tcp, 0.0.0.0:9000->9000/tcp, 9443/tcp portainer-ce addfa7e969b8 iotstack-mosquitto "/docker-entrypoint.…" About a minute ago Up About a minute (healthy) 0.0.0.0:1883->1883/tcp mosquitto c2c9340afbc2 influxdb:1.8 "/entrypoint.sh infl…" About a minute ago Up About a minute (healthy) 0.0.0.0:8086->8086/tcp influxdb