Set up mix_gleam archive, gleam_stdlib, and gleeunit deps. Add Gleam
compiler to all Dockerfiles, CI workflows, nix shell, and .tool-versions.
Rewrite Numeric, QueryHelpers, and URLValidator from Elixir to Gleam with
full ExUnit test coverage. Update all callers to use the Gleam modules
directly via :towerops@module syntax. Remove duplicate sanitize_like/1
private functions in snmp.ex and trace.ex.
Reviewed-on: graham/towerops-web#98
Instead of installing system packages and tools on every deploy, we now
have two base images that pre-bake all the slow setup steps.
Base Images Created:
1. elixir-builder:latest - Builder stage base
- hexpm/elixir with build-essential and git pre-installed
- hex and rebar pre-installed
- Saves ~40 seconds per deploy
2. debian-runtime:latest - Runtime stage base
- Debian with all runtime packages pre-installed
- Locale pre-configured (en_US.UTF-8)
- /app directory pre-created
- Saves ~60 seconds per deploy
Main Dockerfile Changes:
- Use elixir-builder:latest instead of hexpm/elixir
- Use debian-runtime:latest instead of debian:trixie-slim
- Remove apt-get install steps (now in base images)
- Remove hex/rebar install (now in builder base)
- Remove locale setup (now in runtime base)
Build System:
- build.sh builds both images with podman/docker auto-detect
- Pushes to both GitLab registry and Docker Hub
- Makefile targets for build/test/push/clean
Total Time Saved Per Deploy: ~100 seconds (1m40s)
Benefits:
- Faster CI/CD builds (no repeated apt-get install)
- Faster local development builds
- Consistent build environment across all deploys
- Security updates centralized in base image rebuilds
The hexpm images install Erlang and Elixir in /usr/local instead of /usr/lib.
Changes:
- Copy from /usr/local/lib/erlang instead of /usr/lib/erlang
- Copy all Erlang/Elixir binaries from /usr/local/bin
- Remove manual symlink creation (binaries already exist)
- Binaries are symlinks to ../lib/erlang/bin and ../lib/elixir/bin
The Erlang Solutions APT repository was experiencing 504 Gateway Timeout
errors during builds, making the image build process unreliable.
Changes:
- Use official hexpm/elixir Docker image as builder stage
- More reliable (official Docker Hub images)
- Faster builds (pre-built binaries, no package installation)
- Still produces minimal runtime-only final image
- Updated documentation to reflect new approach
Benefits:
- No dependency on erlang-solutions CDN availability
- Faster build times (no apt-get install of large packages)
- Same minimal final image size (~150-200 MB)
- Easier to specify exact Erlang/Elixir versions
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.