Mix install in umbrella projects without mix.exs?

I’m going to use Docker to run elixir app (oh, please don’t tell me don’t use Docker!).

This is a part of my Dockerfile for an umbrella to install dependency to leverage cache (i.e. do not compile deps everytime)

RUN mkdir -p \
    apps/foo \
COPY mix.exs mix.lock ./
COPY apps/foo/mix.exs apps/foo/
COPY apps/bar/mix.exs apps/bar/
RUN mix deps.get && mix deps.compile

If I just copy top-level mix.exs and mix.lock, it fetches all dependency but it only compiles top-level deps, not deps of individual apps. So I had to copy mix.exs of all apps. I guess mix deps.compile needs some package info from mix.exs.

Is it possible (by design) that mix later supports compiling all deps only from mix.lock?

1 Like

I believe this is because mix dep.compile is calling Mix.Dep.load_and_cache/0.

Ideally, it would be nice if I can run both mix deps.get and mix deps.compile only with mix.lock file - but I’m not sure internal dep cache can be rebuilt only with lockfile.

… but why should mix deps.compile care anything about the current project, except for listing the dependencies?

I see there are several reasons to have full mix project for deps.get and deps.compile

  • deps.precompile should be called inside deps.compile (src) and this is not in mix.lock
  • deps.get has --only option for environment, and that info is not in mix.lock

However, if we don’t need that feature very often, then we may add another task to get the list of dep (with correct SCM) and compile them only with mix lockfile.

As I need to build both prod and test dependencies in Docker (to build relkease and run tests)… I really want to avoid full compilation from scratch only for single unrelated changes in mix.exs.

1 Like

Did you get anything to work for you?

I am facing the same issue, and am considering creating a "dummy mix.exs" file that would mirror the original file, excluding parts that change often or irrelevant changes (e.g, project version or aliases).

Another thing I was considering was using buildkit with a cache mount, but that would only contribute to build speedup and would not result that layer being retrieved from cache.

I’m still using the original approach (copying all mix.exs and top-level mix.lock). I’m fine with that so far, since those file doesn’t change very often.

However, I’m not sure it’s right approach though. For example, if a dep is using compile-timed config - then shouldn’t I also include config files as well? hm… :confused: