Docker on Raspberry Pi

I recently purchased Raspberry Pi 2 modelB and I wanted to use it to try out some home IoT projects. I wanted to combine Docker with Raspberry Pi so that I can develop IoT application using Containers. There is already lot of work ongoing to get Docker working on Raspberry Pi and I learnt that it is pretty easy to use it currently. In this blog, I will cover how I setup my Raspberry Pi in headless mode and how I got Docker working in Raspberry Pi. I collected the steps from different websites and I have tried to put them together in this blog.

Model used:

We can buy Raspberry Pi base board alone or a starter kit which contains basic accessories along with the board. I bought this model from amazon which included powersupply, case, ethernet cable, hdmi cable, 8GB SD card with Noobs OS installed.

Basic setup:

I wanted to operate Pi in headless mode since I don’t have a separate monitor at home. Rather than using Noobs and then installing Raspbian OS, I preferred directly installing Raspbian OS in the SD card.

Burning Raspbian OS into SD card:

I downloaded Raspbian Jessie version from here. To burn the image into the SD card, we need SD card writer. I downloaded Win32 disk imager from here and then burnt the ISO image into SD card.

Setting up static IP address:

To access Pi from ethernet port of your laptop, it is needed to set static IP address for the Pi. For this, you need to edit “cmdline.txt” file in the base directory of SD card. This can be done after the Raspbian OS image is burnt into SD card. Following is the updated “cmdline.txt” file in my case where I have used static IP address “169.254.7.193”.

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait ip=169.254.7.193

Once we put the updated SD card in Pi, we can use Putty client to access Pi using SSH connection. SSH is turned on by default in Pi. The default username is “pi” and password is “raspberry”. I had some issues connecting through ssh directly. For some reason, I had to ping the address for few times and the SSH worked fine after that.

Expand hard disk:

Even though I used a 8GB hard disk and the default Raspbian uses close to 4GB, I could not see the 4GB free space in “df -k” output. I had to expand rootfs using the procedure here. Following are the steps:

sudo raspi-config
Select "expand_rootfs"

Following is the “df -k” output in my node after expanding rootfs.

pi@raspberrypi:~ $ df -k
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/root        7510180 3593924   3555240  51% /
devtmpfs          469748       0    469748   0% /dev
tmpfs             474052       0    474052   0% /dev/shm
tmpfs             474052    6420    467632   2% /run
tmpfs               5120       4      5116   1% /run/lock
tmpfs             474052       0    474052   0% /sys/fs/cgroup
/dev/mmcblk0p1     61384   20296     41088  34% /boot
tmpfs              94812       0     94812   0% /run/user/1000

Setting up Wireless:

To access internet from Raspberry, we can either connect Raspberry to the home router through ethernet cable or use a wireless usb adapter from Raspberry to connect to the home router. In my case, I used a wireless usb adapter. To configure wireless on Raspberry, I used the procedure here to setup wireless using CLI. At this point, Pi is totally headless and the only cable we need is the power cable.. I have also setup my home router to give a static DHCP address based on the Pi wlan mac address so that the address for Pi always remains constant.

Setting up Graphical UI:

There are multiple choices available here. 1 option is to use X-server like Xming in the Windows machine and run client like lxsession or startlxde-pi in the Pi. I preferred running vnc server in the Pi and using vncclient from Windows or Linux machine to connect to Pi. I used the procedure here to setup vnc server in Pi. Following set of commands installs the server and starts it.

sudo apt-get install tightvncserver
vncserver :1 -geometry 1920x1080 -depth 24

At this point, we can connect to Pi using any VNC viewer client. To run VNC server automatically on Pi boot, I used the procedure here to start VNC server on reboot using systemd service.

Using Docker on Pi

Hypriot has done a great job in getting Docker to easily work on Pi. One important note to keep in mind is that Pi uses ARM processor because of which regular Linux containers built on X86 will not directly work on Pi.

Docker installation

Hypriot provides two options to install Docker:

  1. Docker is pre-installed in the OS image.
  2. Docker can be installed as a Debian package on top of already existing OS.

Hypriot even have Docker Swarm and Machine images. All Docker images can be downloaded from here.

I used the Debian approach to install Docker engine 1.10.1 version. Following are the steps for installation:

curl -sSL http://downloads.hypriot.com/docker-hypriot_1.10.1-1_armhf.deb >/tmp/docker-hypriot_1.10.1-1_armhf.deb
sudo dpkg -i /tmp/docker-hypriot_1.10.1-1_armhf.deb
rm -f /tmp/docker-hypriot_1.10.1-1_armhf.deb
sudo sh -c 'usermod -aG docker $SUDO_USER'
sudo systemctl enable docker.service

Following is the Docker version running in my Pi:

pi@raspberrypi:~ $ docker version
Client:
 Version:      1.10.1
 API version:  1.22
 Go version:   go1.4.3
 Git commit:   9e83765
 Built:        Fri Feb 12 12:41:05 2016
 OS/Arch:      linux/arm

Server:
 Version:      1.10.1
 API version:  1.22
 Go version:   go1.4.3
 Git commit:   9e83765
 Built:        Fri Feb 12 12:41:05 2016
 OS/Arch:      linux/arm

Hypriot Pi Docker images are available from Docker hub.We can also search for Pi or ARM Docker images in Docker hub to find images uploaded by others.

Building Docker image and pushing to Docker hub

As of now, the only way to build Pi Docker images looks like we either need to build it in Pi itself or in any other ARM machine. Following is a sample Dockerfile that i used to build Apache container.

FROM resin/rpi-raspbian:jessie
MAINTAINER Sreenivas Makam

# Update
RUN apt-get update

# Install apache2
RUN apt-get install -y apache2

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

To build Docker image, do:

docker build -t smakam/apachepi:v1 .

Following is the “docker ps” output in my Pi showing 2 Containers running:

pi@raspberrypi:~/docker $ docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                   NAMES
37f32ecb0e3b        smakam/apachepi:v1          "/usr/sbin/apache2ctl"   12 seconds ago      Up 10 seconds       0.0.0.0:32768->80/tcp   elegant_lumiere
bd3faa301d12        hypriot/rpi-busybox-httpd   "/bin/busybox httpd -"   7 minutes ago       Up 7 minutes        0.0.0.0:80->80/tcp      boring_mcclintock

To push the Apache image into Docker hub, do:

docker push smakam/apachepi:v1

The above command assumes that you have a Docker hub account and that you have logged in from inside Pi. The above pushed image is available in Docker hub.

Summary

Integrating Docker with Pi gives a lot of possibilities. Pi is useful for building IoT projects and Docker is good at build, ship and deploy. Used together, I feel that this will encourage code reuse and make it faster to build and deploy IoT applications.Following are some areas that would need improvement:

  • Cross-platform way of building Docker images.
  • Ability to convert Docker images or Dockerfile between X86 and ARM platforms automatically.

As a next step, I will explore building IoT projects with Pi and Docker.

References

5 thoughts on “Docker on Raspberry Pi

  1. Hi, Thanks for the tut,

    I’ve been trying to get an Apache docker container running on my pi 2, I tried to build my own image and I tried to use your image, but when I run either image I presented with an error “AH00558: apache2: Could not reliably determine the server’s fully qualified domain name, using 172.17.0.2. Set the ‘ServerName’ directive globally to suppress this message”

    Any idea what’s causing this? if I enter the “docker ps” cmd it shows me the container is running in spite of the error message, but I am unable to access the server using my local ip address.

  2. hi
    that error while starting container is fine.
    Can u paste output of “docker ps” and also you are accessing the web server? Most likely, i think you are not using the host port mapping.

    1. Thanks for the quick reply, it’s my first time attempting to use docker, maybe I’ve missed something simple.

      Docker ps:
      http://pastebin.com/ynyfGq0H

      I’m trying to access the container/ server from a windows machine on the same LAN using the raspberry’s ip address (192.168.1.5) I have my ports forwarded, that’s not the problem.

      I did a scan on of my LAN and the pi (192.168.1.5) does not have port 80 open, I thought the container should have opened it?, do I need to open the port outside the container, or have I missed something else?

      1. I manged to find the “Bind container ports to the host” on Docker after reading your response, simply adding the -P option to the run command did the trick, thank you.

Leave a comment