towerops/k8s/base-image/Dockerfile
Graham McIntire 8f87d4bbab
feat: add custom minimal Debian base image build system
Created build system for minimal Debian 13 (Trixie) image with Erlang/OTP
and Elixir runtime pre-installed. This will speed up CI/CD builds by caching
the runtime environment.

Features:
- Multi-stage Dockerfile for minimal final image (~150-200 MB)
- Build script with automatic tagging (versioned, latest, dated)
- Update script for easy security patch rebuilds
- Makefile for common operations
- Comprehensive documentation (README + QUICKSTART)

Benefits:
- Faster CI/CD: Saves 30-60s per build (no apt-get install runtime deps)
- Smaller images: Only essential runtime packages included
- Security: Easy to rebuild weekly/monthly with latest patches
- Consistency: Same runtime across all environments

Usage:
  cd k8s/base-image
  make build    # Build the image
  make test     # Verify it works
  make push     # Push to registry

Then update k8s/Dockerfile to use the custom base image.

This replaces the previous Dockerfile.base approach with a more
comprehensive and maintainable build system.
2026-01-25 09:07:55 -06:00

94 lines
3.2 KiB
Docker

# Minimal Debian 13 (Trixie) with Erlang/OTP and Elixir runtime
# Built from scratch with only essential packages
#
# This image is designed to be rebuilt regularly to get latest security updates
ARG DEBIAN_VERSION=trixie-20251229-slim
ARG ERLANG_VERSION=28.3
ARG ELIXIR_VERSION=1.19.5
FROM docker.io/debian:${DEBIAN_VERSION} as builder
# Install build dependencies (will be removed in final image)
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
wget \
ca-certificates \
gnupg2 \
&& rm -rf /var/lib/apt/lists/*
# Add Erlang Solutions repository for latest Erlang/OTP
RUN wget -O- https://packages.erlang-solutions.com/ubuntu/erlang_solutions.asc | \
gpg --dearmor -o /usr/share/keyrings/erlang-solutions.gpg \
&& echo "deb [signed-by=/usr/share/keyrings/erlang-solutions.gpg] https://packages.erlang-solutions.com/debian trixie contrib" \
> /etc/apt/sources.list.d/erlang.list
# Install Erlang/OTP and Elixir
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
esl-erlang \
elixir \
&& rm -rf /var/lib/apt/lists/*
# Verify installations
RUN erl -eval 'erlang:display(erlang:system_info(otp_release)), halt().' -noshell
RUN elixir --version
# Final minimal runtime image
FROM docker.io/debian:${DEBIAN_VERSION}
LABEL maintainer="towerops"
LABEL description="Minimal Debian 13 with Erlang/OTP and Elixir runtime"
# Copy Erlang and Elixir from builder
COPY --from=builder /usr/lib/erlang /usr/lib/erlang
COPY --from=builder /usr/local/bin/elixir /usr/local/bin/elixir
COPY --from=builder /usr/local/bin/elixirc /usr/local/bin/elixirc
COPY --from=builder /usr/local/bin/iex /usr/local/bin/iex
COPY --from=builder /usr/local/bin/mix /usr/local/bin/mix
COPY --from=builder /usr/local/lib/elixir /usr/local/lib/elixir
# Install only essential runtime dependencies
# This is the absolute minimum needed for Erlang/Elixir + Phoenix apps
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get upgrade -y \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
# Erlang runtime dependencies
libssl3 \
libsctp1 \
libncurses6 \
libstdc++6 \
# System utilities
ca-certificates \
locales \
# Network utilities (minimal set)
iputils-ping \
iproute2 \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get clean
# Configure locale (required for proper string handling)
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
# Create symlinks for Erlang binaries
RUN ln -s /usr/lib/erlang/bin/erl /usr/local/bin/erl \
&& ln -s /usr/lib/erlang/bin/erlc /usr/local/bin/erlc \
&& ln -s /usr/lib/erlang/bin/escript /usr/local/bin/escript
# Add nobody user for security (already exists in Debian)
RUN mkdir -p /app && chown nobody:nogroup /app
WORKDIR /app
USER nobody
# Verify everything works
RUN erl -eval 'erlang:display(erlang:system_info(otp_release)), halt().' -noshell
RUN elixir --version
# Default command - override in application Dockerfile
CMD ["/bin/bash"]