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.
FROM scratch COPY . /
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.
FROM oestrich/arch-pi MAINTAINER Eric Oestrich <firstname.lastname@example.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.
FROM oestrich/base-pi MAINTAINER Eric Oestrich <email@example.com> 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 184.108.40.206 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
foreman. I also installed
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.
FROM oestrich/base-pi-web MAINTAINER Eric Oestrich <firstname.lastname@example.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.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
foreman start web.
An alternative to
CMD is to use
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