# Dockerfile for Dokku deployment # Multi-stage build for Phoenix/Elixir app with monorepo layout ARG ELIXIR_VERSION=1.18.3 ARG OTP_VERSION=27.2.4 ARG DEBIAN_VERSION=bookworm-20260316-slim ARG BUILDER_IMAGE="docker.io/hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}" ARG RUNNER_IMAGE="docker.io/debian:${DEBIAN_VERSION}" # ============================================================================= # Build stage # ============================================================================= FROM ${BUILDER_IMAGE} AS builder RUN apt-get update -y && apt-get install -y build-essential git \ && apt-get clean && rm -f /var/lib/apt/lists/*_* WORKDIR /build # Install hex + rebar RUN mix local.hex --force && \ mix local.rebar --force ENV MIX_ENV="prod" # Copy blogex dependency first (changes less often) COPY blogex /build/blogex # Copy app dependency files first for better layer caching COPY app/mix.exs app/mix.lock /build/app/ WORKDIR /build/app RUN mix deps.get --only $MIX_ENV RUN mkdir config # Copy compile-time config files COPY app/config/config.exs app/config/${MIX_ENV}.exs config/ RUN mix deps.compile # Copy application source and compile COPY app/priv priv COPY app/assets assets COPY app/lib lib COPY app/rel rel COPY app/config/runtime.exs config/ RUN mix compile # Build assets after compile (phoenix-colocated hooks need compiled app) RUN mix assets.deploy # Build the release RUN mix release # ============================================================================= # Runtime stage # ============================================================================= FROM ${RUNNER_IMAGE} RUN apt-get update -y && \ apt-get install -y libstdc++6 openssl libncurses5 locales ca-certificates \ && apt-get clean && rm -f /var/lib/apt/lists/*_* # Set the locale RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen ENV LANG=en_US.UTF-8 ENV LANGUAGE=en_US:en ENV LC_ALL=en_US.UTF-8 WORKDIR /app RUN chown nobody /app ENV MIX_ENV="prod" # Copy the release from the build stage COPY --from=builder --chown=nobody:root /build/app/_build/${MIX_ENV}/rel/firehose ./ USER nobody # Dokku uses the EXPOSE port for routing EXPOSE 5000 ENV PHX_SERVER=true CMD ["/app/bin/server"]