Files
audio-engine-hub/Makefile
stephan 527f611061 feat: Integrate container registry support and Makefile enhancements
This commit integrates support for pushing and pulling Docker images from a container registry and enhances the Makefile for a more flexible development workflow.

Key changes include:

- **Container Registry Configuration:** Added  and  variables to the Makefile and updated  and  targets to correctly tag and push images to the configured registry.
- **Docker Compose Registry Integration:** Modified  to use the image from the registry by default instead of building locally.
- **Makefile Workflow Enhancements:**
    - Introduced a  target (Pulling image git.wlkns.org/stephan/audio-engine-hub:latest from registry...
docker pull git.wlkns.org/stephan/audio-engine-hub:latest) for explicitly downloading images from the registry.
    - Modified the  target (Starting development environment by pulling image from registry...
export IMAGE_NAME=audio-engine-hub && \
export REGISTRY=git.wlkns.org && \
export USERNAME=stephan && \
export TAG=latest && \
docker compose up -d) to use the registry image.
    - Added a  target (Starting development environment (local build) on port 8000...) for local development, which explicitly builds the image from source () before starting the service.
    - Updated  and GNU bash, Version 5.1.16(1)-release (x86_64-pc-linux-gnu)
Diese Shellkommandos sind intern definiert. Geben Sie »help« ein, um diese
Liste zu sehen. Geben Sie »help Name« ein, um die Beschreibung der Funktion
»Name« zu sehen. Geben Sie »info bash« ein, um die vollständige Dokumentation
zu sehen. Geben Sie »man -k« oder »info« ein, um detaillierte Beschreibungen
der Shellkommandos zu sehen.

Ein Stern (*) neben dem Namen kennzeichnet deaktivierte Kommandos.

 Jobbezeichnung [&]                                                         history [-c] [-d Offset] [n] oder history -anrw [Dateiname] oder histor>
 (( Ausdruck ))                                                             if Kommandos; then Kommandos; [ elif Kommandos; then Kommandos; ]... [ >
 . Dateiname [Argumente]                                                    jobs [-lnprs] [Jobbezeichnung ...] or jobs -x Kommando [Arg]
 :                                                                          kill [-s Signalname | -n Signalnummer | -Signalname] pid | jobspec ... >
 [ Argument... ]                                                            let Argument [Argument ...]
 [[ Ausdruck ]]                                                             local [Option] Name[=Wert] ...
 alias [-p] [Name[=Wert] ... ]                                              logout [n]
 bg [Jobbezeichnung ...]                                                    mapfile [-d Begrenzer] [-n Anzahl] [-O Quelle] [-s Anzahl] [-t] [-u fd]>
 bind [-lpsvPSVX] [-m Tastaturtabelle] [-f Dateiname] [-q Name] [-u Name]>  popd [-n] [+N | -N]
 break [n]                                                                  printf [-v var] Format [Argumente]
 builtin [Shell-Kommando [Argument ...]]                                    pushd [-n] [+N | -N | Verzeichnis]
 caller [Ausdruck]                                                          pwd [-LP]
 case Wort in [Muster [| Muster]...) Kommandos ;;]... esac                  read [-ers] [-a Feld] [-d Begrenzer] [-i Text] [-n Zeichenanzahl] [-N Z>
 cd [-L|[-P [-e]] [-@]] [Verzeichnis]                                       readarray [-d Begrenzer] [-n Anzahl] [-O Quelle] [-s Anzahl] [-t]      >
 command [-pVv] Kommando [Argument ...]                                     readonly [-aAf] [Name[=Wert] ...] oder readonly -p
 compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlis>  return [n]
 complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G globpa>  select Name [in Wortliste ... ;] do Kommandos; done
 compopt [-o|+o Option] [-DEI] [Name ...]                                   set [-abefhkmnptuvxBCHP] [-o Option] [--] [Argument ...]
 continue [n]                                                               shift [n]
 coproc [Name] Kommando [Umleitungen]                                       shopt [-pqsu] [-o] [Optionsname ...]
 declare [-aAfFgiIlnrtux] [-p] [Name[=Wert] …]                              source Dateiname [Argumente]
 dirs [-clpv] [+N] [-N]                                                     suspend [-f]
 disown [-h] [-ar] [Jobbezeichnung ... | pid ...]                           test [Ausdruck]
 echo [-neE] [Argument ...]                                                 time [-p] Pipeline
 enable [-a] [-dnps] [-f Dateiname] [Name ...]                              times
 eval [Argument ...]                                                        trap [-lp] [[Argument] Signalbezeichnung ...]
 exec [-cl] [-a Name] [Befehl [Argument …]] [Umleitung …]                   true
 exit [n]                                                                   type [-afptP] Name [Name ...]
 export [-fn] [Name[=Wert] ...] oder export -p                              typeset [-aAfFgiIlnrtux] [-p] Name[=Wert] …
 false                                                                      ulimit [-SHabcdefiklmnpqrstuvxPT] [Grenze]
 fc [-e Editor] [-lnr] [Anfang] [Ende] oder fc -s [Muster=Ersetzung] [Kom>  umask [-p] [-S] [Modus]
 fg [Jobbezeichnung]                                                        unalias [-a] Name [Name ...]
 for Name [in Wortliste ... ] ; do Kommandos; done                          unset [-f] [-v] [-n] [NAME ...]
 for (( Ausdruck1; Ausdruck2; Ausdruck3 )); do Kommandos; done              until Kommandos; do Kommandos; done
 function Name { Kommandos ; } oder Name () { Kommandos ; }                 variables - Namen und Bedeutung einiger Shell-Variablen
 getopts optstring name [arg ...]                                           wait [-fn] [-p var] [id ...]
 hash [-lr] [-p Pfadname] [-dt] [Name ...]                                  while Kommandos; do Kommandos; done
 help [-dms] [Muster ...]                                                   { Kommandos ; } targets accordingly.
- **Session Resume Update:** Updated  to document the container registry integration.
2025-12-04 22:42:38 +01:00

168 lines
5.5 KiB
Makefile

SHELL := /bin/bash
# --- Configuration ---
IMAGE_NAME := audio-engine-hub
TAG := latest
REGISTRY := git.wlkns.org
USERNAME := stephan
# Default internal application port
PORT := 8000
# --- Port Checking Functions ---
# Function to check if required Traefik ports are free
# Exits if any are busy, does not suggest alternatives.
define check_traefik_ports_free
check_traefik_ports_free_func() { \
echo "Checking if Traefik ports ($(TRAEFIK_WEB_PORT), $(TRAEFIK_DASHBOARD_PORT)) are free..." >&2; \
local busy_ports=""; \
if ss -tulnp | grep ":$(TRAEFIK_WEB_PORT) " > /dev/null; then \
busy_ports="$$busy_ports $(TRAEFIK_WEB_PORT)"; \
fi; \
if ss -tulnp | grep ":$(TRAEFIK_DASHBOARD_PORT) " > /dev/null; then \
busy_ports="$$busy_ports $(TRAEFIK_DASHBOARD_PORT)"; \
fi; \
if [ -n "$$busy_ports" ]; then \
echo "ERROR: The following Traefik ports are already in use: $$busy_ports. Please free them or stop Traefik if already running." >&2; \
exit 1; \
fi; \
echo "Traefik ports are free." >&2; \
} ; \
check_traefik_ports_free_func
endef
# --- Docker Commands ---
.PHONY: build
build:
@echo "Building Docker image: $(IMAGE_NAME):$(TAG)"
docker build -t $(IMAGE_NAME):$(TAG) .
.PHONY: run
run:
@APP_PORT=$$(bash -c 'port=$${PORT:-8000}; while ss -tulnp | grep -q :$$port; do echo "Port $$port is busy. Checking next..." >&2; ((port++)); done; echo $$port'); \
echo "Using host port $$APP_PORT for single app container" && \
docker run -d -p $$APP_PORT:$(PORT) --name $(IMAGE_NAME) $(IMAGE_NAME):$(TAG)
.PHONY: stop
stop:
@echo "Stopping Docker containers..."
docker compose stop || true
docker compose rm -f || true
docker stop $(IMAGE_NAME) || true
docker rm $(IMAGE_NAME) || true
.PHONY: logs
logs:
@echo "Showing logs for container: $(if $(CONTAINER),$(CONTAINER),$(IMAGE_NAME)_app)"
docker logs -f $(if $(CONTAINER),$(CONTAINER),$(IMAGE_NAME)_app)
.PHONY: shell
shell:
@echo "Accessing shell in container: $(if $(CONTAINER),$(CONTAINER),$(IMAGE_NAME)_app)"
docker exec -it $(if $(CONTAINER),$(CONTAINER),$(IMAGE_NAME)_app) /bin/bash
# --- Docker Compose Commands ---
.PHONY: up
up:
@echo "Starting development environment by pulling image from registry..."
export IMAGE_NAME=$(IMAGE_NAME) && \
export REGISTRY=$(REGISTRY) && \
export USERNAME=$(USERNAME) && \
export TAG=$(TAG) && \
docker compose up -d
.PHONY: dev-up
dev-up:
@APP_PORT=$$(bash -c 'port=$${PORT:-8000}; while ss -tulnp | grep -q :$$port; do echo "Port $$port is busy. Checking next..." >&2; ((port++)); done; echo $$port'); \
echo "Starting development environment (local build) on port $$APP_PORT..."; \
export IMAGE_NAME=$(IMAGE_NAME) && \
export REGISTRY=$(REGISTRY) && \
export USERNAME=$(USERNAME) && \
export TAG=$(TAG) && \
APP_PORT=$$APP_PORT docker compose up --build -d
.PHONY: down
down:
@echo "Stopping development environment with Docker Compose..."
export IMAGE_NAME=$(IMAGE_NAME) && \
export REGISTRY=$(REGISTRY) && \
export USERNAME=$(USERNAME) && \
export TAG=$(TAG) && \
docker compose down
# --- Image Management ---
.PHONY: pull
pull:
@echo "Pulling image $(REGISTRY)/$(USERNAME)/$(IMAGE_NAME):$(TAG) from registry..."
docker pull $(REGISTRY)/$(USERNAME)/$(IMAGE_NAME):$(TAG)
.PHONY: tag
tag:
@echo "Tagging image $(IMAGE_NAME):$(TAG) as $(REGISTRY)/$(USERNAME)/$(IMAGE_NAME):$(TAG)"
docker tag $(IMAGE_NAME):$(TAG) $(REGISTRY)/$(USERNAME)/$(IMAGE_NAME):$(TAG)
.PHONY: push
push: build tag
@echo "Pushing image $(REGISTRY)/$(USERNAME)/$(IMAGE_NAME):$(TAG) to registry..."
docker push $(REGISTRY)/$(USERNAME)/$(IMAGE_NAME):$(TAG)
.PHONY: test
test:
@if [ -d ".venv" ]; then \
echo "Activating virtual environment..."; \
. .venv/bin/activate; \
fi; \
export PYTHONPATH=$(PWD); \
echo "Running tests with coverage..." && \
pytest --cov=. app/ tests/
.PHONY: health-check
health-check:
@echo "Running health check on running container..."
@CONTAINER_ID=$$(docker compose ps -q app); \
if [ -z "$$CONTAINER_ID" ]; then \
echo "ERROR: App container is not running. Please run 'make up' first." >&2; \
exit 1; \
fi; \
HOST_PORT=$$(docker port $$CONTAINER_ID 8000 | cut -d: -f2); \
if [ -z "$$HOST_PORT" ]; then \
echo "ERROR: Could not determine host port for the app container." >&2; \
exit 1; \
fi; \
echo "App container is running on port $$HOST_PORT."; \
echo "Waiting for app to initialize..."; \
sleep 2; \
curl -s http://localhost:$$HOST_PORT/health | ./scripts/health_check.py
# --- Cleanup ---
.PHONY: clean
clean:
@echo "Cleaning up stopped containers and dangling images..."
docker container prune -f
docker image prune -f
.PHONY: help
help:
@echo "Available commands:"
@echo " build - Build the Docker image"
@echo " run - Run the Docker container (single app, no Traefik)"
@echo " stop - Stop and remove the Docker container"
@echo " logs - Follow the logs of the container"
@echo " shell - Get a shell inside the running container"
@echo " up - Start the dev environment by pulling image from registry"
@echo " dev-up - Start the dev environment by building image locally"
@echo " down - Stop the dev environment with docker-compose"
@echo " pull - Pull the Docker image from the registry"
@echo " tag - Tag the image for a registry"
@echo " push - Push the image to a registry (after tagging)"
@echo " test - Run the pytest test suite"
@echo " health-check - Run a sanity check on the deployed container"
@echo " clean - Clean up unused containers and images"
@echo " help - Show this help message"
.DEFAULT_GOAL := help