2016. május 25., szerda

Docker on Debian Linux 32-bit PC architecture

Docker recently has got a large hype due to its simplicity and lightweight nature. It's especially useful for developers to try out software builds in an isolated namespace without messing with the base system libraries and dependencies. I was a bit frustrated when I wanted to look into Docker, as it did not work for me after following the Docker Quickstart docs, though it is quite straightforward. Downloading a.k.a 'pulling' the default Docker image for Debian Jessie from Docker hub results in:

[qmi@qmitoshiba:~]$ docker pull debian:jessie
jessie: Pulling from library/debian
e41045043712: Pull complete
ce58426c830c: Pull complete
Digest: sha256:3dc34c5b6d35644b1c1af8cc3e0665022611e78999d7269c460afc5a0678ac45
Status: Downloaded newer image for debian:jessie

So far so good. But when I tried running it, it failed with the known exec format error:

[qmi@qmitoshiba:~]$ docker run -i -t debian:jessie /bin/bash
exec format error
Error response from daemon: Cannot start container f14f9b8ddc08f8f5722d28c39b36ef69e15ec98f6bf5a9582237cf938398e043: [8] System error: exec format error

This error message did not look good at first. Then I recalled from my past that this must be something to do with my laptop's architecture. I am having my Debian running on a 32-bit Toshiba laptop, which otherwise works fine. I can run Debian Sid perfectly well, including the Docker daemon and the docker client tool. The following command clearly shows the ELF binary header being my OS on my laptop is a 32-bit platform:

qmi@qmitoshiba:~]$ file /usr/bin/docker
/usr/bin/docker: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=fefa6e269130abb71db94873811c37e86c14c066, not stripped

Ooops...then looking into the pulled Docker image closely, it turns out that it was built for amd64 architecture:

[qmi@qmitoshiba:~]$ docker inspect debian:jessie | grep -A1 "Architecture"
    "Architecture": "amd64",
    "Os": "linux",

Unfortunately, the Docker Quickstart docs (mentioned above) does not state it clearly that the standard images were built for 64-bit platforms and that is how they were published to the registry. This leaves the 32-bit users in a dire need reaching out for help :-/ . I knew for sure that this could be fixed, so I did my own research. I found this blog a great help, so I can just extend what I found there. Kudos to J M Keyes! Credits go to him. Let's prepare our own bootstrapped Jessie core image as follows:

$ mkdir rootfs
$ sudo debootstrap jessie rootfs/

This takes a while but we will get a basic Debian Jessie file system image. Let's compress it into a tar+gzipped image, mine becomes a mere 137Mb size tarball after it's compressed. Make sure you compress it by cd-ing into the directory first, you will need the root directory in the top-level in the tarball image. Suppose you have the bootstrapped image in the directory called roofs in the current active directory, you can use the following command to compress it quickly:

$ sudo tar -czf rootfs.tgz -C rootfs .

Then you will have the rootfs.tgz containing the compressed file system image. Now, let's build our Docker image. Prepare a file named Dockerfile in the current directory with the following content:

FROM scratch
MAINTAINER Miklos Quartus
LABEL "deployer"="qmi"
ADD rootfs.tgz /

The above will tell Docker how to build a brand new image instead of downloading it from the public Docker registry. Of course, you can replace the MAINTAINER information. The LABEL is optional, but it helps later to administer and keep track of the running container. The last line, 'ADD rootfs.tgz' will tell Docker to add the compressed tarball content to the newly built Docker image as a base file system. Now, we are ready to build our first image! It's so simple. Do the following (you don't have to be root):

[qmi@qmitoshiba:~/docker/test]$ docker build -t jessietest .
Sending build context to Docker daemon 143.2 MB
Step 0 : FROM scratch
Step 1 : MAINTAINER Miklos Quartus

 ---> Using cache
 ---> f24ad889833e
Step 2 : LABEL "deployer" "qmi"
 ---> Using cache
 ---> f3ed82889f5b
Step 3 : ADD rootfs.tgz /
 ---> Using cache
 ---> 4d9bbfdae567
Successfully built 4d9bbfdae567

Awesome! It looks like we have just built our first Docker image successfully. You can check it with the command docker images, you'd like. I assume you have the docker application container engine service up and running on your machine (you should have the 'active (running)' state if you run  systemctl status docker.service command), let us try to run our newly build image in our Docker ecosystem. You need to know that every container needs to have an underlying image. So, when we will run our container, we create it and start it in one go. Refer to more explanation for page 62 in the book titled 'Docker Up and Running' :-)

OK, so let's run our container built based on the compressed file system image. We will be requesting a simple shell.

[qmi@qmitoshiba:~/docker/test]$ docker run -i -t jessietest /bin/bash

Voila! There you go! :) We're inside our container running a Bash shell. The container ID is 4cd2f95cbe4a, as the shell prompt shows. The impossible first now became possible after investing in a little bit of effort. I am no longer hurdled by the 64-bit published images in the registry. I have built my own and it works perfectly well. BTW, you can check our container status by running a docker ps command in another terminal.

root@qmitoshiba:~# docker ps -q


Done. We have managed to build our own Docker image for 32-bit platform on Debian. If you have any questions, comments or suggestions, please comment here or send me an email at inbox@miklos.info .

Nincsenek megjegyzések: