How can I remotely update my IoT2040 running customized development Balena 2.12.7+rev1?

I have built the Balena 2.12.7+rev1 with some USB to Serial driver enabled for IoT2040. Now I would like to update the new built OS with some changed.

How can I done that?


Have you tried, and if not could you try, building an image of the version you want? I will try and find out what you would need to update the running device OS image (we call this a HUP, or Host UPdate) if you can confirm the image builds OK :+1:


Yes. I have successful built the customized development OS. And now that OS is running with connected to Balena Cloud.

And now I would like to upgrade it to be the production version remotely. But on the Balena dashboard, the update menu was disabled.

I have checked in the conf/local.conf that there is line
RESINHUP ?= “yes”
include in the configuration.

I will point this thread out to our OS team for comment, because I am not sure how a HUP would work with a privately build image like this.

Thank a lot.


Can you please clarify something…

Earlier in the thread you mention that you were building a custom OS with an extra USB to Serial driver. Now you have this custom OS running and connected to balenaCloud.

If you remotely upgrade it to the production version, the modifications you made i.e. extra driver/any customisation won’t persist. As the remote upgrade will be to the one that you can download from balenaCloud.

So can you please clarify?
a) Yes, I know the customisation I made to the OS will be lost. I still want to move to a production image of the IOT 2000?
b) Oh no. I want to keep my customisation and somehow get to a production style OS which disables ssh access etc.


Hi Zubairlk,

Ok. I may miss understand about production.
I want to keep my customisation and ssh access + I need the solution to upgrade the Host OS remotely.

Best regards,

Ok so the high level steps are

Step 1: Build a production image with your customisation.
Step 2: Load the OS into a docker registry where you can HostOS update from.
Step 3: Manually HostOS update your device from that docker image.

The following detail is generic for any custom OS 2.12.7 onwards. (I think 2.12.7 onwards. not exactly sure about this version).

Build a custom balenaOS

Use, modify OS, build.

The build output artefacts are in the folder build/tmp/deploy/images/

e.g. on my laptop with balena-raspberrypi

zubairlk@zubair-xps-resin:~/$ ls build/tmp/deploy/images/raspberrypi3/*resinos-img*
build/tmp/deploy/images/raspberrypi3/resin-image-raspberrypi3-20191104094606.rootfs.resinos-img  build/tmp/deploy/images/raspberrypi3/resin-image-raspberrypi3.resinos-img

The resinos-img file is the normal one you flash on the SD card for the rpi.
We need the .docker file to HUP to.

zubairlk@zubair-xps-resin:~/$ ls build/tmp/deploy/images/raspberrypi3/*docker -al
-rw-r--r-- 2 zubairlk zubairlk 203854848 Nov  4 10:20 build/tmp/deploy/images/raspberrypi3/resin-image-raspberrypi3-20191104094606.rootfs.docker
lrwxrwxrwx 2 zubairlk zubairlk        53 Nov  4 10:20 build/tmp/deploy/images/raspberrypi3/resin-image-raspberrypi3.docker -> resin-image-raspberrypi3-20191104094606.rootfs.docker

We need to load the .docker file and then push the image onto a docker registry.

Load .docker file

This loads the .docker file as an image into the currently running docker daemon on the laptop.

zubairlk@zubair-xps-resin:~/$ docker load -i build/tmp/deploy/images/raspberrypi3/resin-image-raspberrypi3.docker
Loaded image ID: sha256:57b134e17a8a0619c89cf6478ffc60c227a5aaa2a6998429a4a5d939e94024e8

warning: Don’t use docker import. Need to use docker load with this file

Tag image

Use the sha from the previous command.

docker tag 57b134e17a8a0 my-custom-rpi-x-y-z

Now we have my-custom-rpi-x-y-z. We need to push this to a registry that a device can see/hup from.

During my workflow, I usually have a docker registry running on my laptop in a container.

Run a local registry on my laptop on port 5000

docker run -d -p 5000:5000 --name registry registry:2

Push image onto local registry

zubairlk@zubair-xps-resin:~/i$ docker tag my-custom-rpi-x-y-z localhost:5000/my-custom-rpi-x-y-z
zubairlk@zubair-xps-resin:~/$ docker push localhost:5000/my-custom-rpi-x-y-z
The push refers to repository [localhost:5000/my-custom-rpi-x-y-z]
d17806a58e72: Pushed 
latest: digest: sha256:62055cdb1d9fb1443446ca9c147c7485d4ce475e678d02ad4f3093926a6fa416 size: 528

On the device

This device should be able to see the registry. In my case, it is on the same local network.

In the HostOS, edit /etc/docker/daemon.json using vi and make it look like

 "insecure-registries" : ["MY-LAPTOP-IP:MY-LAPTOP-PORT"]

Restart the balena-host daemon using systemctl restart balena-host

Now run hostapp-update

In my case, on my rpi,

hostapp-update -r -i

This whole dance might be simpler if you push your docker image to your public docker hub registry.

I don’t use that flow. I imagine it will look like

docker tag my-custom-rpi-x-y-z MY-DOCKERHUB-USER-ACCOUNT/my-custom-rpi-x-y-z
docker push MY-DOCKERHUB-USER-ACCOUNT/my-custom-rpi-x-y-z

On the device, it’ll be simpler

hostapp-update -r -i MY-DOCKERHUB-USER-ACCOUNT/my-custom-rpi-x-y-z

Hi Zubairlk,

That’s exactly what I need.
You clarify on each step very clear.
Let me try on it then come back to you with the result.

Thank you so much for your help.

Best regards,