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:
- Docker is pre-installed in the OS image.
- 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
- Pi headless install – 1 and 2
- Raspberry official website
- Hypriot blog on getting started with Docker on Pi
- Docker on Pi blog
- Docker on Pi tutorial
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.
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.
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?
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.