多阶段构建Elixir Docker镜像遇erlexec文件找不到错误求助
问题排查与解决方案
错误原因分析
你遇到的erlexec: not found错误核心来自三个问题:
- libc环境不兼容:构建阶段的
elixir:1.15.1基于Debian(glibc),编译出的Erlang运行时(ERTS)依赖glibc;而最终阶段用的alpine:3.14采用musl libc,两者二进制不兼容,导致系统无法识别erlexec文件。 - 构建流程顺序错误:原Dockerfile中
COPY config/prod.env.exs config/在mix release之后执行,发布包并未包含这个生产配置文件,可能引发运行时配置异常。 - 冗余复制:
COPY --from=build . .复制了整个构建目录,既浪费镜像空间,还可能引入无关文件干扰运行。
修复方案
方案1:使用Debian轻量镜像匹配构建环境
保持构建阶段的Debian环境,最终阶段用轻量Debian slim镜像,规避libc兼容问题:
FROM elixir:1.15.1 as build ENV MIX_ENV=prod # 提前复制所有项目文件,确保release使用正确配置 COPY . . RUN mix local.hex --force && \ mix local.rebar --force && \ mix deps.get && \ mix release # 最终阶段采用Debian slim镜像,与构建阶段libc环境一致 FROM debian:bookworm-slim # 安装运行必需的依赖 RUN apt-get update && apt-get install -y --no-install-recommends \ bash openssl && \ rm -rf /var/lib/apt/lists/* WORKDIR /app # 仅复制release产物到工作目录,减少镜像体积 COPY --from=build /app/_build/prod/rel/todo_app . ENV REPLACE_OS_VARS=true ENV PORT=80 ENV MIX_ENV=prod EXPOSE 80 CMD ["bin/todo_app", "start"]
方案2:全程使用Alpine镜像适配musl
如果坚持用Alpine作为最终镜像,需用Alpine版本的Elixir镜像构建,确保ERTS编译时适配musl:
# 使用Alpine版Elixir镜像构建,保证编译产物适配musl FROM elixir:1.15.1-alpine as build ENV MIX_ENV=prod # 安装编译必需的依赖 RUN apk add --no-cache build-base git COPY . . RUN mix local.hex --force && \ mix local.rebar --force && \ mix deps.get && \ mix release # 最终阶段使用Alpine镜像 FROM alpine:3.18 # 安装Erlang运行必需的依赖(包括ncurses-libs) RUN apk add --no-cache bash openssl ncurses-libs WORKDIR /app COPY --from=build /app/_build/prod/rel/todo_app . ENV REPLACE_OS_VARS=true ENV PORT=80 ENV MIX_ENV=prod EXPOSE 80 CMD ["bin/todo_app", "start"]
关键优化点说明
- 配置文件时机:必须在
mix release前复制所有配置文件,确保发布包包含正确的生产配置。 - 最小化复制:只复制
_build/prod/rel/todo_app目录,避免冗余文件,减少镜像体积。 - 依赖匹配:确保构建和运行阶段的libc环境一致,或使用对应环境的编译镜像。
内容的提问来源于stack exchange,提问作者kusiaga
相关产品推荐
相关产品推荐

