# Lean Alpine-based image for SimpleshopTheme. # # Builder and runner both use Alpine (musl). The vix NIF is compiled against # Alpine's system libvips instead of the glibc-linked precompiled binary. # # Build: docker build -t simpleshop_theme . # Run: docker run --rm -p 4000:4000 \ # -e SECRET_KEY_BASE=$(mix phx.gen.secret) \ # -e DATABASE_PATH=/data/simpleshop_theme.db \ # -e PHX_HOST=localhost \ # -v simpleshop_data:/data \ # simpleshop_theme # # Images: # https://hub.docker.com/r/hexpm/elixir/tags?name=alpine # https://hub.docker.com/_/alpine ARG ELIXIR_VERSION=1.19.5 ARG OTP_VERSION=28.2 ARG ALPINE_VERSION=3.23.3 ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-alpine-${ALPINE_VERSION}" ARG RUNNER_IMAGE="alpine:${ALPINE_VERSION}" # --- Builder --- FROM ${BUILDER_IMAGE} AS builder # Build deps: C compiler for NIFs, git for hex deps, vips-dev for image processing RUN apk add --no-cache build-base git vips-dev WORKDIR /app RUN mix local.hex --force && mix local.rebar --force ENV MIX_ENV="prod" # Use Alpine's system libvips instead of the glibc-linked precompiled binary ENV VIX_COMPILATION_MODE="PLATFORM_PROVIDED_LIBVIPS" # Install mix dependencies COPY mix.exs mix.lock ./ RUN mix deps.get --only $MIX_ENV RUN mkdir config # Compile dependencies (config needed first) COPY config/config.exs config/${MIX_ENV}.exs config/ RUN mix deps.compile # Install tailwind and esbuild CLI tools RUN mix assets.setup # Copy priv in layers ordered by change frequency. # Mockups/fonts are stable; migrations and seeds change more often. COPY priv/static/mockups priv/static/mockups COPY priv/static/fonts priv/static/fonts COPY priv/static/images priv/static/images COPY priv/static/favicon.ico priv/static/robots.txt priv/static/ COPY priv/repo priv/repo COPY priv/gettext priv/gettext # Application code and frontend assets (change most often) COPY lib lib COPY assets assets # Compile the application RUN mix compile # Build assets (both tailwind profiles + esbuild + phx.digest) RUN mix assets.deploy # Remove gzipped copies of mockup images — WebP is already compressed, # gzip saves ~0% and just wastes space in the release RUN find priv/static/mockups -name "*.gz" -delete 2>/dev/null || true # Runtime config doesn't need recompilation COPY config/runtime.exs config/ # Release overlay scripts COPY rel rel # Build the release RUN mix release # --- Runner --- FROM ${RUNNER_IMAGE} AS runner # Runtime deps only — no compilers, no -dev packages RUN apk add --no-cache libstdc++ openssl ncurses-libs vips WORKDIR /app # Non-root user for security RUN adduser -D -h /app appuser RUN chown appuser:appuser /app # Prepare the data directory (for SQLite database) RUN mkdir -p /data && chown appuser:appuser /data ENV MIX_ENV="prod" # Copy the release from the builder COPY --from=builder --chown=appuser:appuser /app/_build/${MIX_ENV}/rel/simpleshop_theme ./ USER appuser # Ensure /data is the default database location ENV DATABASE_PATH="/data/simpleshop_theme.db" EXPOSE 4000 CMD ["/app/bin/server"]