Detection

migetpacks detects an Elixir application when either of the following files is present in the project root:
  • mix.exs
  • mix.lock

Version Detection

Elixir Version

Elixir version is resolved in the following priority order:
SourceExample
.elixir-version1.18.4
.tool-versions (asdf)elixir 1.18.4
Default1.18.4

Erlang/OTP Version

Erlang version is resolved from:
SourceExample
.erlang-version27.0
.tool-versions (asdf)erlang 27.0
DefaultAuto-compatible with Elixir version
If no Erlang version is specified, the Elixir Docker image’s bundled Erlang/OTP version is used, which is guaranteed to be compatible.

Build Process

migetpacks generates a multi-stage Dockerfile using official Elixir images:
# Build stage
FROM elixir:1.18.4 AS builder
WORKDIR /build

# Elixir build environment
ENV MIX_ENV=prod
ENV ERL_FLAGS="-noinput"

# Layer caching: copy dependency files first
COPY mix.exs mix.lock* ./
COPY config ./config/

# Install Hex, Rebar, and fetch dependencies
RUN mix local.hex --force \
    && mix local.rebar --force \
    && mix deps.get --only prod

# Compile dependencies separately
RUN mix deps.compile

# Copy source code
COPY . .

# Compile and build release
RUN mix compile
RUN mix release

# Runtime stage
FROM elixir:1.18.4-slim
WORKDIR /app
COPY --from=builder --chown=1000:1000 /build /app

Phoenix Framework Detection

If mix.exs contains a :phoenix dependency, migetpacks automatically:
  1. Copies config/ early (needed for dependency compilation)
  2. Compiles assets using mix assets.deploy (or falls back to npm-based asset pipeline)
  3. Runs mix phx.digest for static file fingerprinting
# Phoenix asset compilation
RUN mix compile
RUN if [ -d "assets" ]; then \
      mix assets.deploy 2>/dev/null || \
      (cd assets && npm install && npm run deploy && cd .. && mix phx.digest); \
    fi

Umbrella Project Detection

If an apps/ directory exists, migetpacks detects an umbrella project and copies child mix.exs files for proper dependency resolution.

Mix Releases

migetpacks detects if the project uses Mix releases by checking for releases: in mix.exs. When releases are used:
  • The release binary is self-contained (no Hex/Mix needed at runtime)
  • The runtime image is slimmer
  • The run command uses the release binary
When releases are not used:
  • Hex and Mix are copied to the runtime image
  • Git is installed at runtime (needed for git dependency verification)
  • mix phx.server is used as the run command

Run Command

The default run command depends on whether Mix releases are configured:
ConfigurationDefault Command
With releases/app/bin/{app_name} start
Without releases (Phoenix)mix phx.server
Without releases (plain)mix run --no-halt
Override with RUN_COMMAND or a Procfile:
web: /app/bin/myapp start
worker: /app/bin/myapp eval "MyApp.Worker.start()"

Runtime Configuration

VariableValue
MIX_ENVprod
HOME/home/miget

Caching

Layer Caching

Dependencies are cached by copying mix.exs and mix.lock before the full source:
Cached FilesPurpose
mix.exsProject definition with dependencies
mix.lockLocked dependency versions
config/Configuration (Phoenix needs this for deps.compile)
ScenarioDependency Install
First buildRuns
Source code change onlyCached
mix.exs/mix.lock changeRuns

BUILD_CACHE_DIR

When BUILD_CACHE_DIR is set, Hex and Mix dependency caches persist at:
Cache PathContents
hex cacheHex packages
mix cacheMix dependencies and compiled artifacts

DHI Support

Docker Hardened Images (DHI) are not supported for Elixir. Official Elixir images are used for both build and runtime stages.
When USE_DHI=true is set, migetpacks will display a warning and continue using the official Elixir images:
StageImage
Buildelixir:{version}
Runtimeelixir:{version}-slim

Example

docker run --rm \
  -v /path/to/elixir-app:/workspace/source \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e OUTPUT_IMAGE=my-elixir-app:latest \
  miget/migetpacks:latest

Phoenix application

docker run --rm \
  -v /path/to/phoenix-app:/workspace/source \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e OUTPUT_IMAGE=my-phoenix-app:latest \
  miget/migetpacks:latest

Running Phoenix

Phoenix requires SECRET_KEY_BASE at runtime. Generate one with mix phx.gen.secret or openssl rand -hex 64:
docker run -p 5000:5000 \
  -e SECRET_KEY_BASE=$(openssl rand -hex 64) \
  my-phoenix-app:latest
For production with a database:
docker run -p 5000:5000 \
  -e SECRET_KEY_BASE=your-production-secret-key \
  -e DATABASE_URL=ecto://user:pass@host/db \
  my-phoenix-app:latest

With build cache

docker run --rm \
  -v /path/to/elixir-app:/workspace/source \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /tmp/build-cache:/cache \
  -e OUTPUT_IMAGE=my-elixir-app:latest \
  -e BUILD_CACHE_DIR=/cache \
  miget/migetpacks:latest