Mix test runs locally, but not in Docker container

Hi,

I’m able to run my test from my terminal, but if I’m not able to run the tests from within a container.

I get this error when I run docker compose up:

test-1  | Compiling 50 files (.ex)
test-1  | Generated easy_solutions app
test-1  | ** (exit) exited in: GenServer.call(ExUnit.Server, :modules_loaded, :infinity)
test-1  |     ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
test-1  |     (elixir 1.14.0) lib/gen_server.ex:1027: GenServer.call/3
test-1  |     (ex_unit 1.14.0) lib/ex_unit.ex:376: ExUnit.run/1
test-1  |     (mix 1.14.0) lib/mix/compilers/test.ex:42: Mix.Compilers.Test.require_and_run/4
test-1  |     (mix 1.14.0) lib/mix/tasks/test.ex:543: Mix.Tasks.Test.do_run/3
test-1  |     (mix 1.14.0) lib/mix/task.ex:421: anonymous fn/3 in Mix.Task.run_task/4
test-1  |     (mix 1.14.0) lib/mix/task.ex:475: Mix.Task.run_alias/6
test-1  |     (mix 1.14.0) lib/mix/cli.ex:84: Mix.CLI.run_task/2

I have also tried to replace entrypoint with sleep, so that I can do a docker compose exec test /bin/bash into the container. I can confirm that mix compile works, and I get the same error when I run mix test.

Any suggestions to how I can debug this further?

test.Dockerfile

FROM ubuntu:24.04 

ENV MIX_ENV=test
ENV DOCKER_BUILDKIT=1


USER root
RUN apt update
RUN apt install -y erlang-dev elixir erlang-xmerl  
RUN apt install -y curl git 

RUN useradd -ms /bin/bash appuser
RUN mkdir /app
RUN chown -R appuser /app

USER appuser

COPY . /app
WORKDIR /app


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

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

# compile dependencies
COPY config ./config/


ENTRYPOINT ["mix", "test"]

docker-compose.yaml

version: "3"

services:
  test:
    environment:
      DATABASE_PATH: priv/databases/test.db
      SECRET_KEY_BASE: "l7sdfjkhj"
  

    build:
      context: .
      dockerfile:
        test.Dockerfile
    volumes:
      - ./test_result:/app/test_result


I have found this to work previously

ARG ELIXIR_VERSION=1.14.5
ARG OTP_VERSION=26.0.2
ARG DEBIAN_VERSION=bullseye-20231009-slim

ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}"
ARG RUNNER_IMAGE="debian:${DEBIAN_VERSION}"

FROM ${BUILDER_IMAGE} as builder

# .... SNIP ...

FROM ${RUNNER_IMAGE}

# .... SNIP ...

Thanks for the suggestion, @jarlah!
Following your advice, I used the Dockerfile generated by mix phx.gen.release --docker.
I added this the the bottom of the Dockerfile:

FROM builder as test
WORKDIR "/app"

ENV MIX_ENV="test"
COPY . .

# install mix dependencies
RUN mix deps.get --only $MIX_ENV
CMD ["mix", "test"]

My docker-compose.yaml looks like this:


version: "3"

services:
  test:
    environment:
      DATABASE_PATH: priv/databases/test.db
      SECRET_KEY_BASE: "l7sdfjkhj"

    build:
      context: .
      dockerfile: Dockerfile

Now I can run my tests in a CI/CD pipeline by simply executing
docker compose up test

1 Like

Is there a reason you are not using a pre-built docker image for that?

You can find them on dockerhub and hex.

They have erlang and elixir pre-installed and you can select the specific version you need.

2 Likes