Better be prepared for the ARMed IoT flood and port Docker apps to ARM

The great ARMed flood has begun. Especially for the sake of the IoT, every day new tiny devices pop up all around the world. And since most of these devices are build on top of the ARM architecture, with each new device, ARM gets more important compared to the x86 architecture proposed by Intel/AMD. Maybe you even need to run your next app on ARM! Thus better be prepared and port apps to ARM, it’s basically just one step to take.

In comparison to the x86 CPU architecture, ARM supports low power consumption by design, not just as a feature. When thinking of a sensor network at your home, you don’t wanna change the battery of all your sensors every week. Well, think of any device that profits from low power consumption, which does not need the CPU power of a sumo wrestler. As with sumo wrestlers, computers cluttered with resources lack the flexibility needed in today’s IT, and the resources of their built in x86 CPU often are barely needed.

Speaking of the number of devices: Some say we will have 20, some say 50 billion connected IoT devices by 2020, where most of them will be ARMed. Well, least let’s conclude: It will be a flooding number of them.

Fair enough, so let’s start making apps compatible to ARM. To do so, you only need to make sure that the binaries of your apps are compiled explicitly for the ARM architecture. Thus, porting an app to ARM basically means to change the binaries to ARM compatible ones. Let’s do it!

Get started with Docker for an easy porting example

Of course, we use Docker. And in the world of Docker, apps are described by Dockerfiles, like recipes for making cakes. Thus, when we wanna ARM an app, we only change its recipe, i.e. its Dockerfile. So make sure you know about the commands in Dockerfiles with the help of the Dockerfile reference at Docker.

From now on, let’s better refer to an app as a service because often a Dockerfile or a docker-compose file is a recipe for a collection of apps which are combined to a service. Thus a service is described by one or many apps.

In order to directly apply the necessary steps, we go through an example. In this example, we wanna port the Apache webserver to ARM.

As hardware for our example, we use a Raspberry Pi, which is one of the most popular ARM devices for developers. Of course, as operating system we use our SD Card image that provides Docker on the Raspberry Pi by just flashing it to a SD card and booting it.

Let’s ARM it!

First, search for a Dockerfile that describes the service you wanna ARM. In most cases, Dockerfiles reside on the Dockerhub or on Github.

When choosing a Dockerfile, make sure you can check the following three prerequisites:

For Apache, we found a small and popular Dockerfile here. We check the Dockerfile if the three prerequisites in the list we above are met. Here, the Dockerfile is based on Debian, it seems clean and there’s no license given that restricts the usage of this work.

Note that every now and then there are mistakes in Dockerfiles. Therefore we recommend to test the Docker images on your x86 machine before porting it. In case you encounter any errors, the performance advantage of an x86 machine makes debugging much faster than on your ARM machine. See the Docker docs to install Docker on your machine. It’s fast and painless.

Thus, we test the chosen Dockerfile for Apache on a x86 machine. The docker run command to do this is given in the repo description on the Dockerhub. In advance we had to add the tag wheezy (read the next chapter when you are curious about the wheezy here).

docker run -p 80:80 -p 443:443 -d eboraas/apache:wheezy

When the Docker command completed, point your browser to http://<IP OF YOUR PI>:80/. You should see the default page of Apache:

port_dockerfiles_to_arm

Next, let’s move to the target machine running on ARM. Copy the content of the Dockerfile as is to your ARM machine.

In our case, we log into the Raspberry Pi (get help from our getting started guide) and copy the content of the Dockerfile to the machine. For this, on the machine, we use the vim editor by executing

vim Dockerfile

Paste the content.

Then make sure that the content is formatted as it is on the website, e.g. any command should be at the beginning of a new line etc.

After formatting, this is how the Dockerfile should look like:

FROM eboraas/debian:stable
MAINTAINER Ed Boraas <[email protected]>

RUN apt-get update && apt-get -y install apache2 && apt-get clean
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2

RUN /bin/ln -sf ../sites-available/default-ssl /etc/apache2/sites-enabled/001-default-ssl
RUN /bin/ln -sf ../mods-available/ssl.conf /etc/apache2/mods-enabled/
RUN /bin/ln -sf ../mods-available/ssl.load /etc/apache2/mods-enabled/

EXPOSE 80
EXPOSE 443
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

Now we need to change all binaries that are used in this Dockerfile to ARM compatible ones. In general, there are two locations that need to be adjusted:

Finally, save the Dockerfile. Try if the Dockerfile works by creating …

docker build -t rpi-apache .

… and starting a Docker image:

docker run -p 80:80 -d rpi-apache

Now, when you point your browser to the IP address of your ARM machine, you should see the same default page of Apache’s as when you started the image on x86 before.

CONGRATULATIONS! You ARMed your first service! Now you have the basic understanding to ARM more services! In case you encounter any error, get help in the next chapter. We cross our fingers for you!

Note: After you successfully ported a service, you can push it to the Dockerhub, so that other people can use it. In addition make sure to put rpi- in front of the Docker image’s name. This declares it as a Raspberry Pi compatible image and therefore also as an ARM compatible service. It will make the life easier for people looking for ARMed services on the Dockerhub.

Debugging hints to ARM a service

Optimize the Dockerfile (optional)

Optimizing the Dockerfile does have several advantages: It often makes it smaller, i.e. you need less time to download packages and less disk space on your machine. Further, you gain a better overview over the Dockerfile’s structure which simplifies debugging. In the following, we give some recommendations of how to optimize a Dockerfile:

RUN  	apt-get update && \
	apt-get -y install apache2 && \
	apt-get clean

...

EXPOSE 80,443

Use the comments below to share your experiences. Also, join the discussions in the community channel.

We wish happy porting parties!

Mathias & Andreas

comments powered by Disqus