There's a bunch of stuff on the internet about creating elixir clusters on raspberry pi's, but after a quick survey I only found stuff that builds from scratch or uses non-alpine bases or requires a super cool but nonstandard OS on the pi itself. I was looking for something a little bit different, but as a newcomer to docker, elixir, and raspberry pi I thought I'd be in for a difficult slog. It was much easier than expected!

Install Docker on Pi

You need docker already installed on your Raspberry Pi. If you're running some kind of Raspbian then the simplest thing you can do is just install it with the package manager, and chances are good it will work out of the box. That support has been official for a while.

I'll be writing another article about the Ansible that sets up my Pi's for Docker, so I won't get into that much here, but I will say for those are unfamiliar with docker that images can take up a lot of space. Personally my preference is that docker is storing data on a NAS, because it doesn't help much to use Docker to avoid cluttering my system only to discover that the drives is filling up rapidly.

Test Docker Install

Docker images for ARM can be a bit hard to come by, but luckily there's at least a base-image for alpine linux, and from there you can use the alpine package manager to do other stuff. First, verify your docker-installation and platform by running a command like this to test the alpine image.

sudo docker run -it --entrypoint=/bin/sh container4armhf/armhf-alpine -c "echo hello world"

Create Dockerfile

Save this as your Dockerfile

FROM container4armhf/armhf-alpine
RUN echo "" >> /etc/apk/repositories
RUN apk --update add elixir
ENTRYPOINT ["/usr/bin/elixir"]

You can build the Dockerfile with this command:

sudo docker build -t elixir-alpine-armhf-dev .


The build in the last section won't take long. After it's finished, things are working as expected:

pi@nomad:~ $ sudo docker run --rm -it elixir-alpine-armhf-dev

Usage: elixir [options] [.exs file] [data]

  -v                          Prints version and exits
  -e COMMAND                  Evaluates the given command (*)
  -r FILE                     Requires the given files/patterns (*)
  -S SCRIPT                   Finds and executes the given script in PATH
  -pr FILE                    Requires the given files/patterns in parallel (*)
  -pa PATH                    Prepends the given path to Erlang code path (*)
  -pz PATH                    Appends the given path to Erlang code path (*)

  --app APP                   Starts the given app and its dependencies (*)
  --cookie COOKIE             Sets a cookie for this distributed node
  --detached                  Starts the Erlang VM detached from console
  --erl SWITCHES              Switches to be passed down to Erlang (*)
  --hidden                    Makes a hidden node
  --logger-otp-reports BOOL   Enables or disables OTP reporting
  --logger-sasl-reports BOOL  Enables or disables SASL reporting
  --name NAME                 Makes and assigns a name to the distributed node
  --no-halt                   Does not halt the Erlang VM after execution
  --sname NAME                Makes and assigns a short name to the distributed node
  --werl                      Uses Erlang's Windows shell GUI (Windows only)

** Options marked with (*) can be given more than once
** Options given after the .exs file or -- are passed down to the executed code
** Options can be passed to the Erlang runtime using ELIXIR_ERL_OPTIONS or --erl