Makefile

# Makefile for homelab-compose.
#
# I keep the convenience targets here instead of scattered in scripts/.
# Anything that needs more than a couple of lines lives in scripts/ and
# gets called from a target below. See mercemay.top/src/homelab-compose/
# for the story behind each target.

SHELL := /usr/bin/env bash
.ONESHELL:
.SHELLFLAGS := -eu -o pipefail -c

COMPOSE        := docker compose
STACK_DIRS     := $(wildcard stacks/*/compose.yml)
STACK_NAMES    := $(patsubst stacks/%/compose.yml,%,$(STACK_DIRS))

.PHONY: help up down pull restart logs health backup prune upgrade check

help: ## Show this help
	@awk 'BEGIN {FS = ":.*##"; printf "Targets:\n"} /^[a-zA-Z0-9_.-]+:.*##/ {printf "  %-12s %s\n", $$1, $$2}' $(MAKEFILE_LIST)

up: ## Bring every stack up in detached mode
	@for f in $(STACK_DIRS); do \
	  echo "--> up $$f"; \
	  $(COMPOSE) -f $$f up -d; \
	done

down: ## Stop every stack but keep volumes
	@for f in $(STACK_DIRS); do \
	  echo "--> down $$f"; \
	  $(COMPOSE) -f $$f down; \
	done

pull: ## docker compose pull for every stack
	@for f in $(STACK_DIRS); do $(COMPOSE) -f $$f pull --quiet; done

restart: ## Recreate every stack (pull + up -d)
	@$(MAKE) pull
	@$(MAKE) up

logs: ## Tail logs for a single stack: make logs STACK=media
	@test -n "$(STACK)" || (echo "usage: make logs STACK=<name>"; exit 2)
	$(COMPOSE) -f stacks/$(STACK)/compose.yml logs -f --tail=200

health: ## Run scripts/health-check.sh
	scripts/health-check.sh

backup: ## Run scripts/backup.sh
	scripts/backup.sh

prune: ## Safe clean of dangling images/containers/cache
	scripts/prune.sh

upgrade: ## Pull and recreate in rolling order
	scripts/upgrade.sh

check: ## Validate every compose file without starting anything
	@for f in $(STACK_DIRS); do \
	  echo "--> validate $$f"; \
	  $(COMPOSE) -f $$f config -q; \
	done