Skip to content

pierce-h/docker-elixir-build

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 

Repository files navigation

Docker Elixir Build Image Base

This builds a Docker image that can be used as a base to build Elixir (and Erlang) projects.

Contents

As of elixir-build:2.2.0:

  • Erlang 21.0
  • Elixir 1.6.6
  • Node 8.9.3 (npm 5.5.1)
  • make, git
  • openssl

hex and rebar are also installed.

A multi-stage minimal image build

With the new Docker multi-stage builds facility (17.05+) it is now simple to write a single Dockerfile that can build an Elixir project, and create a minimal run-time image using simply docker build.

Assuming distillery is set up, and its rel/config.exs is configured for a stand-alone ERTS release as so:

environment :docker do
  set dev_mode: false
  set include_erts: true
  set include_src: false
  set cookie: :crypto.hash(:sha256, :crypto.rand_bytes(25)) |> Base.encode16 |> String.to_atom
end

Then a Dockerfile to build a minimal run-time image for a Phoenix project may look like:

FROM nexus.in.ft.com:5000/membership/elixir-build:2.2.0 AS build

WORKDIR /build

COPY mix.exs .
COPY mix.lock .
COPY deps deps

ARG MIX_ENV=docker
ARG APP_VERSION=0.0.0
ENV MIX_ENV ${MIX_ENV}
ENV APP_VERSION ${APP_VERSION}

RUN mix deps.get

COPY lib lib
COPY test test
COPY config config
COPY rel rel

# Uncomment line below if you have assets in the priv dir
# COPY priv priv

# Build Phoenix assets
COPY assets assets
RUN cd assets && npm install && ./node_modules/.bin/brunch build --production
RUN mix phx.digest


RUN mix release --env=${MIX_ENV}

### Minimal run-time image
FROM alpine:latest

RUN apk --no-cache update && apk --no-cache upgrade && apk --no-cache add ncurses-libs openssl bash ca-certificates

RUN adduser -D app

ARG MIX_ENV=docker
ARG APP_VERSION=0.0.0

ENV MIX_ENV ${MIX_ENV}
ENV APP_VERSION ${APP_VERSION}

WORKDIR /opt/app

# Copy release from build stage
COPY --from=build /build/_build/${MIX_ENV}/rel/* ./

USER app

# Mutable Runtime Environment
RUN mkdir /tmp/app
ENV RELEASE_MUTABLE_DIR /tmp/app
ENV START_ERL_DATA /tmp/app/start_erl.data

# Start command
# NB 'myapp' should be replaced by your application name, as per mix.exs
CMD ["/opt/app/bin/myapp", "foreground"]

This uses distillery to build a the stand-alone release in one stage, and then copies the release artefacts from the first stage to a second stage, starting afresh from the minimal Alpine base image. Adds additional package openssl to libcrypto.so is available at runtime, YMMV.

NB the APP_VERSION environment var is used in the mix.exs above to set the version, e.g.:

  @version System.get_env("APP_VERSION") || "0.0.0"

  def project do
    [app: :myapp,
     version: @version,
     ...

so passing it as a --build-arg allows the release version to be set, making the whole build image command for a project simply:

docker build --build-arg APP_VERSION=1.1.2 .

About

Dockerfile for building Elixir projects

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Dockerfile 100.0%