homelab-blueprint/Makefile
Brian Pooe 73ff919b9f feat(forgejo): remove gitea-mirror, all repos now first-class
GitHub mirroring is no longer needed now that Forgejo is the primary
remote. Drops the gitea-mirror service, its volume, env vars, Caddy
site, and firewall rule; docs updated to match.
2026-07-19 13:21:05 +02:00

170 lines
6.3 KiB
Makefile

# Homelab Blueprint Makefile
.PHONY: help check-env status deploy-caddy deploy-ha deploy-arr deploy-immich deploy-dns deploy-postgres deploy-gramps deploy-beszel deploy-beszel-hub deploy-proxy deploy-youtarr deploy-bento-pdf deploy-it-tools deploy-paperless deploy-vaultwarden deploy-koffan deploy-forgejo
# Default shell
SHELL := /bin/bash
# Configuration
ENV_FILE ?= .env
STACKS_DIR := docker-compose-files
SUBSTITUTE_SCRIPT := ./substitute_env.sh
help:
@echo "Homelab Blueprint Management"
@echo ""
@echo "Usage: make <target>"
@echo ""
@echo "Deploy Targets:"
@echo " deploy-caddy - Deploy Caddy Reverse Proxy"
@echo " deploy-ha - Deploy Home Assistant (uses setup script)"
@echo " deploy-arr - Deploy Arr Stack (Media Management)"
@echo " deploy-immich - Deploy Immich (Photos)"
@echo " deploy-dns - Deploy Technitium DNS"
@echo " deploy-postgres - Deploy PostgreSQL"
@echo " deploy-gramps - Deploy Gramps Web"
@echo " deploy-beszel - Deploy Beszel Agent"
@echo " deploy-beszel-hub - Deploy Beszel Hub (dashboard)"
@echo " deploy-proxy - Deploy Beszel Socket Proxy"
@echo " deploy-youtarr - Deploy Youtarr"
@echo " deploy-bento-pdf - Deploy BentoPDF"
@echo " deploy-it-tools - Deploy IT-Tools"
@echo " deploy-paperless - Deploy Paperless-ngx"
@echo " deploy-vaultwarden - Deploy Vaultwarden"
@echo " deploy-koffan - Deploy Koffan (grocery list)"
@echo " deploy-forgejo - Deploy Forgejo (self-hosted Git)"
@echo ""
@echo "Utility Targets:"
@echo " status - Show status of all deployed stacks"
@echo " check-env - Validate .env file against templates"
@echo " ip-check - Check IP leak protection for VPN containers"
@echo " clean - Remove generated docker-compose.*.yml files"
check-env:
@target_dir=$$( [ -n "$(STACK)" ] && echo "$(STACKS_DIR)/$(STACK)" || echo "$(STACKS_DIR)/*" ); \
for dir in $$target_dir; do \
if [ -d "$$dir" ]; then \
stack=$$(basename $$dir); \
local_env="$$dir/.env"; \
placeholders=$$(find "$$dir" -type f \( -name '*template*' -o -name '*.yaml' -o -name '*.yml' \) -print0 | \
xargs -0 awk '!/^[[:space:]]*#/ { while (match($$0, /\{\{[A-Za-z_][A-Za-z0-9_]*\}\}/)) { print substr($$0, RSTART + 2, RLENGTH - 4); $$0 = substr($$0, RSTART + RLENGTH) } }' | \
sort -u || true); \
if [ -n "$$placeholders" ]; then \
echo "Validating environment for: $$stack"; \
ERR=0; \
for var in $$placeholders; do \
if ! grep -qE "^$${var}=" $(ENV_FILE) 2>/dev/null && ! grep -qE "^$${var}=" "$$local_env" 2>/dev/null; then \
echo " [MISSING] $$var"; \
ERR=1; \
fi; \
done; \
if [ $$ERR -eq 1 ]; then echo "Error: Missing variables for $$stack. Check your .env files."; exit 1; fi; \
fi; \
fi; \
done
status:
@echo "--- Stack Status ---"
@for f in docker-compose.*.yml; do \
if [ -f "$$f" ]; then \
echo "Stack: $$f"; \
docker compose -f "$$f" ps; \
echo ""; \
fi \
done
ip-check:
@test -x ./ipfconfig || { echo "Error: ipfconfig script not found or not executable." >&2; exit 1; }
@./ipfconfig
clean:
@echo "Removing generated compose files..."
@rm -f docker-compose.*.yml
# Individual Stack Deployments
#
# deploy_stack(stack-dir, compose-suffix) - shared recipe for the common case:
# check-env -> substitute template -> docker compose up -d
define deploy_stack
@$(MAKE) check-env STACK=$(1)
@echo "Deploying $(1)..."
@$(SUBSTITUTE_SCRIPT) $(STACKS_DIR)/$(1)/template.yaml docker-compose.$(2).yml $(ENV_FILE) $(STACKS_DIR)/$(1)/.env
@docker compose -f docker-compose.$(2).yml up -d
endef
# Caddy is special: also renders the Caddyfile and forces an image rebuild.
deploy-caddy:
@$(MAKE) check-env STACK=caddy
@echo "Deploying Caddy..."
@$(SUBSTITUTE_SCRIPT) $(STACKS_DIR)/caddy/Caddyfile_template $(STACKS_DIR)/caddy/Caddyfile $(ENV_FILE) $(STACKS_DIR)/caddy/.env
@$(SUBSTITUTE_SCRIPT) $(STACKS_DIR)/caddy/template.yaml docker-compose.caddy.yml $(ENV_FILE) $(STACKS_DIR)/caddy/.env
@chmod 644 $(STACKS_DIR)/caddy/Caddyfile
@docker compose -f docker-compose.caddy.yml up -d --build
# HA uses an external setup script instead of substitute_env.sh.
deploy-ha:
@test -x ./setup-homeassistant.sh || { echo "Error: setup-homeassistant.sh not found or not executable." >&2; exit 1; }
@$(MAKE) check-env STACK=homeassistant
@echo "Deploying Home Assistant..."
@./setup-homeassistant.sh
@docker compose -f docker-compose.homeassistant.yml up -d
deploy-arr:
$(call deploy_stack,arr-stack,arr-stack)
deploy-immich:
$(call deploy_stack,immich,immich)
deploy-dns:
$(call deploy_stack,technitium,technitium)
deploy-postgres:
$(call deploy_stack,postgres,postgres)
deploy-gramps:
@$(MAKE) check-env STACK=gramps-web
@echo "Deploying gramps-web..."
@mkdir -p gramps_config
@$(SUBSTITUTE_SCRIPT) $(STACKS_DIR)/gramps-web/config/config_template.cfg gramps_config/config.cfg $(ENV_FILE) $(STACKS_DIR)/gramps-web/.env
@$(SUBSTITUTE_SCRIPT) $(STACKS_DIR)/gramps-web/template.yaml docker-compose.gramps.yml $(ENV_FILE) $(STACKS_DIR)/gramps-web/.env
@docker compose -f docker-compose.gramps.yml up -d
deploy-beszel:
$(call deploy_stack,beszel-agent,beszel)
deploy-beszel-hub:
$(call deploy_stack,beszel-hub,beszel-hub)
deploy-bento-pdf:
$(call deploy_stack,bento-pdf,bento-pdf)
deploy-it-tools:
$(call deploy_stack,it-tools,it-tools)
deploy-paperless:
$(call deploy_stack,paperless-ngx,paperless)
deploy-vaultwarden:
$(call deploy_stack,vaultwarden,vaultwarden)
deploy-koffan:
$(call deploy_stack,koffan,koffan)
deploy-proxy:
$(call deploy_stack,socket-proxy,proxy)
deploy-forgejo:
$(call deploy_stack,forgejo,forgejo)
deploy-youtarr:
$(call deploy_stack,youtarr,youtarr)
reload-caddy:
@docker compose -f docker-compose.caddy.yml ps --status running --services 2>/dev/null | grep -q '^caddy$$' \
|| { echo "Error: Caddy container is not running. Run 'make deploy-caddy' first." >&2; exit 1; }
@$(MAKE) check-env STACK=caddy
@echo "Performing zero-downtime Caddy reload..."
@$(SUBSTITUTE_SCRIPT) $(STACKS_DIR)/caddy/Caddyfile_template $(STACKS_DIR)/caddy/Caddyfile $(ENV_FILE) $(STACKS_DIR)/caddy/.env
@chmod 644 $(STACKS_DIR)/caddy/Caddyfile
@docker compose -f docker-compose.caddy.yml exec caddy caddy validate --config /etc/caddy/Caddyfile
@docker compose -f docker-compose.caddy.yml exec caddy caddy reload --config /etc/caddy/Caddyfile