# ============================================================== # VEREINS.HAUS — Makefile # Deploy-Strategie: SSH zur DS, Docker Compose # ============================================================== DS_HOST := ds DS_IP := 10.47.11.10 DS_SSH_PORT := 4711 DS_PATH := /volume1/docker/vereinshaus CONTAINER_PB := vereinshaus-pocketbase CONTAINER_APP := vereinshaus-app DOCKER := sudo /usr/local/bin/docker STAGING_PATH := /volume1/docker/vereinshaus-staging CONTAINER_PB_STAGING := vereinshaus-staging-pocketbase CONTAINER_APP_STAGING:= vereinshaus-staging-app STAGING_PB_URL := http://localhost:8091 STAGING_MIGRATIONS := $(STAGING_PATH)/pocketbase/migrations STAGING_HOOKS := $(STAGING_PATH)/pocketbase/data/pb_hooks TAR_EXCLUDE := --exclude='.git' \ --exclude='./app/node_modules' \ --exclude='./app/.svelte-kit' \ --exclude='./app/build' \ --exclude='./.env' \ --exclude='./.DS_Store' HOOKS_SRC := pocketbase/pb_hooks HOOKS_DST := /volume1/docker/vereinshaus/pocketbase/data/pb_hooks MIGRATIONS_SRC := pocketbase/pb_migrations MIGRATIONS_DST := /volume1/docker/vereinshaus/pocketbase/migrations .PHONY: help check-ssh start stop restart status logs logs-f logs-app \ shell-pb pb-admin deploy # ---------------------------------------------------------- # Hilfe # ---------------------------------------------------------- help: @echo "" @echo " vereins.haus — verfügbare Befehle:" @echo "" @echo " make deploy App bauen + zur DS übertragen + Container neu starten" @echo " make start Alle Container starten" @echo " make stop Alle Container stoppen" @echo " make restart Alle Container neu starten" @echo " make status Container-Status anzeigen" @echo "" @echo " make logs PocketBase-Logs (100 Zeilen)" @echo " make logs-app App-Logs (100 Zeilen)" @echo " make logs-f PocketBase Live-Log" @echo " make shell-pb Shell in PocketBase-Container" @echo " make pb-admin PocketBase Admin-URL anzeigen" @echo "" # ---------------------------------------------------------- # SSH-Prüfung # ---------------------------------------------------------- check-ssh: @if ! nc -z -w3 $(DS_IP) $(DS_SSH_PORT) 2>/dev/null; then \ echo ""; \ echo " ✗ DS nicht erreichbar ($(DS_IP):$(DS_SSH_PORT))"; \ echo ""; \ exit 1; \ fi # ---------------------------------------------------------- # DEPLOY # ---------------------------------------------------------- deploy: check-ssh @echo "→ Sync zu DS..." @COPYFILE_DISABLE=1 tar czf - $(TAR_EXCLUDE) . | ssh $(DS_HOST) "tar xzf - -C $(DS_PATH)/" @echo "→ .env auf DS aktualisieren..." @if [ -f .env ]; then \ cat .env | ssh $(DS_HOST) "cat > $(DS_PATH)/.env"; \ fi @echo "→ PocketBase Hooks synchronisieren..." @if ls $(HOOKS_SRC)/*.pb.js 2>/dev/null | grep -q .; then \ for f in $(HOOKS_SRC)/*.pb.js; do \ cat "$$f" | ssh $(DS_HOST) "cat > $(HOOKS_DST)/$$(basename $$f)"; \ done; \ fi @echo "→ PocketBase Migrations synchronisieren (nur neue)..." @ssh $(DS_HOST) "mkdir -p $(MIGRATIONS_DST)" @if ls $(MIGRATIONS_SRC)/*.js 2>/dev/null | grep -q .; then \ for f in $(MIGRATIONS_SRC)/*.js; do \ fname=$$(basename "$$f"); \ if ! ssh $(DS_HOST) "test -f $(MIGRATIONS_DST)/$$fname" 2>/dev/null; then \ cat "$$f" | ssh $(DS_HOST) "cat > $(MIGRATIONS_DST)/$$fname"; \ echo " ✓ $$fname"; \ fi; \ done; \ fi @echo "→ Docker rebuild + restart..." @ssh $(DS_HOST) " \ cd $(DS_PATH) && \ $(DOCKER) compose down && \ $(DOCKER) compose build app && \ $(DOCKER) compose up -d" @echo " ✓ Deploy fertig." @ssh $(DS_HOST) "$(DOCKER) logs $(CONTAINER_APP) --tail=10" # ---------------------------------------------------------- # Container-Steuerung # ---------------------------------------------------------- start: check-ssh @ssh $(DS_HOST) "cd $(DS_PATH) && $(DOCKER) compose up -d" @echo " ✓ Gestartet." stop: check-ssh @ssh $(DS_HOST) "cd $(DS_PATH) && $(DOCKER) compose down" @echo " ✓ Gestoppt." restart: check-ssh @ssh $(DS_HOST) "cd $(DS_PATH) && $(DOCKER) compose restart" @echo " ✓ Neugestartet." status: check-ssh @ssh $(DS_HOST) "$(DOCKER) ps \ --filter name=vereinshaus \ --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'" # ---------------------------------------------------------- # Logs # ---------------------------------------------------------- logs: check-ssh @ssh $(DS_HOST) "$(DOCKER) logs $(CONTAINER_PB) --tail=100" logs-app: check-ssh @ssh $(DS_HOST) "$(DOCKER) logs $(CONTAINER_APP) --tail=100" logs-f: check-ssh @ssh $(DS_HOST) "$(DOCKER) logs $(CONTAINER_PB) -f" # ---------------------------------------------------------- # Shell + Admin # ---------------------------------------------------------- shell-pb: check-ssh @ssh -t $(DS_HOST) "$(DOCKER) exec -it $(CONTAINER_PB) sh" pb-admin: @echo " PocketBase Admin: https://api.vereins.haus/_/" # ============================================================== # STAGING # ============================================================== .PHONY: staging-deploy staging-reset staging-seed staging-logs staging-status staging-stop staging-deploy: check-ssh @echo "→ Sync zu DS (Staging)..." @COPYFILE_DISABLE=1 tar czf - $(TAR_EXCLUDE) . | ssh $(DS_HOST) "tar xzf - -C $(STAGING_PATH)/" @echo "→ .env auf DS (Staging)..." @if [ -f .env ]; then \ cat .env | ssh $(DS_HOST) "cat > $(STAGING_PATH)/.env"; \ fi @echo "→ Hooks synchronisieren (Staging, vollständig)..." @ssh $(DS_HOST) "mkdir -p $(STAGING_HOOKS)" @if ls $(HOOKS_SRC)/*.pb.js 2>/dev/null | grep -q .; then \ for f in $(HOOKS_SRC)/*.pb.js; do \ cat "$$f" | ssh $(DS_HOST) "cat > $(STAGING_HOOKS)/$$(basename $$f)"; \ done; \ fi @echo "→ Migrations synchronisieren (Staging, immer aktuell)..." @ssh $(DS_HOST) "mkdir -p $(STAGING_MIGRATIONS)" @if ls $(MIGRATIONS_SRC)/*.js 2>/dev/null | grep -q .; then \ for f in $(MIGRATIONS_SRC)/*.js; do \ cat "$$f" | ssh $(DS_HOST) "cat > $(STAGING_MIGRATIONS)/$$(basename $$f)"; \ done; \ fi @echo "→ Docker rebuild + restart (Staging)..." @ssh $(DS_HOST) " \ cd $(STAGING_PATH) && \ $(DOCKER) compose -f docker-compose.staging.yml down && \ $(DOCKER) compose -f docker-compose.staging.yml build app-staging && \ $(DOCKER) compose -f docker-compose.staging.yml up -d" @echo " ✓ Staging bereit." @echo " App: https://staging.vereins.haus" @echo " PocketBase: https://api-staging.vereins.haus/_/" # Löscht alle PB-Daten auf Staging → Migrations laufen frisch durch # Danach: make staging-deploy && make staging-seed staging-reset: check-ssh staging-stop @echo "→ PocketBase-Daten auf Staging löschen..." @ssh $(DS_HOST) "rm -rf \ $(STAGING_PATH)/pocketbase/data/storage \ '$(STAGING_PATH)/pocketbase/data/data.db' \ '$(STAGING_PATH)/pocketbase/data/data.db-wal' \ '$(STAGING_PATH)/pocketbase/data/data.db-shm' \ $(STAGING_PATH)/pocketbase/migrations" @echo "→ Alle Hooks auf Staging löschen (werden via staging-deploy neu geschrieben)..." @ssh $(DS_HOST) "rm -f $(STAGING_HOOKS)/*.pb.js" @echo " ✓ Reset fertig. Jetzt: make staging-deploy && make staging-seed" staging-seed: @echo "→ Testdaten in Staging einfügen..." @echo " Voraussetzung: PB_EMAIL + PB_PASSWORD in .env gesetzt (Staging-Superuser)" @if [ -f .env ]; then \ export $$(grep -v '^#' .env | xargs) && \ PB_URL=https://api-staging.vereins.haus node scripts/seed.js; \ else \ PB_URL=https://api-staging.vereins.haus node scripts/seed.js; \ fi staging-logs: check-ssh @ssh $(DS_HOST) "$(DOCKER) logs $(CONTAINER_APP_STAGING) --tail=50" staging-status: check-ssh @ssh $(DS_HOST) "$(DOCKER) ps \ --filter name=vereinshaus-staging \ --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'" staging-stop: check-ssh @ssh $(DS_HOST) "cd $(STAGING_PATH) && $(DOCKER) compose -f docker-compose.staging.yml down" @echo " ✓ Staging gestoppt."