Deprecated: We've since released balena.io as a full service allowing you to easily run and update docker containers on multiple architectures. See https://balena.io/ for more details.
At
balena.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:
export RPIDIR=$HOME/rpi
mkdir -p $RPIDIR && cd $RPIDIR
Download needed files
wget https://downloads.raspberrypi.org/arch/images/archlinux-hf-2013-07-22/archlinux-hf-2013-07-22.img.zip
unzip archlinux-hf-2013-07-22.img.zip
curl https://codeload.github.com/raspberrypi/linux/tar.gz/rpi-3.11.y | tar xz
curl https://codeload.github.com/raspberrypi/tools/tar.gz/master | tar xz
cd $RPIDIR/linux-rpi-3.11.y
git clone git://git.code.sf.net/p/aufs/aufs3-standalone
Install Arch Linux on SD card
- Insert an SD card into your system
sudo dd if=$RPIDIR/archlinux-hf-2013-07-22.img of=/dev/mmcblk0 bs=4m
- 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
Update the install:
pacman -Syu
pacman -S linux-raspberrypi-latest
Create a swap file
dd if=/dev/zero of=/swapfile bs=1M count=1024
chmod 600 /swapfile
mkswap /swapfile
echo /swapfile none swap defaults 0 0 >> /etc/fstab
reboot
Install a new kernel on the RPi.
Run the following on the host system
- Setup environment
export RPIDIR=$HOME/rpi
mkdir -p $RPIDIR/root/boot
mkdir -p $RPIDIR/root/usr
export INSTALL_MOD_PATH=$RPIDIR/root/usr
export KERNEL_SRC=$RPIDIR/linux-rpi-3.11.y
export CCPREFIX=$RPIDIR/tools-master/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-
export CROSS_COMPILE=$CCPREFIX
export ARCH=arm
- Patch kernel with AUFS
cd $KERNEL_SRC/aufs3-standalone
git checkout aufs3.11
cp -rp *.patch ../
cp -rp fs ../
cp -rp Documentation/ ../
cp -rp include/ ../
cd $KERNEL_SRC
patch -p1 < aufs3-kbuild.patch
(ignore the error)
patch -p1 < aufs3-base.patch
patch -p1 < aufs3-mmap.patch
patch -p1 < aufs3-loopback.patch
patch -p1 < aufs3-standalone.patch
- Configure the kernel
make mrproper
ssh root@192.168.1.2 cat /proc/config.gz | gunzip > .config
(replace the IP with the IP of your Pi)
make oldconfig
- Choose yes for Aufs
- Press enter for all other options
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
- Build the kernel
make
(Optionally pass -j $(nproc)
to speed it up)
make modules_install
make headers_install INSTALL_HDR_PATH=$INSTALL_MOD_PATH
cd $RPIDIR/tools-master/mkimage
./imagetool-uncompressed.py ${KERNEL_SRC}/arch/arm/boot/zImage
cp kernel.img $RPIDIR/root/boot/.
- Transfer to the RPi
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)
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:
pacman -S screen
(answer Yes to all)
screen bash
— Start a screen session in case we disconnect
pacman -S gcc lxc make patch git mercurial sqlite sudo yaourt
yaourt -S debootstrap
- Install gnupg1
yaourt -S gnupg1
- Edit PKGBUILD when prompted and replace
arch=('i686' 'x86_64')
with arch=('any')
export PATH=/usr/local/go/bin:/root/go/bin:$PATH
export GOPATH=/root/go:/root/go/src/github.com/dotcloud/docker/vendor
curl https://go.googlecode.com/files/go1.2rc2.src.tar.gz | tar xz -C /usr/local
cd /usr/local/go/src
./make.bash
cd $HOME
curl https://codeload.github.com/morfoh/aufs-util/tar.gz/aufs3.x-rcN | tar xz
cd $HOME/aufs-util-aufs3.x-rcN
sed -i 's/7/0/' ver.c
make && make install
Install docker
mkdir -p /root/go/src/github.com/dotcloud/docker
cd /root/go/src/github.com/dotcloud/docker
git clone https://github.com/dotcloud/docker.git .
git checkout v0.6.4
curl https://gist.github.com/petrosagg/7260553/raw/docker-arm-v0.6.4.patch | git apply -
export VERSION=$(cat ./VERSION)
export GITCOMMIT=$(git rev-parse --short HEAD)
export LDFLAGS="-X main.GITCOMMIT $GITCOMMIT -X main.VERSION $VERSION -w -linkmode external -extldflags '-static -Wl,--unresolved-symbols=ignore-in-shared-libs'"
go build -v -o /root/go/bin/docker -ldflags "$LDFLAGS" ./docker
Make the base image
sysctl -w net.ipv4.ip_forward=1
docker -d &
cd contrib
curl -s https://archive.raspbian.org/raspbian.public.key | gpg --import
./mkimage-debian.sh raspbian wheezy https://archive.raspbian.org/raspbian
Build docker 0.6.6 using docker 0.6.4
cd /root/go/src/github.com/dotcloud/docker
git reset --hard
curl https://gist.github.com/petrosagg/7260553/raw/docker-arm-v0.6.6.patch | git apply -
docker build -t docker .
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.