31 March 2022 / Last updated: 31 Mar 2022

Improving our device image management workflow with the balenaHub Container Registry

Good news everyone! As we very recently hinted, we have been working hard on giving users a complete image management workflow for blocks, including image release management and image references that consumers can use directly in their docker-compose files.
Introducing the balenaHub Container Registry

What’s a block again?

In a nutshell, they’re a container you can drop into your fleet to provide functionality to handle common tasks related to edge and IoT applications.
Blocks have been around for a while now at balena, and we've written about what they are and how to make your own in previous posts.
Our go-to example is always the browser block which provides a Chromium browser on any connected display and automatically displays any HTTP output also running on the device. For example, a developer creating a Point-Of-Sale system can focus on their payment application, and let the browser block take care of putting it on the screen.
You can find lots of other blocks on balenaHub.

Introducing the balenaHub Container Registry

What we wanted was to remove the friction of creating, managing and sharing blocks. We knew that manually building and pushing to Docker Hub while also pushing to balenaCloud was an additional burden that would slow down block development and possibly prevent developers from making blocks public. We also knew that having two places to push a block introduced the possibility of things getting out of sync, which imposed a further burden to the developer.
Starting this week, any block published to balenaHub is available to download directly as a container image, no additional registry pushes required! This also applies to any existing blocks as long as they have Visibility set to On and a Repository URL set in the block Settings dashboard.
View blocks settings in balenaCloud
The image reference format may be slightly different than what you are used to, so allow me to take you through some examples.
The expected format is bh.cr/<slug>/<commit or version> where:
  • <slug> is the block Slug which has the format <organization_handle>/<block_name> as shown in the Summary pane of the balenaCloud dashboard
  • <commit or version> is optional and is the release as shown in the Releases pane of the balenaCloud dashboard
Blocks created and maintained by balena are usually under the bh.cr/balenablocks org, but yours will match your organization name.

Find information about a block on its balenaHub page

Check out blocks pages on balenaHub
With this release, we’re happy to announce block pages on balenaHub. Now you can get more information about blocks, links to source code, and more.

Examples

Using the block Slug as shown in the Summary page would result in the latest version of the block being pulled. If the release track is not tracking latest, it will instead refer to the pinned release.
Information about a given balena block
services:
    hostname:
        image: bh.cr/g_tomas_migone1/hostname
There may be situations where you want to pull a specific release of a block, and not the latest. While this could be accomplished by changing the release track in the balenaCloud dashboard, it can also be done in the docker-compose file where the block is used, by including either the commit hash or the release version in the image path.
Here’s how to pull a specific release version given several available releases in the dashboard.
Check out blocks pages on balenaHub
services:
    hostname:
        image: bh.cr/g_tomas_migone1/hostname/3.5.0
Note that specifying a revision via +rev_ is not supported in image URLs as the plus sign is considered a special character. Instead, we will default to pulling the latest revision when a release version is provided.
So if there are multiple revisions of a release, for example 3.5.0, 3.5.0+rev1, and 3.5.0+rev2, specifying 3.5.0 in the image URL will result in 3.5.0+rev2 being pulled.
During development you may want to pull a draft release for testing. Since draft releases are not included in the latest release track, you must specify the whole version string including the build stamp.
service:
    hostname:
        image: bh.cr/g_tomas_migone1/hostname/3.6.0-1640898570135
You can also refer to a release by its build commit by copying the commit hash from the first column of the releases dashboard.
service:
    hostname:
        image: bh.cr/g_tomas_migone1/hostname/490a6b48a457bcb49d558fc1b82cfed5
Additional examples can be found in our documentation.

What’s next?

Next we are working on multi-architecture blocks to enable publishing of images that can be applied to both ARM and Intel devices with the same release. The current implementation can support multiple device types, but is still limited to compatible architectures. This is a clear source of developer friction that we are working to resolve.
In the meantime, here’s how you can support multiple architectures with your block!
Start by pushing a release to separate blocks in balenaCloud, one per architecture, like we’ve done with the Browser block.
Check out blocks pages on balenaHub
It doesn’t matter which device type you select for each block, as long as it matches the architecture you have targeted. The list of device types and their architectures can be found here.
Once each block has at least one release available, use our existing Dockerfile templates instead of a direct link in your docker-compose file where the Block will be used.
For example, if you are developing a Fleet that uses the Browser block, instead of using bh.cr/balenablocks/browser in your docker-compose file which only supports one architecture, you could create a Dockerfile.template that uses the %%BALENA_ARCH%% variable in the FROM target.
# ./docker-compose.yml
services:
    browser:
        build: ./browser
Note that the docker-compose file has been changed from image: to build: so we can reference the block image path in the template.
# ./browser/Dockerfile.template
FROM bh.cr/balenablocks/browser-%%BALENA_ARCH%%
By directing your docker-compose file to build this template, it will ensure the correct architecture variant of the block is pulled at build time.

Testing and feedback are welcome

Add blocks, use the container registry, build interesting projects, and let us know all about it. Comment away below, or get in touch on the balenaForums.
by Kyle HardingProduct Builder at balena