Introduction: Build Docker Image for Raspberry Pi

This instructables show how to build a Docker Image for Raspberry Pi.

Step 1: Why Docker?

You can use Raspberry Pi (RPi) do many thing, tiny web server, AI assistant, Robotics ... etc.

Many projects you want to try, but the pain points are:

Time To Build

RPi is not keen on processing power, and the SD/USB drive limited the IO speed. Use apt install all dependency package requires an hour and building the source requires more hours. Especially for AI related projects, time to wait more than time to try.

Version Conflict

Everyone try many projects in one RPi. When you have tried a project and would like to switch to another one, you may find some build fail caused by dependency libraries version conflict with previous project. Some libraries stop developing few years ago and depend on some very old libraries. In contrast, active project depended on latest libraries. Both project cannot co-exist in the same SD/USB drive😔.

Image Backup

Since some projects cannot co-exists, simply buy more SD/USB drive to keep each project image dependent is a way. If money is not limited😅. But it increases the difficulties of file/image management, sometimes you require swap SD/USB and boot many times to find out what you want.

Hard To Share

When you built your project and would like to share the source to friends, your friends may get the build failed feed back. Distribution/libraries version too old or too new, building parameters and some tricks. You need use up the time to solve others build problems but not support the project itself.

The above pain points are my experience in this few years. Docker can help most of it.

Docker start build from selecting a prebuilt parent image. E.g. debian:jessie-slim start from an old stable Debian light weight distribution; node:10-buster-slim start from Debian light weight distribution with Node.js 10 installed. The prebuilt image can save much time to flash image, get update and install depended libraries. Each project can start from different OS version, runtime version and libraries version. When you finished develop your own project, you can push the Docker image to docker hub and share to everyone. You can keep all project data at the same SD/USB (data should routine backup to other media). For saving local storage, you can even cleanup the Docker image when not use, anytime you can pull from Docker hub again.

Step 2: Docker Overhead

Docker added one virtualize layer, overhead is an concern. I have not test too much about the Docker overhead. Most Googled result claim very low overhead and I found this document about some related research:

https://domino.research.ibm.com/library/cyberdig.n...

Step 3: Install Docker

Step 4: Building Docker Image

Please find the official guide on building docker image:

https://docs.docker.com/get-started/part2/

I have 2 projects using Docker, you may find the Dockerfile as a reference:

  • BanateCAD requires Lua runtime and some addition Lua libraries. Only Lua 5.1 can compatible to all required Lua libraries but it is the product of 2006. The latest Debian distribution that can build Lua 5.1 success is Jessie (The version before current Debian old stable). So I built a Lua 5.1 environment Docker Image to run it.

https://github.com/moononournation/BanateCAD/tree/...

  • OpenCV is an actively developing project, the source code depends latest libraries and compiler. So it very high chance to build failed, libraries method signature, compiler version, dependency conflict... I would like to use opencv4nodejs to make a simple app and do not required latest features. So when I found a way to build opencv4nodejs success, I would like to freeze it to a Docker Image and do my actual application coding.

https://github.com/moononournation/face-aware-phot...

Step 5: Development Build Speed Vs Image Size

You may found my face-aware-photo-osd project have 2 versions of Dockfile:

https://github.com/moononournation/face-aware-phot...

While development, I like split RUN command as small as possible and arrange most likely to change RUN command to last step. So for every build for development change, I can utilize previous built layer as much as possible and save much build speed.

In contrast, I will combine all RUN commands in one before release. lesser layer can much reduce the Docker Image size. My face-aware-photo-osd project as example it can reduce more than 100 MB in size.

Step 6: Multi Arch Images

As mentioned before, RPi is not a keen on processing power. Use RPi build Docker image may not a good choice, especially when your only RPi is running another projects.

Use an x86 computer also can help you build the Docker Image, please find more details here:

https://www.docker.com/blog/multi-arch-images/

simple 2 commands can build x86 and ARM Docker Image in parallel:

docker buildx create --use

docker buildx build --platform linux/amd64,linux/arm -t moononournation/debian-imagemagick-lua-meshlab:1.0.1 --push .

Multi Arch can build multi platform image with same Docker image tag, so your project can run in different machine seamlessly. e.g.

docker run -it moononournation/debian-imagemagick-lua-meshlab:1.0.1

No matter you run the above command on RPi or your x86 computer, you can get a Lua runtime environment.

Step 7: Happy RPi!

You can now develop and share your RPi project more easily!