Docker Raspberry Pi Images

Posted on 11 Feb 2015 by Eric Oestrich

For a while I’ve been interested in doing some kind of cluster with Raspberry Pis. When the second version came out, I decided to look into docker based deployment. I found some really cool stuff in CoreOS, but I doubt we’ll get that any time soon. For now I will make due with a plain Arch install running docker.

Docker was easy to install on Arch, but I ran into a problem fairly quickly. I couldn’t find any images that were built for the ARM platform on the docker hub. This seemed like a good chance to try out building a docker image from scratch.

oestrich/arch-pi Dockerfile
FROM scratch
COPY . /

The arch-pi image is the latest raspberry pi Arch tar.gz that is extracted into the same folder as the Dockerfile. I use arch-chroot on that folder to be able to remove a few packages first. This helps shrink the image considerably. I removed most of the firmware and kernels. Since docker uses the host kernel, this is OK to do.

oestrich/base-pi Dockerfile
FROM oestrich/arch-pi
MAINTAINER Eric Oestrich <eric@oestrich.org>

RUN pacman -Syu --noconfirm
RUN pacman -S --noconfirm \
      base-devel \
      libffi \
      libyaml \
      openssl \
      zlib \
      git

RUN git clone https://github.com/sstephenson/ruby-build.git
RUN cd ruby-build && ./install.sh
RUN ruby-build 2.2.0 /opt/ruby
ENV PATH $PATH:/opt/ruby/bin

This docker image installs everything needed to get ruby installed. Note that this will take a good hour or so to build. I did discover that the Raspberry Pi was quicker than the old t1.micro instance on AWS, go Raspberry Pi.

oestrich/base-pi-web Dockerfile
FROM oestrich/base-pi
MAINTAINER Eric Oestrich <eric@oestrich.org>

RUN pacman -Syu --noconfirm
RUN pacman -S --noconfirm \
      libxml2 \
      libxslt \
      imagemagick \
      openssl \
      postgresql \
      python2

RUN gem install bundler
RUN gem install foreman
RUN gem install libv8 --version 3.16.14.7
RUN gem install nokogiri --version 1.6.5

This docker image gets the base environment set for a rails app. Whatever system libraries are required and some base gems like bundler and foreman. I also installed libv8 and nokogiri because together they take about 40 minutes to install. I used the --version flag to install the exact version that bundler will install. This lets bundler simple use the installed gem, saving 40 minutes each time the Gemfile changes.

project/web Dockerfile
FROM oestrich/base-pi-web
MAINTAINER Eric Oestrich <eric@oestrich.org>

RUN mkdir -p /apps/project

ADD Gemfile* /apps/project/

WORKDIR /apps/project
RUN bundle -j4 --without development test
ADD . /apps/project
ADD .env.production /apps/project/.env

RUN . /apps/project/.env && bundle exec rake assets:precompile

CMD ["foreman", "start", "web"]

This last docker image installs a rails app. It copies over the Gemfile and Gemfile.lock into the container first to install gems. This way you only rebundle if your Gemfile changes, saving time on each deploy. I also want to point out the -j4 option on the bundle. The Raspberry Pi 2 is quad core, so let’s use all the power available. Assets are compiled and then ends with a CMD of foreman start web.

An alternative to CMD is to use ENTRYPOINT:

ENTRYPOINT ["foreman", "start"]

This will let you use different foreman apps without having to build a separate image for each one.

docker run -t -i -p 5000:5000 project/web worker
comments powered by Disqus
Creative Commons License
This site's content is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License unless otherwise specified. Code on this site is licensed under the MIT License unless otherwise specified.