We were unable to load Disqus. If you are a moderator please see our troubleshooting guide.

Preslav Rachev • 5 years ago

Thank you for this post! It saved me a ton of time while trying to deploy my Elixir release in a Docker container. I hope you will accept a tiny advice, in order to make the building process even more efficient:

Since Docker relies on layers, which it caches and reuses later on, I'd advise to first copy the mix.exs and mix.lock, get the dependencies, and only then copy the actual code over. This trick would effectively cache your fetched dependencies and reuse the layer in the future. Assuming that your actual code changes much more often than your dependency configuration, this will speed your image builds by an order of magnitude.

Alex Koutmos • 5 years ago

Great tip Preslav and thanks for sharing! I'll keep that one in mind :)

anandu pavanan • 5 years ago

Thanks for the post, very informative and practical. Please keep on continuing elixir and phoenix Ninja blog posts:)

Alex Koutmos • 5 years ago

Thanks for the kind words! I try and release a new post every 4-6 weeks for your reading pleasure :)

Hot Cheese • 5 years ago
you can also use alpine if you prefer but the build step will also require some changes if you chose to go that route


Can you please explain how to use Alpine in this case?

Alex Koutmos • 5 years ago

You would use the alpine based Elixir image during the first part of the multi-stage build https://hub.docker.com/laye...

And then in the second part of the multi-stage build you would use FROM alpine:3.11 for example, and copy over the Mix release artifact as I did here. Should work more or less the same minus the differences in commands available in alpine versus debian (namely apt-get).

Hope that helps!

Komo Kun • 5 years ago

Excellent post!

Sean Brennan • 6 years ago

Great post! Thanks. If you work with Phoenix LiveView at all a post about that would be helpful!

Alex Koutmos • 6 years ago

Thanks! Writing a post on LiveView is indeed on my radar. Next week I'll be publishing my post on setting up Prometheus+Grafana along with an Elixir+Phoenix app.

Sean Brennan • 6 years ago

With the image elixir:1.9.1 out, how would the Dockerfile change?
substituting "FROM elixir:1.9.1" for the "RUN set -xe" part doesn't seem to do it.
Edit: replacing the erlang image with the elixir worked!

Alex Koutmos • 6 years ago

The build stage of your multpart Dockerfile should look like this:


# ---- Build Stage ----
FROM elixir:1.9.1 AS app_builder

# Set environment variables for building the application
ENV MIX_ENV=prod \
LANG=C.UTF-8

# Install hex and rebar
RUN mix local.hex --force && \
mix local.rebar --force

# Create the application build directory
RUN mkdir /app
WORKDIR /app

# Copy over all the necessary application files and directories
COPY config ./config
COPY lib ./lib
COPY priv ./priv
COPY mix.exs .
COPY mix.lock .

# Fetch the application dependencies and build the application
RUN mix deps.get
RUN mix deps.compile
RUN mix release

Let me know if that works for you!

Ludovic Demblans • 6 years ago

Thank you very much for this post, it works very well !

I see a `rel` directory (that was genereated when I ran `mix release.init` I suppose). Should it be copied along with the config in the dockerfile ?

Alex Koutmos • 6 years ago

That is correct. When you run `mix release.init` the rel directory will be created. The rel directory contains scripts which allow you to configure BEAM virtual machine flags and environment variables for your application. In my example I am not copying over the directory in the Dockerfile since the files contain nothing of value (just commented out autogenerated stuff). If you find yourself needing to configure the BEAM or export env vars you should add those into your Dockerfile.

Ludovic Demblans • 6 years ago

Good to know, thank you :)

Antonio M. • 6 years ago

Thanks for the post,

I'm having an issue trying to build the image based on elixir 1.9.4, this is how the first part of the Dockerfile looks

# ---- Build Stage ----

FROM elixir:1.9.4 AS app_builder

# Set environment variables for building the application

ENV MIX_ENV=prod \

TEST=1 \

LANG=C.UTF-8

# Install hex and rebar

RUN mix local.hex --force && \

mix local.rebar --force

and I'm getting this error:

** (Mix) httpc request failed with: {:failed_connect, [{:to_address, {'repo.hex.pm', 443}}, {:inet, [:inet], :nxdomain}]}

Could not install Hex because Mix could not download metadata at https://repo.hex.pm/install....

If I run mix local.hex locally in the host machine it works, Does anyone having a similar issue?

Alex Koutmos • 6 years ago

I have never seen that issue before. Was it a transient error that went away? Perhaps hex was down?

Antonio M. • 6 years ago

It was transient, I tried a couple of hours later and it worked thanks !!!

Chuck Irvine • 6 years ago

I would like to see something like this for non-phoenix Elixir applications.

Alex Koutmos • 6 years ago

Have anything in mind in particular? Simple Plug example, RabbitMQ producer/consumer, etc?

Guest • 6 years ago
Alex Koutmos • 6 years ago

You're welcome! I plan to release a post every 3/4 weeks, so if there is anything you would like to see a tutorial style post about feel free to let me know :). Thanks for stopping by!