Cross compile Ethereum for Docker and ARM
Supply-chain attacks are quite popular these days, as the Solarwind hack demonstrated. My advise is don’t trust blindly containers, and run sanity checks on your build environment!
Geth, the official implementation of Ethereum protocol written in Go, can be cross-compiled for different CPU architecture including ARM.
At the time of writing, the official docker image of geth is not build for ARM architecture, only linux/amd64.
We will explain here how to build your own flavour of geth container from the sources for different platforms.
Docker multi-platform to the rescue
The first part is to find a coss-compilation toolchain that can perform this task nice and sound.
Luckily, Docker is multi-platform
for quite some time now, and a buildx
command ease the process to build for multiple platform
at once!
Let’s create a cross platform compilation stack, and them try to build Geth!
First thing first, see what is the current state of the buildx
setup
$ docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS
default * docker
default default running
If your output look like this, it’s ok, you have a default builder and nothing else. Let’s create one capable of cross-compiling
$ docker buildx create --use --name xplatformbuilder
And bootstrap the environment
$ docker buildx inspect --bootstrap
Great, that’s it, that was not more complicated than that.
$ docker buildx ls
Now, after a proper checkout of the Geth sources, let’s build them for multiple achitecture:
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t ethereum/go-client:latest .
The previous command will take some time, but didn’t produce much useful result. We’ll need
to push the containers to a container registry to be able to pull from multiple targets.
Setting up a docker registry is beyond the scope of this article, but assuming you have one,
you could tag the build accordingly and --push
the image:
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t my.docker.registry/ethereum/go-client:latest --push .
Now you can pull your freshly built Geth container from multiple targets:
Raspberry Pi 4
$ uname -m
aarch64
$ docker pull my.docker.registry/ethereum/go-client:latest
Odroid XC4
$ uname -m
armv7lv
$ docker pull my.docker.registry/ethereum/go-client:latest
Amd Epyc or Intel Xeon
$ uname -m
x86_64
$ docker pull my.docker.registry/ethereum/go-client:latest
And so on…
Enjoy running containerized Geth on ARM!
> admin.nodeInfo.name
"Geth/v1.9.25-stable-e7872729/linux-arm64/go1.15.7"
Side note, since this is now