Add Makefile and unify stack management

This commit is contained in:
Brian Pooe 2026-06-17 18:57:05 +02:00
parent 78f42fc7ca
commit c13af8f98f
3 changed files with 169 additions and 23 deletions

108
Makefile Normal file
View file

@ -0,0 +1,108 @@
# Homelab Blueprint Makefile
.PHONY: help check-env status logs-caddy deploy-caddy deploy-ha deploy-arr deploy-immich deploy-dns deploy-vault deploy-postgres deploy-gramps deploy-beszel deploy-proxy
# 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-vault - Deploy HashiCorp Vault"
@echo " deploy-postgres - Deploy PostgreSQL"
@echo " deploy-gramps - Deploy Gramps Web"
@echo " deploy-beszel - Deploy Beszel Agent"
@echo " deploy-proxy - Deploy Beszel Socket Proxy"
@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:
@if [ ! -f $(ENV_FILE) ]; then echo "Error: $(ENV_FILE) not found. Copy .env.sample first."; exit 1; fi
@echo "Validating environment variables..."
@MISSING=$$(grep -roE '\{\{[A-Za-z_][A-Za-z0-9_]*\}\}' $(STACKS_DIR)/ | cut -d: -f2 | sort -u | sed 's/{{//;s/}}//' | while read -r var; do \
if ! grep -qE "^$${var}=" $(ENV_FILE); then echo "$$var"; fi; \
done); \
if [ -n "$$MISSING" ]; then \
echo "Warning: The following variables are missing from $(ENV_FILE) (and have no defaults in templates):"; \
echo "$$MISSING"; \
else \
echo "Success: All template variables found in $(ENV_FILE)"; \
fi
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:
@./ipfconfig
clean:
@echo "Removing generated compose files..."
@rm -f docker-compose.*.yml
# Individual Stack Deployments
deploy-caddy:
@$(SUBSTITUTE_SCRIPT) $(STACKS_DIR)/caddy/Caddyfile_template $(STACKS_DIR)/caddy/Caddyfile $(ENV_FILE)
@$(SUBSTITUTE_SCRIPT) $(STACKS_DIR)/caddy/template.yaml docker-compose.caddy.yml $(ENV_FILE)
@chmod 644 $(STACKS_DIR)/caddy/Caddyfile
@docker compose -f docker-compose.caddy.yml up -d --build
deploy-ha:
@./setup-homeassistant.sh
deploy-arr:
@$(SUBSTITUTE_SCRIPT) $(STACKS_DIR)/arr-stack/template.yaml docker-compose.arr-stack.yml $(ENV_FILE)
@docker compose -f docker-compose.arr-stack.yml config --quiet
@docker compose -f docker-compose.arr-stack.yml up -d
deploy-immich:
@$(SUBSTITUTE_SCRIPT) $(STACKS_DIR)/immich/template.yaml docker-compose.immich.yml $(ENV_FILE)
@docker compose -f docker-compose.immich.yml up -d
deploy-dns:
@$(SUBSTITUTE_SCRIPT) $(STACKS_DIR)/technitium/template.yaml docker-compose.technitium.yml $(ENV_FILE)
@docker compose -f docker-compose.technitium.yml up -d
deploy-vault:
@$(SUBSTITUTE_SCRIPT) $(STACKS_DIR)/vault/template.yaml docker-compose.vault.yml $(ENV_FILE)
@docker compose -f docker-compose.vault.yml up -d
deploy-postgres:
@$(SUBSTITUTE_SCRIPT) $(STACKS_DIR)/postgres/template.yaml docker-compose.postgres.yml $(ENV_FILE)
@docker compose -f docker-compose.postgres.yml up -d
deploy-gramps:
@$(SUBSTITUTE_SCRIPT) $(STACKS_DIR)/gramps-web/template.yaml docker-compose.gramps.yml $(ENV_FILE)
@docker compose -f docker-compose.gramps.yml up -d
deploy-beszel:
@$(SUBSTITUTE_SCRIPT) $(STACKS_DIR)/beszel-agent/template.yaml docker-compose.beszel.yml $(ENV_FILE)
@docker compose -f docker-compose.beszel.yml up -d
deploy-proxy:
@$(SUBSTITUTE_SCRIPT) $(STACKS_DIR)/socket-proxy/template.yaml docker-compose.proxy.yml $(ENV_FILE)
@docker compose -f docker-compose.proxy.yml up -d

View file

@ -4,15 +4,19 @@ Docker Compose templates and deployment guides for self-hosted services.
## Quick Start
Run repository commands from the project root:
1. Copy the sample environment file:
```bash
cp -n .env.sample .env
```
2. Configure `.env` with your values.
3. Use the `Makefile` to deploy a stack:
```bash
make help # See all available commands
make check-env # Validate your .env file
make deploy-caddy # Deploy the reverse proxy
```
```bash
cp -n .env.sample .env
```
Configure `.env`, then follow the README for the stack you want to deploy. Each
guide explains appdata placement, template rendering, startup, verification,
networking, troubleshooting, and backup.
Each stack guide in `docker-compose-files/<stack>/README.md` explains appdata placement, rendering, and networking.
## Stacks
@ -29,9 +33,27 @@ networking, troubleshooting, and backup.
| [Technitium DNS](docker-compose-files/technitium/README.md) | DNS server and ad blocking |
| [Vault](docker-compose-files/vault/README.md) | HashiCorp Vault secrets management |
## Management
The repository includes a `Makefile` to unify management of all stacks.
| Command | Description |
|---|---|
| `make check-env` | Validates `.env` against all placeholders in templates |
| `make status` | Shows `docker compose ps` for all generated compose files |
| `make ip-check` | Verifies VPN connectivity for Arr Stack containers |
| `make deploy-<stack>` | Renders templates and starts the specified stack |
### Custom Services (Rust/MQTT)
To add your own services (e.g., Rust-based backends):
1. Add your service to a new or existing `docker-compose.*.yml`.
2. Connect it to the `ha-network` if it needs to reach Home Assistant.
3. Expose it via Caddy by adding a block to `docker-compose-files/caddy/Caddyfile_template` and running `make deploy-caddy`.
## Shared Commands
Most stacks use the following pattern:
Most stacks use the following manual pattern (automated by `make`):
```bash
./substitute_env.sh docker-compose-files/<stack>/template.yaml docker-compose.<stack>.yml .env

View file

@ -1,17 +1,33 @@
## Check if VPN is set up correctly on all containers.
#!/bin/bash
# gluetun does not have curl so we download and cat the ip
sudo docker exec -it gluetun wget ipconfig.io
sudo docker exec -it gluetun cat index.html
## Check if VPN is set up correctly on all containers in the Arr Stack.
sudo docker exec -it prowlarr curl ipconfig.io
sudo docker exec -it qbittorrent curl ipconfig.io
sudo docker exec -it sabnzbd curl ipconfig.io
set -euo pipefail
## Not on VPN
sudo docker exec -it radarr curl ipconfig.io
sudo docker exec -it sonarr curl ipconfig.io
sudo docker exec -it bazarr curl ipconfig.io
sudo docker exec -it flaresolverr curl ipconfig.io
sudo docker exec -it emby curl ipconfig.io
sudo docker exec -it seerr curl ipconfig.io
# Use sudo if not running as root
SUDO=""
if [ "$(id -u)" -ne 0 ]; then
SUDO="sudo"
fi
check_ip() {
local container="$1"
echo -n "Container: $container -> "
if [[ "$container" == "gluetun" ]]; then
# gluetun does not have curl so we download and cat the ip
$SUDO docker exec "$container" wget -qO- ipconfig.io || echo "Error"
else
$SUDO docker exec "$container" curl -s ipconfig.io || echo "Error"
fi
}
echo "Checking VPN-protected containers..."
check_ip "gluetun"
check_ip "prowlarr"
check_ip "qbittorrent"
check_ip "sabnzbd"
echo -e "\nChecking non-VPN containers (should show your public IP)..."
for container in radarr sonarr bazarr flaresolverr emby seerr; do
check_ip "$container"
done