114 lines
3.1 KiB
Docker
114 lines
3.1 KiB
Docker
|
|
# 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"]
|