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