# ────────────────────────────────────────────────────────────── # BanGUI — Project Makefile # # Compatible with both Docker Compose and Podman Compose. # Auto-detects which compose binary is available. # # Usage: # make up — start the debug stack # make down — stop the debug stack # make build — (re)build the backend image without starting # make clean — stop, remove all containers, volumes, and local images # make logs — tail logs for all debug services # make restart — restart the debug stack # make dev-ban-test — one-command smoke test of the ban pipeline # make e2e — run the Robot Framework E2E test suite # ────────────────────────────────────────────────────────────── COMPOSE_FILE := Docker/compose.debug.yml # Compose project name (matches `name:` in compose.debug.yml). PROJECT := bangui-dev # All named volumes declared in compose.debug.yml. # Compose prefixes them with the project name. DEV_VOLUMES := \ $(PROJECT)_bangui-dev-data \ $(PROJECT)_frontend-node-modules \ $(PROJECT)_fail2ban-dev-config \ $(PROJECT)_fail2ban-dev-run # Locally-built images (compose project name + service name). # Public images (fail2ban, node) are intentionally excluded. DEV_IMAGES := \ $(PROJECT)_backend # Detect available compose binary. COMPOSE := $(shell command -v podman-compose 2>/dev/null \ || echo "podman compose") # Env file in the project root. # Passed explicitly because docker compose v2 defaults to the compose file's # directory as the project directory, not the shell's cwd. ENV_FILE := .env COMPOSE_OPTS := --env-file $(ENV_FILE) -f $(COMPOSE_FILE) # Detect available container runtime (podman or docker). RUNTIME := $(shell command -v podman 2>/dev/null || echo "docker") .PHONY: up down build restart logs clean dev-ban-test e2e ensure-env ## Ensure .env exists with BANGUI_SESSION_SECRET set. ## Copies .env.example → .env on first run and auto-generates the secret. ensure-env: @if [ ! -f .env ]; then \ cp .env.example .env; \ python3 -c "\ import re, secrets; \ content = open('.env').read(); \ secret = secrets.token_hex(32); \ content = re.sub(r'(?m)^BANGUI_SESSION_SECRET=.*', 'BANGUI_SESSION_SECRET=' + secret, content); \ open('.env', 'w').write(content); \ print('Created .env with a generated BANGUI_SESSION_SECRET.')"; \ fi ## Start the debug stack (detached). ## Ensures log stub files exist so fail2ban can open them on first start. ## All output is logged to Docker/logs/make-up.log. up: ensure-env @mkdir -p Docker/logs @touch Docker/logs/auth.log $(COMPOSE) $(COMPOSE_OPTS) up -d 2>&1 | tee Docker/logs/make-up.log ## Stop the debug stack. down: ensure-env $(COMPOSE) $(COMPOSE_OPTS) down ## (Re)build the backend image without starting containers. build: ensure-env $(COMPOSE) $(COMPOSE_OPTS) build ## Restart the debug stack. restart: down up ## Tail logs for all debug services. logs: ensure-env $(COMPOSE) $(COMPOSE_OPTS) logs -f ## Stop containers, remove ALL debug volumes and locally-built images. ## The next 'make up' will rebuild images from scratch and start fresh. clean: ensure-env $(COMPOSE) $(COMPOSE_OPTS) down --remove-orphans $(RUNTIME) volume rm $(DEV_VOLUMES) 2>/dev/null || true $(RUNTIME) rmi $(DEV_IMAGES) 2>/dev/null || true rm -rf ./data @echo "All debug volumes, local images, and ./data removed. Run 'make up' to rebuild and start fresh." ## Run the Robot Framework E2E test suite. ## Requires: stack up (make up), BANGUI_SESSION_SECRET env var set. ## Installs: pip install -r e2e/requirements.txt && rfbrowser init e2e: down clean up @echo "Waiting 2 minutes for services to initialize..." @sleep 120 @echo "Waiting for stack to be healthy..." @timeout=120; \ until curl -sf http://localhost:8000/api/v1/health > /dev/null 2>&1; do \ sleep 5; timeout=$$((timeout-5)); \ if [ $$timeout -le 0 ]; then echo "Backend not healthy after 120s"; exit 1; fi; \ done pip install -r e2e/requirements.txt -q rfbrowser init robot --outputdir e2e/results e2e/tests/ ## One-command smoke test for the ban pipeline: ## 1. Start fail2ban, 2. write failure lines, 3. check ban status. dev-ban-test: ensure-env $(COMPOSE) $(COMPOSE_OPTS) up -d fail2ban sleep 5 bash Docker/simulate_failed_logins.sh sleep 3 bash Docker/check_ban_status.sh