I found myself wanting to use Docker on my Raspberry Pi, but of course, didn't know what I didn't know.
Installing Docker was straightforward as always, but then building or running an image forced me to understand a major distinction of the Pi as a platform.
So I had Docker installed on my Pi and went to use one of my custom Dockerfiles. The problem first manifested itself as this less-than-specific error:
standard_init_linux.go:178: exec user process caused "exec format error"
This blog post was the one that explained it in a way that I got it.
The fundamental chip architecture of the Pi is different than the processors generally used in PCs or servers. ( I'll admit that when it gets down to the nitty-gritty CS stuff like chip architecture, all I really understand is that they're not cross-compatible. ) This rocked my Docker boat a little bit, as it seemed to me to violate the "build once, deploy anywhere" promise. I learned that it's more like, "build anywhere, deploy on any host with the correct architecture".
To learn the specific chip you're working with, you can run the following command on your Pi to see the output:
$> uname -a
Linux pi3 4.14.98-v7+ #1200 SMP Tue Feb 12 20:27:48 GMT 2019 armv7l GNU/Linux
( Otherwise, refer to this full overview of Pi models and their details. )
The relevant bit is 'armv7', or really just that it is an ARM architecture. This is opposed to AMD or x86/x64. Again, I'll admit that I spend a very small amount of my time thinking about these distinctions. While obviously very important, in this case I'm only looking for the path forward that will allow me to move on building shit. ( This is actually most of the time )
Finding Compatible Docker Images
So it became clear that I was going to have to re-work some of my Docker images using different ( arm32v7 compatible ) base images. Once I started poking around Docker Hub there is actually a lot of stuff available. Check out the official ARM32v7 account and the Hypriot collection of images.
For example, any of my node-based stuff can use: https://hub.docker.com/r/arm32v7/node/
How I should handle multi-architecture projects
If I were really organized I would separate the architecture-specific parts of the project ( all the Docker images and their runtime configuration ) from the architecture-agnostic parts like the application code. There is probably even a fancy term for this. Maybe I'll explore this in a future post?
Learning about setting up applications using microservices and Docker has broadened my skills as a developer, often in directions that I wouldn't have explored.