Elixir on Heroku with Docker Containers

It is possible to deploy your Elixir application on Heroku using the Elixir Buildpack. However, you may want to deploy using Docker on Heroku instead. Perhaps your application has complex setup or configuration needs. Or perhaps you already have a Docker-ified application and you don’t want to have to do extra work to convert it to buildpacks and Procfiles.

Heroku supports Docker via the Container Registry and Runtime. Here’s the process of getting it set up:

  1. Create a Heroku application with heroku create <app_name>.
  2. Set the Heroku stack to “container” heroku set:stack container. This enables the container functionality and ensures that Heroku doesn’t become confused if your project also contains other manifests (such as package.json or Gemfile).
  3. Set up your Docker environment to talk to Heroku’s Docker registry instead of the default Docker registry: heroku container:login.
  4. Build the image and push it to the Heroku registry: heroku container:push web.
  5. Deploy it to your dynos: heroku container:release web.
  6. Check your site and make sure everything works.
  7. If your application does not boot and logs the error message Shall I install Hex? (if running non-interactively, use "mix local.hex --force") [Yn] ** (Mix) Could not find an SCM for dependency :phoenix from <app_name>.Mixfile, you may have to make a small change to your Dockerfile.

    • Add ENV MIX_HOME=/opt/mix before you install hex & rebar in your Dockerfile. The reason this is needed from what I can gather is that Heroku’s Docker execution environment is different from your local development environment.

For reference, here’s my full Dockerfile for my Phoenix application:

FROM elixir:1.8.0-alpine

RUN apk add make gcc libc-dev

ENV CC=gcc
ENV MIX_HOME=/opt/mix

RUN mix local.hex --force \
  && mix local.rebar --force

WORKDIR /root/app

ADD ./ /root/app/

EXPOSE 4000

ARG MIX_ENV=prod
RUN echo ${MIX_ENV}
ENV MIX_ENV=$MIX_ENV
ENV PORT=4000

RUN mix deps.get
RUN mix deps.compile
RUN MAKE=cmake mix compile
RUN mix phx.digest

CMD ["mix", "phx.server"]

Categories: