From a8d07ba2abf5b27849b0d7131dd30bdcb216b6b7 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 9 Jun 2026 15:18:13 +0200 Subject: [PATCH] =?UTF-8?q?Makefile:=20lokale=20Dev-/DB-Ziele=20(build,=20?= =?UTF-8?q?migrate,=20seed,=20setup)=20erg=C3=A4nzen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docker-compose.dev.yml: veröffentlicht Postgres-Port 5432 für Host-läufige Migrationen/Seeds (Produktiv-Postgres bleibt app-intern). - Makefile: help-Default + Ziele install/dev/build-app/lint/typecheck/test, db-up/db-wait/migrate/seed/seed-auth/seed-all/generate/db-check/studio/db-reset, one-shot 'setup', E2E-Ziele; bestehende Deploy-Ziele (build/up/deploy/data) erhalten. 'make build-app migrate' bzw. 'make setup' decken den gewünschten Build+Migrate-Flow ab. Co-Authored-By: Claude Opus 4.8 (1M context) --- Makefile | 149 +++++++++++++++++++++++++++++++++++------ docker-compose.dev.yml | 11 +++ 2 files changed, 139 insertions(+), 21 deletions(-) create mode 100644 docker-compose.dev.yml diff --git a/Makefile b/Makefile index 33d39f9..bcc1b56 100644 --- a/Makefile +++ b/Makefile @@ -1,38 +1,145 @@ -# FlorianNetz — Deployment-Makefile (externes Traefik). +# FlorianNetz — Makefile +# Lokale Entwicklung, Datenbank (Migrationen/Seeds) und Deployment (externes Traefik). # -# Ziele: -# make build - baut das App-Image (Next.js standalone, non-root) -# make up - startet den Stack (App + Postgres + Geo) hinter Traefik -# make down - stoppt den Stack -# make logs - folgt den App-Logs -# make deploy - build + up (Standard-Deploy) -# make data - bereitet die OSRM-Geodaten vor (Download + Preprocessing) -# make config - validiert die Compose-Konfiguration +# Schnellstart (lokal, Postgres via Docker): +# make setup # install + Postgres hoch + migrate + seed-all +# make dev # Dev-Server -> http://localhost:3000 # -# Hinweis: up/data/deploy benötigen Docker (+ Netzzugriff/RAM/Disk) und werden -# NICHT in CI/Sandbox ausgeführt. Das externe Traefik-Netz muss existieren: -# docker network create traefik +# Nur Build + Migrate (z. B. CI / vor Deploy): +# make build-app migrate +# +# Voll-Deploy hinter externem Traefik (Docker): +# docker network create traefik # einmalig +# make deploy +# +# `make help` listet alle Ziele. -COMPOSE = docker compose --env-file .env +SHELL := /bin/bash +COMPOSE = docker compose --env-file .env +# Lokale DB-Ziele binden den Dev-Override ein (veröffentlicht Postgres-Port 5432). +COMPOSE_DEV = docker compose --env-file .env -f docker-compose.yml -f docker-compose.dev.yml -.PHONY: build up down logs deploy data config +.DEFAULT_GOAL := help -build: +# --------------------------------------------------------------------------- +.PHONY: help +help: ## Diese Übersicht anzeigen + @grep -hE '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) \ + | awk 'BEGIN{FS=":.*?## "}{printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}' + +# --- Umgebung ------------------------------------------------------------- +.PHONY: env install +env: ## .env aus .env.example erzeugen (falls noch nicht vorhanden) + @if [ ! -f .env ]; then cp .env.example .env && echo "→ .env aus .env.example erstellt (Werte anpassen!)"; else echo "→ .env existiert bereits"; fi + +install: ## npm-Abhängigkeiten installieren + npm install + +# --- Lokale Entwicklung & Qualität --------------------------------------- +.PHONY: dev build-app lint typecheck test test-cov check +dev: ## Next.js Dev-Server (http://localhost:3000) + npm run dev + +build-app: ## Next.js Production-Build (ohne Docker) + npm run build + +lint: ## ESLint + npm run lint + +typecheck: ## TypeScript prüfen (tsc --noEmit) + npm run typecheck + +test: ## Unit-Tests (Vitest) + npm run test + +test-cov: ## Unit-Tests mit Coverage + npm run test:coverage + +check: lint typecheck test ## Lint + Typecheck + Unit-Tests (Offline-DoD) + +# --- E2E (braucht laufenden Server + Browser) ---------------------------- +.PHONY: e2e-install e2e e2e-gating +e2e-install: ## Playwright-Browser installieren (einmalig) + npx playwright install + +e2e: ## Komplette Playwright-E2E-Suite + npm run test:e2e + +e2e-gating: ## Nur die Default-deny-Gating-Suite + npm run test:e2e:gating + +# --- Datenbank (lokal; Postgres via Docker, Port auf Host veröffentlicht) - +.PHONY: db-up db-down db-wait generate migrate seed-auth seed seed-all db-check studio db-reset +db-up: ## Nur Postgres starten (Docker, Port 5432 lokal) + $(COMPOSE_DEV) up -d postgres + +db-down: ## Postgres-Container stoppen + $(COMPOSE_DEV) stop postgres + +db-wait: ## Warten bis Postgres bereit ist (max ~60s) + @echo "→ Warte auf Postgres…"; \ + for i in $$(seq 1 30); do \ + if $(COMPOSE_DEV) exec -T postgres sh -c 'pg_isready -U "$$POSTGRES_USER" -d "$$POSTGRES_DB"' >/dev/null 2>&1; then \ + echo "→ Postgres bereit."; exit 0; \ + fi; sleep 2; \ + done; echo "✗ Postgres nicht bereit (Timeout)."; exit 1 + +generate: ## Drizzle-Migration aus dem Schema generieren + npm run db:generate + +migrate: ## Migrationen anwenden (DATABASE_URL aus .env -> localhost:5432) + npm run db:migrate + +seed-auth: ## Ersten Platform-Admin anlegen (idempotent) + npm run db:seed-auth + +seed: ## NÖ-Katalog seeden: Merkmale/Vorlagen/Kategorien (idempotent) + npm run db:seed + +seed-all: seed-auth seed ## Auth- + Katalog-Seed + +db-check: ## Drizzle-Schema-/Migrationskonsistenz prüfen (offline) + npm run db:check + +studio: ## Drizzle Studio öffnen (DB-Browser) + npm run db:studio + +db-reset: ## ACHTUNG: Postgres-Volume löschen, neu migrieren + seeden + $(COMPOSE_DEV) rm -sf postgres + -docker volume rm florian-netz_postgres-data + $(MAKE) db-up db-wait migrate seed-all + +# --- Erststart (lokal, von 0) -------------------------------------------- +.PHONY: setup +setup: install env db-up db-wait migrate seed-all ## Komplettes lokales Setup von 0 + @echo "" + @echo "✓ Setup fertig. Login-Admin via 'make seed-auth' angelegt. Weiter mit: make dev" + +# --- Deployment (externes Traefik; braucht Docker) ----------------------- +# Externes Netz muss existieren: docker network create traefik +.PHONY: build up down logs ps deploy migrate-stack data config +build: ## App-Image bauen (Next.js standalone, non-root) $(COMPOSE) build app -up: +up: ## Stack starten (App + Postgres + Geo) hinter Traefik $(COMPOSE) up -d -down: +down: ## Stack stoppen $(COMPOSE) down -logs: +logs: ## App-Logs folgen $(COMPOSE) logs -f app -deploy: build up +ps: ## Status der Stack-Container + $(COMPOSE) ps -data: +deploy: build up ## build + up (Standard-Deploy; migrate läuft via Entrypoint automatisch) + +migrate-stack: ## Migrationen im laufenden App-Container ausführen (manuell) + $(COMPOSE) exec app node docker/migrate.mjs + +data: ## OSRM-Geodaten vorbereiten (Download + Preprocessing; viel RAM/Disk) ./scripts/prepare-osm-data.sh -config: +config: ## Compose-Konfiguration validieren $(COMPOSE) config --services diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..5c08730 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,11 @@ +# Lokale Entwicklung: veröffentlicht den Postgres-Port auf dem Host (5432), +# damit auf dem HOST laufende Befehle (`make migrate`, `make seed`, `npm run db:*`) +# die Datenbank über DATABASE_URL (…@localhost:5432/…) erreichen. +# +# Wird NUR von den lokalen DB-Zielen des Makefiles eingebunden +# (docker compose -f docker-compose.yml -f docker-compose.dev.yml …), +# NICHT vom Produktiv-Deploy — dort bleibt Postgres app-intern (kein offener Port). +services: + postgres: + ports: + - "5432:5432"