Why inconsistent Elixir version on Docker

I want to use Elixir:1.9.1 and Phoenix: 1.4.9, so docker-compose up successfully, but inconsistent Phoenix and Elixir versions mix deps file and Docker-container.
Is there a best setting for matching version consistency?

  • Dockerfile
FROM elixir:1.9.1

RUN curl -sL https://deb.nodesource.com/setup_10.x | bash \
  && apt-get install -y nodejs

RUN npm install npm@latest -g

RUN mix local.hex --force && \
  mix archive.install hex phx_new 1.4.9 --force && \
  mix local.rebar --force && \

RUN apt-get install -y inotify-tools

WORKDIR /app
$ docker-compose run web mix phx.new sample --no-ecto
  • mix.exs(Why elixir: “~> 1.4” and phoenix, “~> 1.3.4”)
defmodule Sample.Mixfile do
  use Mix.Project

  def project do
    [
      app: :sample,
      version: "0.0.1",
      elixir: "~> 1.4",
      elixirc_paths: elixirc_paths(Mix.env),
      compilers: [:phoenix, :gettext] ++ Mix.compilers,
      start_permanent: Mix.env == :prod,
      deps: deps()
    ]
  end

  # Configuration for the OTP application.
  #
  # Type `mix help compile.app` for more information.
  def application do
    [
      mod: {Sample.Application, []},
      extra_applications: [:logger, :runtime_tools]
    ]
  end

  # Specifies which paths to compile per environment.
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_),     do: ["lib"]

  # Specifies your project dependencies.
  #
  # Type `mix help deps` for examples and options.
  defp deps do
    [
      {:phoenix, "~> 1.3.4"},
      {:phoenix_pubsub, "~> 1.0"},
      {:phoenix_html, "~> 2.10"},
      {:phoenix_live_reload, "~> 1.0", only: :dev},
      {:gettext, "~> 0.11"},
      {:cowboy, "~> 1.0"}
    ]
  end
end

In container(Phoenix v1.4.9 is correct, but Elixir 1.8.1 is wrong),

$ docker exec -it CONTAINER_ID bash
root@XXXXXXX:/app# mix phx.new --version
Phoenix v1.4.9
root@XXXXXXX:/app# elixir -v
Erlang/OTP 21 [erts-10.3.4] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [hipe]

Elixir 1.8.1 (compiled with Erlang/OTP 21)

refs

For me, elixir:1.9.1 contains an elixir that is version 1.9.1, so I can not reconstruct your issue.

Are you sure you are in the correct container?

Aside of that, there is usually no need to have phy_new installed in a container. You usually do not create a new project from within the container, but only compile and run it. phx_new is really just the generators, it is not a run time dependency of phoenix.

2 Likes

I tried your Dockerfile and the result is below

# elixir -v
Erlang/OTP 22 [erts-10.4.4] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [hipe]

Elixir 1.9.1 (compiled with Erlang/OTP 22)

I guess you may try to rebuild the image


Besides, for your reference I am using these config on my api server. It works pretty well

Dockerfile dev

# Extend from the official Elixir image
FROM elixir:1.9.0-alpine

# Create app directory and copy the Elixir projects into it
RUN mkdir /app
COPY . /app
WORKDIR /app

# Install hex package manager
# By using --force, we don’t need to type “Y” to confirm the installation
RUN apk add --update git && mix local.hex --force && \
    mix local.rebar --force && \
    mix hex.info &&\
    mix deps.get &&\
    mix deps.compile

CMD ["./entrypoint.sh"]

entrypoint.sh


#!/bin/sh

mix deps.get
mix ecto.migrate
mix phx.server

Dockerfile

# Extend from the official Elixir image
FROM elixir:1.9.0-alpine as build

ENV MIX_ENV=prod

RUN mkdir /app
WORKDIR /app

# install mix dependencies
COPY mix.exs mix.lock ./
COPY config config
RUN mix deps.get
RUN mix deps.compile

# build project
COPY priv priv
COPY lib lib
RUN mix compile

# build release
RUN mix release

# prepare release image
FROM alpine:3.9 AS app
RUN apk add --update bash openssl

RUN mkdir /app
WORKDIR /app

COPY --from=build /app/_build/prod/rel/myapp ./
RUN chown -R nobody: /app
USER nobody

ENV HOME=/app

CMD ["./bin/myapp", "start"]
2 Likes

Is it possible you have upgraded your Dockerfile but not rebuilt your containers before running docker compose run? That command does not automatically handle changes to the Dockerfile.

1 Like

Thanks reply.
I had 1.7.4 and 1.8.1, 1.9.1 on Elixir images, so tried to remove these images.
Then I thought some dependencies including phoenix, are consistent(not change code), but why still elixir: “~> 1.5” in mix.exs…
Let me think about it.Thank you!


Because thats the minimum version that is required by phoenix, of course you are free to choose any other version bounds you like.

That has nothing to do with the actual elixir version that is used.

Its just that you would see an error when you were using an elixir version thats not matching that version spec.

3 Likes

Thank you so much for your lucid explanations :bowing_man:

Hi there, original author here of the Github repo that you referenced :slight_smile:

With respect to versions (see release tags in the repo), I am doing my best to match Elixir releases to Phoenix releases, for instance, Phoenix 1.4.9 was released July 3rd, while Elixir 1.9.1 was released July 18th, so the natural thing would be to match it with Elixir 1.9.0 released June 24th.

However in this particular case, I really wanted the bug fix for Fix formatter wrongly removing nested parens in nested calls that came with 1.9.1 so I matched the Phoenix 1.4.9 container with the later Elixir release. Hope that makes sense?

Cheers!

3 Likes

But why pull phx_new in? You do not need it, unless you want to run mix phx.new, whioch you rarely do in a container.

That’s exactly the reason :wink: Keep in mind, everyone has different workflows and use cases… for example I find myself creating projects with older Phoenix versions from time to time (e.g., to create a prototype for an older app that I am maintaining) - doing that with a phx.new that’s baked into a particular Docker image is super convenient.

1 Like

I don’t get it.
Where else would you run
$ mix phx.new
If not in the container?
If I do not have it in the container, then it means running on my machine, meaning I need to install elixir on my machine, which I do not want, because I only want it in my container.

Thats of course one of the rare use cases where you indeed want it in the container :wink:

Though the docker file from this post was not intended to be used as a development “VM”, but instead as a deployment target.

Thx for clearing up, I thought I had it all wrongly set up. :wink:

1 Like