# Docker Alpine Linux Image for ARM


[Alpine Linux](https://www.alpinelinux.org/) is a super small Linux distribution
which targets Docker. The only downside is that they use [musl libc](http://www.musl-libc.org/)
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](http://blog.hypriot.com/).

After reading a modest amount of documentation I found the
[mkimage-alpine.sh](https://raw.githubusercontent.com/lifeeth/docker-arm/master/contrib/mkimage-alpine.sh)
script which build a docker image ala
[alpine](https://registry.hub.docker.com/_/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](/downloads/2015/mkimage-alpine.sh) 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](http://miek.nl/posts/2015/Feb/15/Setup%20Etcd%20on%20Raspberry%20Pi%20cluster/)
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](https://github.com/skynetservices/skydns/blob/alpine/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](https://github.com/coreos/etcd/issues/2308).

