We’re designing a one-click onboarding flow for our end users and would like guidance on the right architecture before we
commit to an approach.
What we want the user to experience
- The user opens our web app and clicks a single button.
- They get back a fully pre-provisioned and preloaded image — already bound to the correct fleet, with the latest release
baked in. - They flash that image to an SD card and boot. Nothing else. No balenaCLI, no Docker, no Balena account, no first-boot
configuration screens.
Everything that today is normally done by an operator running balena-cli (provisioning + balena preload) should happen
server-side, on our backend, transparently.
What we’d like the community’s input on
- Is there an officially supported way to perform balena preload from a backend service? Ideally via the SDK or HTTP API.
Everything we’ve found so far points to balena-cli / balena-preload, which assume Docker is available on the host and feel
designed for a developer’s laptop, not for a headless service. - What’s the recommended hosting setup on GCP for this kind of worker? Cloud Run / Cloud Functions seem to be out due to the
Docker-in-Docker requirement and the size of the artifacts. Are people running this on a GCE VM with Docker, on GKE with a
privileged sidecar, on a Balena-managed builder, or something else entirely? - How is concurrency and cost typically handled? Preload is heavy on disk, CPU, and bandwidth — multi-GB images, release
layers pulled per run. If two users click the button at the same time for the same fleet + commit, we don’t want to pay the
full cost twice. Is there a recommended pattern for queuing requests and caching preloaded artifacts between them? - Is it safe / supported to split the work into a cached expensive step + a cheap per-request step? I.e., cache a
preloaded-but-unconfigured image per (fleet, commit) in GCS, and only do the per-user configuration injection on the fly
before serving the download. Or does this break assumptions inside the preload tooling and we should preload + configure
together every time? - What’s the recommended way to deliver the final multi-GB artifact to the user? Streaming the file directly out of the
preload worker into the HTTP response, or pushing it to GCS and handing the user a signed URL? Any guidance on resumable
downloads so a flaky connection doesn’t force the user to start over?
Environment
- Backend: Node.js + TypeScript, planning to use balena-sdk.
- Hosting: GCP.
Any reference architectures, sample setups, or “don’t do that, do this instead” advice would be hugely appreciated before we
lock in a design.