Sunday 14 February 2021

Multi-arch Docker Container Builds - Part 2

 And so I found problems.......

On my PC I also run Wine and it has some major issues with the binfmt loader

Every time the buildx.service is started it messes up wine and it wont run.


Easy solution, just change the "--install all" to be a list of emulators that you actually want :)

For me it becomes "--install arm,arm64"


Easy as

Saturday 13 February 2021

Need a version control of IoT sensors, embedded docker containers

For a while now I have been building sensor software that runs on both Raspberry PI and embedded IoT platforms but I have a problem with deployment of versions.

For the embedded sensors I just just check every run for a new version and install but the problem is that it is an expensive operation as it take a few seconds for each run...

On the pi its a fully manual task that is either copying code or updating a container.

I want better :)


After looking at some of the code for Tasmota I think I found the start of how this will work.

Tasmota uses MQTT to send a subject to the device to inform it to update. This subject has the version number in it and if the current version is less the topic then it will update

I can make the PI also look at this topic for updates too.


Once I have the MQTT topic format sorted ( it will be similar to Tasmota ) then I will work on the PI to make it update a local binary file package, then make a docker controller to do the same in docker. Finally I will make a web site that allows for individual control of packages ( web, api and DB schema )

Multi-arch Docker Container Builds

 Recently I had the need to create some containers to run on both x64 and arm (Raspberry PI). 

I tried for a long time to build each on their respective platforms and the do individual pushes to the repositories ( dockerhub in this case )


But it all failed... why?


I found out that when you do a push for test/foo:6, it will just overwrite the manifest data on dockerhub :(

So if I pushed the arm version last I would no longer have access to the x64 container manifest and therefor I would be unable to run the container......


The solution is Buildkit and 'docker buildx' command

Install was simple enough, just follow the readme @ https://github.com/docker/buildx


There is however one little "gotcha"

whilst following the doco you find the following

docker run --privileged --rm tonistiigi/binfmt --install all

and a few steps after on building. Whats not there is anything to tell you that you need this each time you reboot as the registration of the binfmt into your kernel is reset on boot...


Once this was found it was just a simple little systemd script to run on boot and all was good

To fix, first create this service file in /usr/lib/systemd/system/buildx.service


[Unit]
Description=Docker Application Container Engine - buildx
Documentation=https://github.com/docker/buildx
After=docker.service containerd.service
Wants=docker.service
Requires=docker.socket containerd.service

[Service]
ExecStart=/usr/bin/docker run --privileged --rm tonistiigi/binfmt --install all

StartLimitBurst=3

StartLimitInterval=60s

LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity

TasksMax=infinity

Delegate=yes

KillMode=process
OOMScoreAdjust=-500

[Install]
WantedBy=multi-user.target

So what is this doing, once activated by systemd it will run once and exit on boot after docker has started. At this point it will register every device driver available to qemu that is already installed in the system.

If you wish to install a new architecture for building then just register it by installing the appropriate qemy-system-[driver] package