Docker & Raspberry Pi, perfect combo!

Introduction

We all know how wonderful piece of hardware the Raspberry Pi is, can do many things, just to mention three cool projects: Multimedia Center, Meteorological Station and Retro Game Console. In this Awesome List you could get a collection of tools, projects, images and resources related to Raspberry universe.

I like to be at the technological forefront, it means I’m always testing services to satisfy some particular interest. Raspberry Pi has become my faithful companion of these hobbies, however many times I have given up to try out a new service because of the anxiety of going through the process of starting from scratch a new service setup and to add unnecessary extra load on my Pi.

Recently, I had the chance to use and setup Laradock, a Docker development environment and this project was a radical change for me in how to tackle development environments. I had already heard about Docker and I always believed that Docker was just a VM manager (what a n00b!), but after using it and reading a lot about it I understood what it really is, a platform that simplify the process of building, shipping, running and sharing applications in different environments and in that moment I’d realized Docker and Raspberry Pi can give me all the confidence to use and build services quickly and efficiently without reinstalling again and again the Raspberry OS.

Mind = Blown

Prerequisites

Through this article I want to describe my procedure to setup Docker Engine using a Debian headless server on a Raspberry Pi. With this setup, you will manage to build and execute as many docker containers as a Raspberry PI can withstand (i.e. VPN server, TOR router, Load Balancer, Apache or Nginx Server, NAS server, etc.). As you realized, a docker container is an isolated and secured server instance running as a virtual OS inside Docker Engine and sharing resources with the host OS.

To complete this guide you will need:

  • Raspberry Pi (dah!).
  • MicroSD card and adapter.
  • Ethernet connection.
  • Linux box to complete following steps.

Raspbian Installation

There are several operating system variants for Raspberry Pi. I’m going to use the latest Raspbian Jessie Lite image, a headless and minimal image based on Debian 8.

Identify your device id

Find device where your SD card is located in your linux box. Use lsblk command and search disk with the size of your SD card. In my case, my device is /dev/mmcblk0.

1
2
3
4
5
6
7
8
9
10
11
12
➜  ~ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 232.9G 0 disk
├─sda1 8:1 0 16M 0 part
├─sda2 8:2 0 256M 0 part /boot
└─sda3 8:3 0 232.6G 0 part
└─crypt 254:0 0 232.6G 0 crypt
├─lvm-swap 254:1 0 8G 0 lvm [SWAP]
└─lvm-root 254:2 0 224.6G 0 lvm /
sr0 11:0 1 1024M 0 rom
mmcblk0 179:0 0 14.9G 0 disk
└─mmcblk0p1 179:1 0 14.9G 0 part /run/media/kafebob/3730-3031

Get latest version of Raspbian Lite

1
wget -O raspbian_lite.zip https://downloads.raspberrypi.org/raspbian_lite_latest

Copy image to SD card

Format the partition of your SD card, which I don’t think you need to do, but I thought it would be good to remind myself of the mkfs command.

1
2
sudo umount /dev/mmcblk0p1 && \
sudo mkfs.vfat -n RaspbianFAT /dev/mmcblk0p1

Unzip raspbian_lite.zip and copy the image in your SD card. If you use dd make sure that you are not using the first partition on de SD card, use of=/dev/mmcblk0 and not of=/dev/mmcblk0p1.

1
unzip -p raspbian_lite.zip | sudo dd of=/dev/mmcblk0 bs=4M status=progress && sync

Enable SSH

For Jessie Lite, SSH is disabled by default. You must enabled it by placing a file named ssh, without any extension, onto the boot partition of the SD card. When the Pi boots, it looks for the ssh file.

You can execute following script to auto create the ssh file onto the boot partition of the SD card.

1
2
3
4
5
sudo sh -c "mkdir /tmp/raspbian && \
mount /dev/mmcblk0p1 /tmp/raspbian && \
touch /tmp/raspbian/ssh && \
umount /dev/mmcblk0p1 && \
rm -rf /tmp/raspbian"

You could also mount the SD card using your linux box and manually create the file in boot partition.

First time boot

It’s time to boot your rpi, plug the SD card in your Pi and turn it on. All raspberry devices MAC addresses in the world starts with B8:27:EB, if your pi is connected to the network you can easily find it with a nmap command sorcery. Replace 192.168.1 with the according segment of your internal network.

1
2
3
➜  ~ sudo nmap -T5 -n -p 22 --open 192.168.1.0/24 |  awk '/^Nmap/{ip=$NF}/B8:27:EB/{print ip}'
192.168.1.4
192.168.1.135

In my case I got two IP addresses, 192.168.1.4 is a Pi running a NAS server and 192.168.1.135 is the one recently created.

That’s it! You can now connect through SSH ssh pi@192.168.1.135 and configure your Pi via sudo raspi-config. (The default user is pi and default password is raspberry)

Docker installation

Docker setup

Since 2016, Docker provides official support for the ARM architecture. To install Docker Engine, logon to your Pi and just type:

1
curl -sSL https://get.docker.com | sh

If everything goes well, you should be able to check Docker version in console.

1
2
pi@192.168.1.135:~ $ sudo docker --version
Docker version 17.05.0-ce-rc3, build 90d35ab

Docker Compose setup

After some time using Docker, one of the first tools you will need from Docker universe is docker-compose, So it is better to have it installed now. Just type:

1
2
sudo apt-get -y install python-pip && \
sudo pip install docker-compose

If everything goes well, you should be able to check Docker Compose version in console.

1
2
pi@192.168.1.135:~ $ sudo docker-compose --version
docker-compose version 1.14.0, build c7bdf9e

With docker-compose you should be able to manage multiple containers as one single project application. From development point of view, this is one of the features I love, it has a similar purpose as package.json manage your nodejs and module project dependencies, with docker-compose you are able to define your multi-container dependencies in docker-compose.yml file in order to build and run a particular environment.

And from here, my friend, you can start to create, pull, run, stop, delete containers as if there were no tomorrow.

Container Example: Alltube

As a quick example, let’s try a service that I love, AllTube, is a video download service and could be used to save music sessions from Youtube in mp3 format, I usually use it to have my gym workout sessions on my mobile. To create and run a container with AllTube in your Pi-Docker engine just ssh to your pi and type:

1
sudo docker run -d -p 80:80 --name alltube kafebob/rpi-alltube

That’s it, after Docker finished container setup you will be able to access this service at http://yourRPIaddress (in my case is http://192.168.1.135)

If you want to stop this service just type sudo docker stop alltube or if you want to start it again sudo docker start alltube. Your OS host will never be affected with any dependency from AllTube.

Let me know in comments, what do you think? Do you want me to write about a particular service running on a Docker-Pi?

Happy coding!