This repo contains the scripts to serially modify an original RPi image (say, from the RPi Foundation), to add Pioreactor software and files. Builds currently target Raspberry Pi OS based on Debian Trixie (ships with Python 3.13).
When a new release is made in pioreactor/pioreactor, a dispatch is sent to this repo using Github Actions, including the version of Pioreactor software to use. A new workflow is kicked off that builds the images, creates a new release, and attaches the images to the release.
The following url will point to a specific asset in the latest release:
https://github.com/pioreactor/custopizer/releases/latest/download/<asset_name>
Available at nightly.pioreactor.com/
With Docker running:
bash make_leader_image.sh <version> ./config.local
Systemd Targets
- Common:
pioreactor.target— pulls up shared services (pioreactor-web.target,avahi_aliases,everyboot,firstboot,wifi_powersave,write_ip,local_access_point,pioreactor_startup_run@monitor,network-info.timer). - Leader:
pioreactor-leader.target— addsmosquitto,pioreactor_startup_run@mqtt_to_db_streaming,backup-database.timer,ui-exports-cleanup.timer. - Worker:
pioreactor-worker.target— addsload_rp2040. - Web:
pioreactor-web.target— groupslighttpd.serviceandhuey.servicefor joint start/stop/restart.
Enable only the appropriate targets during image build; individual units are not enabled directly in scripts anymore.
Timers (replaces cron)
network-info.timer: updates/boot/firmware/network_info.txtevery 5 minutes.backup-database.timer: weekly database backup viapio run backup_database.ui-exports-cleanup.timer: monthly cleanup of exported files in/run/pioreactor/exports.
Check with systemctl list-dependencies pioreactor*.target and systemctl list-timers on a device.
Web Stack Ops
- Restart both web services:
sudo systemctl restart pioreactor-web.target - Start/stop both:
sudo systemctl start|stop pioreactor-web.target
Environment File
- Shared env for units at
/etc/pioreactor.env:DOT_PIOREACTOR=/home/pioreactor/.pioreactor(used to locate configs and data)RUN_PIOREACTOR=/run/pioreactor(tmpfs for ephemeral runtime files)LG_WD=/run/pioreactorandTMPDIR=/tmp/for temp paths
- Units reference it via
EnvironmentFile=/etc/pioreactor.env.
Image Flavors → Targets
- Leader: enable
pioreactor.target+pioreactor-leader.target. - Worker: enable
pioreactor.target+pioreactor-worker.target. - Leader+Worker: enable all three targets.
These are applied by the top-level make_*_image.sh scripts and in CI.
Exports Location
/exports/is served from/run/pioreactor/exports(tmpfs, cleared on reboot). No exports are stored under~/.pioreactor.
FastCGI Socket
- lighttpd connects to the Flask backend via Unix socket
RUN_PIOREACTOR/pioreactor_web.sock.
Cache
- Transient UI/Huey/cache files live under
/run/pioreactor/cache(created on boot via tmpfiles), replacing the previous/tmp/pioreactor_cache.
- Builds Pioreactor-ready Raspberry Pi OS images from the official “lite” base by applying ordered customizations in
workspace/scripts/. - Produces three headless image flavors (leader, worker, leader+worker) that differ only by enabled systemd targets; build locally with Docker via
make_leader_image.sh,make_worker_image.sh, ormake_leader_worker_image.sh(bash <script> <pio_version> ./config.local), which output zipped.imgfiles inworkspace/. - GitHub Actions receives dispatches from upstream
pioreactorreleases, runs the same containerized build (seeaction.yml), and attaches the images to the latest release; nightly images are hosted athttps://nightly.pioreactor.com/. - Artifacts:
workspace/scripts/files/(systemd units/targets/timers, bash helpers, lighttpd configs, tmpfiles rules, firstboot/everyboot scripts, NetworkManager profiles) andsrc/(CustoPiZer driver files used in the container build). - End users download the desired image (leader/worker/leader_worker) from GitHub releases or nightlies, flash to an SD card, and boot; services come pre-enabled via targets (
pioreactor.target,pioreactor-leader.target,pioreactor-worker.target,pioreactor-web.target) so Pioreactor CLI/UI work immediately.