prop/Dockerfile.ci
Graham McIntire 845f23b093
Some checks failed
Build base image / Build and push base image (push) Successful in 15s
Build and Push / Build CI test image (push) Successful in 5m17s
Build and Push / Build and Push Docker Image (push) Failing after 6m9s
fix(ci): use DEBUG=1 instead of sed to avoid EXLA OOM
Replace fragile sed -i s/-O3/-O0/g with DEBUG=1 env var. EXLA's Makefile
natively checks ifdef DEBUG and uses -g (debug symbols) instead of -O3
(heavy optimization), avoiding the g++ OOM kill on CI runners.

Also set EXLA_CPU_ONLY=1 to skip unnecessary nvcc probing.
2026-08-05 14:00:27 -05:00

68 lines
2.6 KiB
Text

# syntax=docker/dockerfile:1.6
#
# Pre-built CI test image. Extends the hexpm/elixir image with:
# * build-essential + git + curl + ca-certificates + cdo
# * hex + rebar
# * Precompiled EXLA NIF + object files at /opt/exla-cache/
#
# EXLA's cached_make copies libexla.so to deps/exla/cache/, but Make
# still tries to compile .o files when they're missing (they don't
# survive mix deps.get). We save the full cache/ directory and restore
# it in the test step before mix test runs.
#
# Rebuild whenever mix.exs changes elixir/exla/xla versions or c_src/
# files change (the cache key auto-invalidates).
#
# Built by .forgejo/workflows/build.yaml (build-ci-image job).
ARG ELIXIR_IMAGE="docker.io/hexpm/elixir:1.20.1-erlang-29.0.2-debian-trixie-20260518-slim"
FROM ${ELIXIR_IMAGE} AS builder
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update -qq && \
apt-get install -y -qq git curl ca-certificates build-essential cdo && \
rm -rf /var/lib/apt/lists/*
RUN mix local.hex --force && mix local.rebar --force
WORKDIR /tmp/exla_warm
COPY mix.exs mix.lock /tmp/exla_warm/
COPY vendor /tmp/exla_warm/vendor
# Minimal config — nx needs :default_backend to exist.
# Set :exla make_args to -j1 so C++ compiles serially (the default
# nproc-2 can cause parallel OOM kills on CI runners).
RUN mkdir -p /tmp/exla_warm/config && \
printf 'import Config\nconfig :nx, :default_backend, EXLA.Backend\nconfig :exla, :make_args, ["-j1"]\n' > /tmp/exla_warm/config/config.exs
# Compile all deps. EXLA's Makefile defaults to -O3 which OOM-kills g++
# on low-memory CI runners. Set DEBUG=1 so the Makefile uses -g
# (debug symbols, low compile-time memory) instead of -O3 (heavy
# optimization passes). Also set EXLA_CPU_ONLY=1 to skip nvcc probing.
RUN mix deps.get && \
DEBUG=1 EXLA_CPU_ONLY=1 mix deps.compile
# Save the full build cache (libexla.so + .o files + xla_extension lib)
# so Make finds all targets already built when restored in the test step.
RUN mkdir -p /opt/exla-cache && \
cp -a deps/exla/cache /opt/exla-cache/cache
FROM ${ELIXIR_IMAGE} AS final
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update -qq && \
apt-get install -y -qq git curl ca-certificates build-essential cdo && \
rm -rf /var/lib/apt/lists/*
RUN mix local.hex --force && mix local.rebar --force
# XLA archive download + cached libexla.so (cached_make fast path).
COPY --from=builder /root/.cache/xla /root/.cache/xla
# Pre-built EXLA object files + libexla.so + xla_extension/ lib.
# Restored in the test step: cp -a /opt/exla-cache/cache /app/deps/exla/cache
COPY --from=builder /opt/exla-cache /opt/exla-cache
WORKDIR /app