Docker Alpine Linux Image for ARM
Alpine Linux is a super small Linux distribution which targets Docker. The only downside is that they use musl libc instead of glibc, which causes some issues for Golang programs. But I want this as a base image for SkyDNS on my Raspberry Pi, running HypriotOS.
After reading a modest amount of documentation I found the mkimage-alpine.sh script which build a docker image ala alpine, but makes it possible to select different archs. I had to tweak this script a little to make it do what I want, but after that it worked.
--- mkimage-alpine.sh.1 2015-05-25 14:47:09.415635082 +0100
+++ mkimage-alpine.sh 2015-05-25 14:38:02.815659184 +0100
@@ -2,13 +2,8 @@
set -e
-[ $(id -u) -eq 0 ] || {
- printf >&2 '%s requires root\n' "$0"
- exit 1
-}
-
usage() {
- printf >&2 '%s: [-r release] [-m mirror] [-s]\n' "$0"
+ printf >&2 '%s: [-r release] [-m mirror] [-a armhf|x86|x86_64] [-s]\n' "$0"
exit 1
}
@@ -20,7 +15,7 @@
apkv() {
curl -s $REPO/$ARCH/APKINDEX.tar.gz | tar -Oxz |
- grep '^P:apk-tools-static$' -A1 | tail -n1 | cut -d: -f2
+ grep -a '^P:apk-tools-static$' -A1 | tail -n1 | cut -d: -f2
}
getapk() {
@@ -51,7 +46,8 @@
tar --numeric-owner -C $ROOTFS -c . | xz > rootfs.tar.xz
}
-while getopts "hr:m:s" opt; do
+ARCH=$(uname -m)
+while getopts "ha:r:m:s" opt; do
case $opt in
r)
REL=$OPTARG
@@ -62,6 +58,8 @@
s)
SAVE=1
;;
+ a) ARCH=$OPTARG
+ ;;
*)
usage
;;
@@ -72,7 +70,7 @@
MIRROR=${MIRROR:-http://nl.alpinelinux.org/alpine}
SAVE=${SAVE:-0}
REPO=$MIRROR/$REL/main
-ARCH=$(uname -m)
+ARCH=armhf
tmp
getapk
Copy this script to your Pi and run it. It
should create an image that you can use as a base image. All docker images that
I create for ARM (or non x86_64) will be postfixed with the arch. So this will
be named miek/alpine-armv6l
(uname -m
on the Pi).
Next we cross
compile
SkyDNS for my PI: GOARCH=arm GOARM=5 go build
This creates a static binary.
Note that creating a static binary for x86 requires:
go build -ldflags "-linkmode external -extldflags -static"
Then we tweak the Dockerfile
a little (a different FROM line) and create an image for the Raspberry. This all needs to
be done on the Pi itself. docker build -t miek/skydns-armv6l .
End result:
- Alpine image: https://registry.hub.docker.com/u/miek/alpine-armv6l/
- SkyDNS image: https://registry.hub.docker.com/u/miek/skydns-armv6l/
Proof:
$ docker run miek/skydns-armv6l
2015/05/25 14:23:24 skydns: falling back to default configuration, could not read from etcd: 501: All the given peers are not reachable (Tried to connect to each peer twice and failed) [0]
2015/05/25 14:23:24 skydns: ready for queries on skydns.local. for tcp://127.0.0.1:53 [rcache 0]
2015/05/25 14:23:24 skydns: ready for queries on skydns.local. for udp://127.0.0.1:53 [rcache 0]
Yes, no Etcd, because of this.