An OTP release is a standalone, compiled, runnable system containing the minimum OTP applications required by an Erlang or Elixir application. It can also embed the minimum Erlang runtime, making the package self-sufficient. Releases contain runtime artifacts, not source code, documentation, or tests. section 13.2 section 13.4
The operational motivation is to build once and ship binary artifacts. Production hosts then need no source tree, compilation toolchain, Elixir installation, or Erlang installation when the runtime is embedded. Releases also support remote interaction and systematic online upgrades and downgrades. section 13.2 section 13.1.3
A release separates production operation from compilation:
- Compile the application and dependencies, assemble the release, and transfer only the resulting runtime package. section 13.0 section 13.2
- Start the packaged system in the foreground with start, or start_iex when an attached interactive shell is useful. section 13.2.4
- Use a remote shell or runtime observation tools to interact with and inspect the running BEAM node. section 13.4 section 13.3.3
Packaging an Elixir release in Docker
A two-stage Docker build compiles the project and runs mix release in an Elixir/Erlang builder image, then copies _build/prod/rel/todo into a smaller Debian image. The container starts /todo/bin/todo start_iex, exposing the running to-do system for HTTP requests. section 13.2.4
Listing 13.2 The build stage (todo_release/Dockerfile)
ARG ELIXIR="1.15.4" #1
ARG ERLANG="26.0.2" #1
ARG DEBIAN="bookworm-20230612-slim" #1
ARG OS="debian-${DEBIAN}" #1
FROM "hexpm/elixir:${ELIXIR}-erlang-${ERLANG}-${OS}" as builder #1
WORKDIR /todo
ENV MIX_ENV="prod" #2
RUN mix local.hex --force && mix local.rebar --force #3
COPY mix.exs mix.lock ./ #4
COPY config config #4
COPY lib lib #4
RUN mix deps.get --only prod #5
RUN mix release #6
...
Shows the build-stage Dockerfile that sets production mode, installs Mix tooling, copies project inputs, fetches production dependencies, and assembles the release. section 13.2.4
Listing 13.3 Building the final image (todo_release/Dockerfile)
ARG DEBIAN="bookworm-20230612-slim"
...
FROM debian:${DEBIAN} #1
WORKDIR "/todo"
RUN apt-get update -y && apt-get install -y openssl locales
COPY \ #2
--from=builder \ #2
--chown=nobody:root \ #2
/todo/_build/prod/rel/todo ./ #2
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
ENV LANG="en_US.UTF-8"
ENV LANGUAGE="en_US:en"
ENV LC_ALL="en_US.UTF-8"
CMD ["/todo/bin/todo", "start_iex"] #3
Shows the final runtime image that copies the compiled release, configures locales, and starts the packaged application. section 13.2.4
