docker from scratch in erlang.mk

I have been using erlang.mk for a couple of years now on various projects – just a Makefile, but what a Makefile! I’ve recently added a fork that includes support for creating docker containers from scratch.

On MacOS you might want to run shortishly/docker-erlang which will give you erlang and docker packaged together in a shell (brew install docker-machine if you don’t already have it):

docker run \
       -v /var/run/docker.sock:/var/run/docker.sock \
       -t \
       -i \
       --rm \
       shortishly/docker-erlang \
       /bin/bash

This is a short tutorial that assumes you are running on Linux, with both erlang and docker installed:

First lets create and move into a directory for this tutorial:

mkdir demo && cd demo

We need a copy of erlang.mk from the fork that I have created:

wget -q https://github.com/shortishly/erlang.mk/raw/master/erlang.mk

Bootstrap a new erlang.mk project as you would do normally, including a release template:

make -f erlang.mk bootstrap
make bootstrap-rel

Also bootstrap this project to create a Docker container:

make bootstrap-docker

The “bootstrap-docker” target has created a Dockerfile for us:

FROM scratch

ARG REL_NAME
ARG REL_VSN=1
ARG ERTS_VSN

ENV BINDIR /erts-7.2.1/bin
ENV BOOT /releases/1/demo_release
ENV CONFIG /releases/1/sys.config
ENV ARGS_FILE /releases/1/vm.args

ENV TZ=GMT

ENTRYPOINT exec ${BINDIR}/erlexec -boot_var /lib -boot ${BOOT} -noinput -config ${CONFIG} -args_file ${ARGS_FILE}

ADD _rel/demo_release/ /

Finally! Lets build the demo:

make

There should be lots of output at this point. At the end you should see:

===> Starting relx build process ...
===> Resolving OTP Applications from directories:
          /home/pmorgan/src/git/demo/ebin
          /home/pmorgan/opt/erlang/18.2.1/lib
          /home/pmorgan/src/git/demo/apps
          /home/pmorgan/src/git/demo/deps
===> Resolved demo_release-1
===> Including Erts from /home/pmorgan/opt/erlang/18.2.1
===> release successfully created!
 GEN    docker-scratch-cp-dynamic-libs
 GEN    docker-scratch-cp-link-loader
 GEN    docker-scratch-cp-sh
 GEN    docker-strip-erts-binaries
 GEN    docker-build
sha256:6440d984e0efb5a7f10168e805cdfcf47f670b03ce953427ba2613b177072d8c

A release has been successfully created “demo_release-1”, together with a bunch of new docker based targets and a new docker image (you will have a different sh256 output). You can check the output of docker images:

docker images

REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
demo_release               0.0.1               6440d984e0ef        3 minutes ago       22.02 MB

You can run the image with make docker-run:

make docker-run

 GEN    docker-rm
 GEN    docker-run
b9deb1f7ef337540a6d17731ef309768c22cc0fa9703ea68be819895e4d78732

Again, you will have a different hash shown for the container that is now running – you can check that it is running with docker ps -a:

docker ps -a

CONTAINER ID        IMAGE                COMMAND                  CREATED              STATUS              PORTS               NAMES
b9deb1f7ef33        demo_release:0.0.1   "/bin/sh -c 'exec ${B"   About a minute ago   Up About a minute                       demo_release

You can use the shortcut make docker-logs to display the logs from your container:

make docker-logs

 GEN    docker-logs
heart_beat_kill_pid = 1

So with the help of erlang.mk we have been able to bootstrap an erlang project, building and running a docker container in about 10 shell commands.

Leave a Reply

Your email address will not be published. Required fields are marked *