Article summary
You may have heard of Balena from the excellent (and free!) balenaEtcher, which has become a favorite tool for writing OS images to USB sticks and SD cards. What you may not be aware of, though, is the company’s main products: BalenaCloud and BalenaOS.
When I think of embedded/Internet-of-Things (IoT), I think of tiny microcontrollers, proprietary C compilers, and developers struggling for every last kilobyte of memory. The Balena platform sits in a different space, meant for single-board computers like Nvidia Jetson and Raspberry Pi.
Relatively inexpensive single-board computers like the Raspberry Pi 4 have become powerful enough to run multiple containerized services with reasonable performance. Balena has embraced this to build its own container-optimized embedded Linux distribution (BalenaOS), paired with a management software service (BalenaCloud).
Below I’ll walk through some high-level concepts important for working with Balena.
balenaOS
balenaOS is a Linux distribution based on Yocto. It supports a bunch of devices including many popular development boards.
Out of the Box
Out of the box it has networking, a cloud connection, remote connectivity, logging, etc. Development versions have an interactive login available via SSH or TTY. But balenaOS’ main task is to run your app’s services, which exist as Docker containers running on balenaEngine, their specialized Docker runtime.
Typically, you download a mostly blank OS image, loaded only with wifi credentials and your account information. After flashing it to a disk and booting your device, it will connect to balenaCloud and retrieve your project’s docker images to run.
Your project’s services are specified via docker-compose, providing a familiar way to express your network ports, storage volumes, environment variables, etc.
Extras and Caveats
I’d like to highlight a couple of extras and caveats:
- Balena-specific additions are expressed through docker-compose labels, used e.g. to expose certain host features to docker containers.
- Regrettably, the supported docker-compose syntax is based on v2.x, which is now a couple of versions behind. This is increasingly diverging from the reference materials and search results you’ll encounter day to day and leaves out v3.x features like health checks. It’s currently the third most-wanted item in their roadmap, so hopefully an update will come soon!
Docker-compose enables the multiple-container architecture you may be used to on the web. That means, for instance, you can grab an existing dockerized third-party component if it fits your needs. You can look over a whole host of example projects on balenaHub to get started.
The OS has minor releases most weeks, but there’s a less-frequent LTS release track (“ESR”) available with the higher-tier subscription plans.
Both the OS and your application services receive updates over the air. One of my favorite parts is that service updates are delivered as deltas — so if you optimize your Dockerfiles (as you might do to speed up cloud deployments), your updates can be very small and quite fast.
See the docs for more details on balenaOS.
balenaCloud
Devices belong to fleets, which are managed via balenaCloud. We mostly access it via the web UI and balena-cli tool, but there’s also an API.
You can view logs streaming off each service on your device, and SSH to individual services or the host OS.
Software is deployed to a fleet via balena push
that works similarly to `git ‘-based deployment on cloud hosts like Vercel. Balena will take your code, run the build, store the artifacts, and deliver them to devices.
You can configure fleets to track the latest software version or pin them on specific versions to update only when you say so. Other cloud-managed configuration includes environment variables for your apps, balena-specific configuration like update behavior, and hardware-specific configurations like HDMI timing.
Devices may inherit fleet configuration, or be overridden with device-specific values.
Impressions
My team’s project hasn’t yet launched at scale, but so far we’ve been happy with the development experience. In future posts, I plan to go deeper into how balena fits with our daily development workflow.