simpleshop_theme/Dockerfile

114 lines
3.1 KiB
Docker
Raw Permalink Normal View History

# 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"]