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 --no-cache -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 # --- Test Environment Commands --- .PHONY: kokoro-up kokoro-up: @echo "Starting Kokoro test environment on port 8001..." export IMAGE_NAME=$(IMAGE_NAME) && \ export REGISTRY=$(REGISTRY) && \ export USERNAME=$(USERNAME) && \ export TAG=dev-kokoro-v5 && \ docker compose -f docker-compose.kokoro-test.yml up -d .PHONY: kokoro-down kokoro-down: @echo "Stopping Kokoro test environment..." export IMAGE_NAME=$(IMAGE_NAME) && \ export REGISTRY=$(REGISTRY) && \ export USERNAME=$(USERNAME) && \ export TAG=dev-kokoro-v5 && \ docker compose -f docker-compose.kokoro-test.yml down .PHONY: kokoro-logs kokoro-logs: @echo "Showing logs for Kokoro test container..." docker logs -f audio-engine-hub_kokoro_test .PHONY: xtts-up xtts-up: @echo "Starting XTTS test environment on port 8002..." export IMAGE_NAME=$(IMAGE_NAME) && \ export REGISTRY=$(REGISTRY) && \ export USERNAME=$(USERNAME) && \ export TAG=dev-xtts && \ docker compose -f docker-compose.xtts-test.yml up -d .PHONY: xtts-down xtts-down: @echo "Stopping XTTS test environment..." export IMAGE_NAME=$(IMAGE_NAME) && \ export REGISTRY=$(REGISTRY) && \ export USERNAME=$(USERNAME) && \ export TAG=dev-xtts && \ docker compose -f docker-compose.xtts-test.yml down .PHONY: xtts-logs xtts-logs: @echo "Showing logs for XTTS test container..." docker logs -f audio-engine-hub_xtts_test # --- 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) # --- Tagged Image Management --- .PHONY: build-kokoro build-kokoro: @echo "Building Kokoro test image: $(IMAGE_NAME):dev-kokoro-v5" docker build --no-cache -t $(IMAGE_NAME):dev-kokoro-v5 . docker tag $(IMAGE_NAME):dev-kokoro-v5 $(REGISTRY)/$(USERNAME)/$(IMAGE_NAME):dev-kokoro-v5 .PHONY: push-kokoro push-kokoro: build-kokoro @echo "Pushing Kokoro test image to registry..." docker push $(REGISTRY)/$(USERNAME)/$(IMAGE_NAME):dev-kokoro-v5 .PHONY: pull-kokoro pull-kokoro: @echo "Pulling Kokoro test image from registry..." docker pull $(REGISTRY)/$(USERNAME)/$(IMAGE_NAME):dev-kokoro-v5 .PHONY: build-xtts build-xtts: @echo "Building XTTS test image: $(IMAGE_NAME):dev-xtts" docker build --no-cache -t $(IMAGE_NAME):dev-xtts . docker tag $(IMAGE_NAME):dev-xtts $(REGISTRY)/$(USERNAME)/$(IMAGE_NAME):dev-xtts .PHONY: push-xtts push-xtts: build-xtts @echo "Pushing XTTS test image to registry..." docker push $(REGISTRY)/$(USERNAME)/$(IMAGE_NAME):dev-xtts .PHONY: pull-xtts pull-xtts: @echo "Pulling XTTS test image from registry..." docker pull $(REGISTRY)/$(USERNAME)/$(IMAGE_NAME):dev-xtts .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 "" @echo "Main Deployment:" @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 "" @echo "Test Environments:" @echo " kokoro-up - Start Kokoro test environment (port 8001)" @echo " kokoro-down - Stop Kokoro test environment" @echo " kokoro-logs - View Kokoro test container logs" @echo " xtts-up - Start XTTS test environment (port 8002)" @echo " xtts-down - Stop XTTS test environment" @echo " xtts-logs - View XTTS test container logs" @echo "" @echo "Image Management (main 'latest' tag):" @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 "" @echo "Image Management (test tags):" @echo " build-kokoro - Build Kokoro test image (dev-kokoro-v5 tag)" @echo " push-kokoro - Build and push Kokoro test image to registry" @echo " pull-kokoro - Pull Kokoro test image from registry" @echo " build-xtts - Build XTTS test image (dev-xtts tag)" @echo " push-xtts - Build and push XTTS test image to registry" @echo " pull-xtts - Pull XTTS test image from registry" @echo "" @echo "Testing & Maintenance:" @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