towerops/k8s/base-image/Makefile
Graham McIntire edd64479df
feat: create builder and runtime base images for faster deploys
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
2026-01-25 09:29:22 -06:00

87 lines
4.2 KiB
Makefile

.PHONY: build push test update clean help
# Detect container engine (podman or docker)
CONTAINER_CMD := $(shell command -v podman 2>/dev/null || command -v docker 2>/dev/null)
REGISTRY ?= registry.gitlab.com/towerops/towerops
DOCKERHUB_REGISTRY ?= docker.io/gmcintire
BUILDER_IMAGE_NAME ?= elixir-builder
RUNTIME_IMAGE_NAME ?= debian-runtime
ELIXIR_VERSION ?= 1.19.4
OTP_VERSION ?= 28.3
DEBIAN_VERSION ?= trixie-20251229-slim
TAG ?= $(ELIXIR_VERSION)-erlang-$(OTP_VERSION)-debian-$(DEBIAN_VERSION)
help: ## Show this help message
@echo "Available targets:"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}'
build: ## Build the base image with latest packages
@chmod +x build.sh
@./build.sh
update: build ## Alias for build (rebuilds with latest packages)
test: ## Test the built images
@echo "Testing builder image..."
@$(CONTAINER_CMD) run --rm $(REGISTRY)/$(BUILDER_IMAGE_NAME):latest mix --version
@echo "Testing runtime image..."
@$(CONTAINER_CMD) run --rm $(REGISTRY)/$(RUNTIME_IMAGE_NAME):latest locale | grep "en_US.UTF-8"
@echo "✅ All tests passed!"
push: ## Push images to GitLab and Docker Hub
@echo "Pushing builder image to GitLab registry..."
@$(CONTAINER_CMD) push $(REGISTRY)/$(BUILDER_IMAGE_NAME):$(TAG)
@$(CONTAINER_CMD) push $(REGISTRY)/$(BUILDER_IMAGE_NAME):latest
@echo "Pushing runtime image to GitLab registry..."
@$(CONTAINER_CMD) push $(REGISTRY)/$(RUNTIME_IMAGE_NAME):$(TAG)
@$(CONTAINER_CMD) push $(REGISTRY)/$(RUNTIME_IMAGE_NAME):latest
@echo "Tagging for Docker Hub..."
@$(CONTAINER_CMD) tag $(REGISTRY)/$(BUILDER_IMAGE_NAME):$(TAG) $(DOCKERHUB_REGISTRY)/$(BUILDER_IMAGE_NAME):$(TAG)
@$(CONTAINER_CMD) tag $(REGISTRY)/$(BUILDER_IMAGE_NAME):latest $(DOCKERHUB_REGISTRY)/$(BUILDER_IMAGE_NAME):latest
@$(CONTAINER_CMD) tag $(REGISTRY)/$(RUNTIME_IMAGE_NAME):$(TAG) $(DOCKERHUB_REGISTRY)/$(RUNTIME_IMAGE_NAME):$(TAG)
@$(CONTAINER_CMD) tag $(REGISTRY)/$(RUNTIME_IMAGE_NAME):latest $(DOCKERHUB_REGISTRY)/$(RUNTIME_IMAGE_NAME):latest
@echo "Pushing to Docker Hub..."
@$(CONTAINER_CMD) push $(DOCKERHUB_REGISTRY)/$(BUILDER_IMAGE_NAME):$(TAG)
@$(CONTAINER_CMD) push $(DOCKERHUB_REGISTRY)/$(BUILDER_IMAGE_NAME):latest
@$(CONTAINER_CMD) push $(DOCKERHUB_REGISTRY)/$(RUNTIME_IMAGE_NAME):$(TAG)
@$(CONTAINER_CMD) push $(DOCKERHUB_REGISTRY)/$(RUNTIME_IMAGE_NAME):latest
pull: ## Pull latest images from registry
@$(CONTAINER_CMD) pull $(REGISTRY)/$(BUILDER_IMAGE_NAME):latest
@$(CONTAINER_CMD) pull $(REGISTRY)/$(RUNTIME_IMAGE_NAME):latest
inspect: ## Show image details (size, layers, labels)
@echo "Builder image size:"
@$(CONTAINER_CMD) images $(REGISTRY)/$(BUILDER_IMAGE_NAME):latest --format "table {{.Repository}}:{{.Tag}}\t{{.Size}}\t{{.CreatedAt}}"
@echo ""
@echo "Runtime image size:"
@$(CONTAINER_CMD) images $(REGISTRY)/$(RUNTIME_IMAGE_NAME):latest --format "table {{.Repository}}:{{.Tag}}\t{{.Size}}\t{{.CreatedAt}}"
@echo ""
@echo "Builder image labels:"
@$(CONTAINER_CMD) inspect $(REGISTRY)/$(BUILDER_IMAGE_NAME):latest --format '{{range $$k, $$v := .Config.Labels}}{{$$k}}={{$$v}}{{println}}{{end}}'
@echo ""
@echo "Runtime image labels:"
@$(CONTAINER_CMD) inspect $(REGISTRY)/$(RUNTIME_IMAGE_NAME):latest --format '{{range $$k, $$v := .Config.Labels}}{{$$k}}={{$$v}}{{println}}{{end}}'
clean: ## Remove local images
@$(CONTAINER_CMD) rmi $(REGISTRY)/$(BUILDER_IMAGE_NAME):$(TAG) || true
@$(CONTAINER_CMD) rmi $(REGISTRY)/$(BUILDER_IMAGE_NAME):latest || true
@$(CONTAINER_CMD) rmi $(REGISTRY)/$(RUNTIME_IMAGE_NAME):$(TAG) || true
@$(CONTAINER_CMD) rmi $(REGISTRY)/$(RUNTIME_IMAGE_NAME):latest || true
@$(CONTAINER_CMD) rmi $(DOCKERHUB_REGISTRY)/$(BUILDER_IMAGE_NAME):$(TAG) || true
@$(CONTAINER_CMD) rmi $(DOCKERHUB_REGISTRY)/$(BUILDER_IMAGE_NAME):latest || true
@$(CONTAINER_CMD) rmi $(DOCKERHUB_REGISTRY)/$(RUNTIME_IMAGE_NAME):$(TAG) || true
@$(CONTAINER_CMD) rmi $(DOCKERHUB_REGISTRY)/$(RUNTIME_IMAGE_NAME):latest || true
@echo "✅ Cleaned local images"
login: ## Login to GitLab container registry
@$(CONTAINER_CMD) login registry.gitlab.com
login-dockerhub: ## Login to Docker Hub
@$(CONTAINER_CMD) login docker.io
# Quick commands
b: build ## Shortcut for build
t: test ## Shortcut for test
p: push ## Shortcut for push