Home

Docker on Raspberry Pi

Update: If you're curious why we did this, read our reasoning for doing this. If you're looking for the short route, see our new post on getting Docker on the Pi in 4 simple steps

At Resin.io, our goal is to simplify development for the Internet of Things. One challenge we’ve faced is deploying applications to devices. It’s okay when you have just one or two devices, but once a deployment scales larger, this becomes a major issue.

In July we discovered Docker, a tool that vastly simplifies the deployment of applications across variety of environments. However Docker didn’t yet support or run on the Raspberry Pi.

We wanted to change that.

Ken Cochrane had made some progress on this. As of the 21st of October, we decided to allocate our full resources to completing the task. By the 2nd of November, we reported back to the community that we were almost there.

Today, November 10th, we’ve made a break-through: Docker is fully running on the Raspberry Pi.


Installing Docker on the Raspberry Pi

We originally performed these steps on Arch Linux x86_64 Linux 3.10.3 with an 8GB SD card. Over the next week, we'll be verifying and updating these instructions to support running them on a Mac.

Setup:

  1. export RPIDIR=$HOME/rpi
  2. mkdir -p $RPIDIR && cd $RPIDIR

Download needed files

  1. wget http://downloads.raspberrypi.org/arch/images/archlinux-hf-2013-07-22/archlinux-hf-2013-07-22.img.zip
  2. unzip archlinux-hf-2013-07-22.img.zip
  3. curl https://codeload.github.com/raspberrypi/linux/tar.gz/rpi-3.11.y | tar xz
  4. curl https://codeload.github.com/raspberrypi/tools/tar.gz/master | tar xz
  5. cd $RPIDIR/linux-rpi-3.11.y
  6. git clone git://git.code.sf.net/p/aufs/aufs3-standalone

Install Arch Linux on SD card

  1. Insert an SD card into your system
  2. sudo dd if=$RPIDIR/archlinux-hf-2013-07-22.img of=/dev/mmcblk0 bs=4m
  3. Eject the SD card

SSH Into the Raspberry Pi

Put the SD card in the Raspberry Pi, boot it and connect over SSH (root/root)

Resize the Root Partition

Follow this guide to resizing the Root Partition whilst the Raspberry Pi is running.

Update the install:

  1. pacman -Syu (answer yes to everything)
  2. pacman -S linux-raspberrypi-latest (answer yes to everything)

Create a swap file

  1. dd if=/dev/zero of=/swapfile bs=1M count=1024
  2. chmod 600 /swapfile
  3. mkswap /swapfile
  4. echo /swapfile none swap defaults 0 0 >> /etc/fstab
  5. reboot

Install a new kernel on the RPi.

Run the following on the host system

  1. Setup environment
    1. export RPIDIR=$HOME/rpi
    2. mkdir -p $RPIDIR/root/boot
    3. mkdir -p $RPIDIR/root/usr
    4. export INSTALL_MOD_PATH=$RPIDIR/root/usr
    5. export KERNEL_SRC=$RPIDIR/linux-rpi-3.11.y
    6. export CCPREFIX=$RPIDIR/tools-master/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-
    7. export CROSS_COMPILE=$CCPREFIX
    8. export ARCH=arm
  2. Patch kernel with AUFS
    1. cd $KERNEL_SRC/aufs3-standalone
    2. git checkout aufs3.11
    3. cp -rp *.patch ../
    4. cp -rp fs ../
    5. cp -rp Documentation/ ../
    6. cp -rp include/ ../
    7. cd $KERNEL_SRC
    8. patch -p1 < aufs3-kbuild.patch (ignore the error)
    9. patch -p1 < aufs3-base.patch
    10. patch -p1 < aufs3-mmap.patch
    11. patch -p1 < aufs3-loopback.patch
    12. patch -p1 < aufs3-standalone.patch
  3. Configure the kernel
    1. make mrproper
    2. ssh root@192.168.1.2 cat /proc/config.gz | gunzip > .config (replace the IP with the IP of your Pi)
    3. make oldconfig
    4. Choose yes for Aufs
    5. Press enter for all other options
  4. make menuconfig
    Choose the following options to be built-in (i.e with an asterisk):

    • Device Drivers → Character Devices → Support multiple instances of devpts
    • Device Drivers → Network Device Support → Virtual ethernet pair device
    • Device Drivers → Multiple devices driver support (RAID and LVM) → Thin provisioning target

    Press escape multiple times until prompted to save the config and choose YES

  5. Build the kernel

    1. make (Optionally pass -j $(nproc) to speed it up)
    2. make modules_install
    3. make headers_install INSTALL_HDR_PATH=$INSTALL_MOD_PATH
    4. cd $RPIDIR/tools-master/mkimage
    5. ./imagetool-uncompressed.py ${KERNEL_SRC}/arch/arm/boot/zImage
    6. cp kernel.img $RPIDIR/root/boot/.
  6. Transfer to the RPi

    1. tar cz -C $RPIDIR/root . | ssh root@192.168.1.2 tar xz -C / (Replace the IP with the IP of your Pi, ignore the error of ownership change)
    2. ssh root@192.168.1.2 reboot (Replace the IP with the IP of your Pi)

Installing dependencies:

Connect to the RPi over SSH(root/root) and run:

  1. pacman -S screen (answer Yes to all)
  2. screen bash — Start a screen session in case we disconnect
  3. pacman -S gcc lxc make patch git mercurial sqlite sudo yaourt
  4. yaourt -S debootstrap
  5. Install gnupg1
    1. yaourt -S gnupg1
    2. Edit PKGBUILD when prompted and replace arch=('i686' 'x86_64') with arch=('any')
  6. export PATH=/usr/local/go/bin:/root/go/bin:$PATH
  7. export GOPATH=/root/go:/root/go/src/github.com/dotcloud/docker/vendor
  8. curl https://go.googlecode.com/files/go1.2rc2.src.tar.gz | tar xz -C /usr/local
  9. cd /usr/local/go/src
  10. ./make.bash
  11. cd $HOME
  12. curl https://codeload.github.com/morfoh/aufs-util/tar.gz/aufs3.x-rcN | tar xz
  13. cd $HOME/aufs-util-aufs3.x-rcN
  14. sed -i 's/7/0/' ver.c
  15. make && make install

Install docker

  1. mkdir -p /root/go/src/github.com/dotcloud/docker
  2. cd /root/go/src/github.com/dotcloud/docker
  3. git clone https://github.com/dotcloud/docker.git .
  4. git checkout v0.6.4
  5. curl https://gist.github.com/petrosagg/7260553/raw/docker-arm-v0.6.4.patch | git apply -
  6. export VERSION=$(cat ./VERSION)
  7. export GITCOMMIT=$(git rev-parse --short HEAD)
  8. export LDFLAGS="-X main.GITCOMMIT $GITCOMMIT -X main.VERSION $VERSION -w -linkmode external -extldflags '-static -Wl,--unresolved-symbols=ignore-in-shared-libs'"
  9. go build -v -o /root/go/bin/docker -ldflags "$LDFLAGS" ./docker

Make the base image

  1. sysctl -w net.ipv4.ip_forward=1
  2. docker -d &
  3. cd contrib
  4. curl -s https://archive.raspbian.org/raspbian.public.key | gpg --import
  5. ./mkimage-debian.sh raspbian wheezy http://archive.raspbian.org/raspbian

Build docker 0.6.6 using docker 0.6.4

  1. cd /root/go/src/github.com/dotcloud/docker
  2. git reset --hard
  3. curl https://gist.github.com/petrosagg/7260553/raw/docker-arm-v0.6.6.patch | git apply -
  4. docker build -t docker .
  5. docker run -privileged -v `pwd`:/go/src/github.com/dotcloud/docker docker hack/make.sh binary

Hopefully the above instructions worked, and you should now be able to use Docker on your Raspberry Pi!


Updates

11/11/2013

  • Replaced step 2.11. patch -p1 < aufs3-proc_map.patch with patch -p1 < aufs3-loopback.patch
  • Changed instructions for resizing the partition sizes. Now done on the Raspberry Pi instead via GParted.
  • Ensure screen is install before we try to use it in Installing dependencies.

You can follow the discussion on Hackernews, or follow us on Twitter at @resin_io, to keep track of our progress or to ask us questions, or email us. Why not signup for an invite to our platform?

Team Resin.io

Resin.io allows you to 'git push' to your hardware devices, like you can today with servers in the data centre. We cross-compile your code in the cloud, turn it to a Docker container, and ship it!

Register
comments powered by Disqus