Erlang cluster on Kubernetes: Speeding up the container build

21 Dec 2022 19:49 erlang kubernetes docker rebar3

I noticed that whenever I made any change to the application, it caused the dockerpodman build to re-fetch and recompile all of the dependencies. On the tiny laptop I was using at the time, this was taking several extra minutes for every build.

I asked on Hachyderm and got pointed to this Dockerfile. It’s for Elixir, but I was able to do something similar:

# ...

# Fetch deps into a separate layer; should improve caching.
COPY rebar.config rebar.config
COPY rebar.lock rebar.lock
RUN rebar3 get-deps
RUN rebar3 compile --deps_only

# Copy the rest and compile it
COPY . .
RUN rebar3 as prod release

# ...

By only copying the rebar.config and rebar.lock files, we don’t invalidate the caching unless those change. Then we can use rebar3 get-deps and rebar3 compile --deps_only to fetch and build the dependencies. That allows the dependencies to be cached.

Only then do we copy the rest of the files and build the release.

Note: changing the version number in rebar.config invalidates the cache and causes dependencies to be fetched and compiled again.

At this point, I’m not editing the version number (I’m relying on imagePullPolicy: Always and deleting the deployment to force container updates), so I’ll ignore it for now. It’ll need fixing later, once I start actually updating version numbers.

By putting the version number in rebar.config.script – see this post – and by omitting that file from the first stage of the build, we can avoid invalidating the cached layers.