aprs.me/Dockerfile
Graham McIntire 12971b63e2
Manually compile vendored aprs dependency
The vendored dependency wasn't being found in the expected location.
This approach manually compiles it and copies the compiled files to
the correct location before running the main compilation.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 17:42:33 -05:00

115 lines
3.1 KiB
Docker

# Build arguments
ARG ELIXIR_VERSION=1.18.4
ARG OTP_VERSION=27.2.4
ARG DEBIAN_VERSION=bullseye-20250520-slim
ARG APP_NAME=aprs
ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}"
ARG RUNNER_IMAGE="debian:${DEBIAN_VERSION}"
# Stage 1: Build Elixir release
FROM ${BUILDER_IMAGE} AS builder
# Install build dependencies
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update -y && apt-get install -y --no-install-recommends build-essential git curl \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Prepare build directory
WORKDIR /app
# Install Hex and Rebar
RUN mix local.hex --force && mix local.rebar --force
# Install mix_gleam archive (required for Gleam compilation)
RUN mix archive.install hex mix_gleam 0.6.2 --force
# Set build environment
ENV MIX_ENV="prod"
# Install dependencies
COPY mix.exs mix.lock ./
# Copy vendor directory for local dependencies
COPY vendor vendor
RUN mix deps.get --only $MIX_ENV
# Copy application code
COPY config config
COPY priv priv
COPY lib lib
COPY assets assets
COPY rel rel
# Copy Gleam source files and configuration
COPY src src
COPY gleam.toml gleam.toml
# Copy pre-compiled Gleam BEAM files
# This is crucial for production builds where gleam compiler is not available
COPY priv/gleam priv/gleam
# Compile all dependencies
RUN mix deps.compile
# Manually compile the vendored aprs dependency
RUN cd vendor/aprs && \
MIX_ENV=prod mix compile && \
mkdir -p ../../_build/prod/lib/aprs/ebin && \
cp -r _build/prod/lib/aprs/ebin/* ../../_build/prod/lib/aprs/ebin/ && \
cd ../..
# Copy Gleam BEAM files before compiling the main app
RUN mkdir -p _build/prod/lib/aprsme/ebin && \
cp priv/gleam/*.beam _build/prod/lib/aprsme/ebin/ || true
# Now compile the main application
RUN mix compile
# Install Node.js for asset building
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
apt-get install -y nodejs && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# Install npm dependencies
WORKDIR /app/assets
RUN npm install
# Go back to app root
WORKDIR /app
# Compile assets
RUN mix assets.deploy
# Compile and release
RUN mix release --path /app/release
# Stage 2: Runtime
FROM ${RUNNER_IMAGE}
# Install runtime dependencies
RUN apt-get update -y && \
apt-get install -y --no-install-recommends libstdc++6 openssl libncurses5 locales ca-certificates \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Set locale
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
ENV LANG="en_US.UTF-8" LANGUAGE="en_US:en" LC_ALL="en_US.UTF-8"
# Set working directory and create it
WORKDIR "/app"
RUN mkdir -p /app
# Set deployment timestamp to current time during runtime container build
RUN date -u +"%Y-%m-%dT%H:%M:%SZ" > /app/deployed_at.txt
# Copy release from builder
COPY --from=builder --chown=nobody:root /app/release ./
# Set ownership for the entire app directory
RUN chown -R nobody:root /app
# Set user and command
USER nobody
CMD ["/app/bin/server"]
# Optional: Add healthcheck
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:4000/health || exit 1