Fix/Workaround - libseccomp2 and Alpine 3.13 - Installing Raspbian Docker 19.04+ on Raspberry Pi 4 Buster
If you're reading this you're probably dealing with the hell I've just been through trying to get apps like Nextcloud, Redis and all sorts of other things in Docker to run on a Raspberry Pi4, which suddenly seemed to stop working overnight. The reason? These apps all use Alpine Linux as a common base image. However, Alpine made a move that caused some chaos for us. Their Alpine 3.13 variant is not compatible with Raspberry Pi 4 devices IF:
- You are running a version of Docker prior to 19.04 (which is currently the case for stock Raspbian Repositories which has version 18 as the latest.
- You are running an outdated libseccomp2 library.
Either one of, or both of these criteria will land you with incompatibilities and containers randomly crashing and refusing to start left/right/centre. The specifics for this issue are detailed (quite well to be fair) over at Alpine Linux's site - https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.13.0#time64_requirements
There are a few ways you can fix this issue, but all of them were hacky and janky in ways that didn't appeal to me - notably, reducing the enforcement capabilities of Docker by adjusting the seccomp profile. Alternatively you could try downgrading container versions (e.g. Nextcloud 21 back down to 20). The problem is that can lead to database versions detecting them as incompatible. Etc. etc.
So, the solution I've come up with is two-fold. Update libseccomp2 to the 'latest' version and run ahead of Raspbian Mainline. Then do the same for their version of Docker. See below, I'm running Docker 20.10 on Kernel 5.10 just fine. Confusingly, libseccomp2 is in Buster BACKports, but that version is AHEAD of Raspbian Mainline.
The steps for libseccomp2 are well documented, as this has been a problem on multiple platforms (not just RPI4). You could do a 'oneshot' installation of a newer version, which can be found here https://github.com/itzg/docker-minecraft-server/issues/755#issuecomment-781615497
Personally I feel the better method is to install it from the Buster Backports repo, which is very safe to add. It also means any future updates to libseccomp will be applied to the Pi.
# Get signing keys to verify the new packages, otherwise they will not install
rpi ~$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC 648ACFD622F3D138
# Add the Buster backport repository to apt sources.list
rpi ~$ echo 'deb http://httpredir.debian.org/debian buster-backports main contrib non-free' | sudo tee -a /etc/apt/sources.list.d/debian-backports.list
rpi ~$ sudo apt update
rpi ~$ sudo apt install libseccomp2 -t buster-backports
The solution for Docker is something I came up with to skip ahead Raspbian Mainline's slow update cycle. We step forward and use Debian Bullseye unstable repositories, and pinch their lovely Docker Engine binaries which they've got cached upstream for the Beta Testers. Note their confusing names again: Buster is the current version of Debian, with Bullseye being the next iteration 'upstream'. Why choose two names beginning with B...?
Here's how to do it...
First, we add Debian Bullseye as a repository which Raspbian can poll for software updates. We do this by creating the file /etc/apt/sources.list.d/bullseye-testing-docker.list and filling it with the contents below:
deb http://mirrordirector.raspbian.org/raspbian/ bullseye main
Then you ALSO NEED to put an Apt Preferences file into place, so that this new repository does not totally "override" the normal Raspbian Buster one. Do not run apt-get upgrade just yet, or you'll magically transform your Pi into a Debian ARM build.
Create the Apt Preferences file /etc/apt/preferences.d/bullseye-docker.pref and populate it:
Package: *
Pin: release n=bullseye
Pin-Priority: 50
This file's meaning translates to 'Any packages found in this repository, set their priority to be lower than the default Raspbian Buster ones' (which have a priority of 500).
Now, we install Docker.io from Bullseye Upstream. Make sure to stop Docker first to avoid any potential nastiness (systemctl stop docker).
apt install docker.io/bullseye
Voila! You have Docker 20+, and an up to date LibSecComp. Restart the Docker Daemon and have fun.
You may be thinking - why not just install Docker from their website with the awful curl/bash script? This is because the script overwrites any custom config you have for Docker set up, and I have a lot. This was the most viable method for me in the end.