146 lines
4.5 KiB
Bash
Executable File
146 lines
4.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
if [[ -f ".env_dev" ]]; then
|
|
set -a
|
|
source .env_dev
|
|
set +a
|
|
fi
|
|
|
|
APP_PORT="${APP_PORT:-3911}"
|
|
BACKEND_PORT="${BACKEND_PORT:-3002}"
|
|
API_PROXY_TARGET="${API_PROXY_TARGET:-http://127.0.0.1:${BACKEND_PORT}}"
|
|
export APP_PORT BACKEND_PORT API_PROXY_TARGET
|
|
export NEXT_TELEMETRY_DISABLED=1
|
|
|
|
kill_port_processes() {
|
|
local port="$1"
|
|
local pids=""
|
|
|
|
if command -v lsof >/dev/null 2>&1; then
|
|
pids="${pids}"$'\n'"$(lsof -tiTCP:"${port}" -sTCP:LISTEN 2>/dev/null || true)"
|
|
fi
|
|
|
|
if command -v fuser >/dev/null 2>&1; then
|
|
pids="${pids}"$'\n'"$(fuser -n tcp "${port}" 2>/dev/null | tr ' ' '\n' || true)"
|
|
fi
|
|
|
|
if command -v ss >/dev/null 2>&1; then
|
|
pids="${pids}"$'\n'"$(ss -ltnp "sport = :${port}" 2>/dev/null | grep -o 'pid=[0-9]*' | cut -d= -f2 || true)"
|
|
fi
|
|
|
|
pids="$(printf '%s\n' "${pids}" | sed '/^$/d' | sort -u)"
|
|
|
|
if [[ -z "${pids}" ]]; then
|
|
echo "Port ${port} ist frei."
|
|
return
|
|
fi
|
|
|
|
echo "Beende Prozess(e) auf Port ${port}: ${pids//$'\n'/ }"
|
|
kill ${pids} 2>/dev/null || true
|
|
sleep 1
|
|
|
|
local remaining=""
|
|
for pid in ${pids}; do
|
|
if kill -0 "${pid}" 2>/dev/null; then
|
|
remaining="${remaining} ${pid}"
|
|
fi
|
|
done
|
|
|
|
if [[ -n "${remaining}" ]]; then
|
|
echo "Erzwinge Stop für:${remaining}"
|
|
kill -9 ${remaining} 2>/dev/null || true
|
|
fi
|
|
}
|
|
|
|
kill_port_processes "${BACKEND_PORT}"
|
|
if [[ "${APP_PORT}" != "${BACKEND_PORT}" ]]; then
|
|
kill_port_processes "${APP_PORT}"
|
|
fi
|
|
|
|
if [[ -z "${DATABASE_URL:-}" ]]; then
|
|
echo "DATABASE_URL fehlt. Beispiel:"
|
|
echo " export DATABASE_URL='postgresql://user:pass@localhost:5432/tickettracker'"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -z "${SECRET_ENCRYPTION_KEY:-}" && -z "${TICKETTRACKER_SECRET_KEY:-}" ]]; then
|
|
export SECRET_ENCRYPTION_KEY="${DATABASE_URL}"
|
|
fi
|
|
|
|
DATABASE_HOST="$(node -e 'const url = new URL(process.env.DATABASE_URL); process.stdout.write(url.hostname)' 2>/dev/null || true)"
|
|
DATABASE_PORT="$(node -e 'const url = new URL(process.env.DATABASE_URL); process.stdout.write(url.port || "5432")' 2>/dev/null || echo 5432)"
|
|
POSTGRES_CONTAINER="${POSTGRES_CONTAINER:-tickettracker-postgres}"
|
|
|
|
if command -v docker >/dev/null 2>&1 && docker inspect "${POSTGRES_CONTAINER}" >/dev/null 2>&1; then
|
|
POSTGRES_CONTAINER_IP="$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "${POSTGRES_CONTAINER}")"
|
|
|
|
if [[ -n "${POSTGRES_CONTAINER_IP}" ]]; then
|
|
SHOULD_USE_CONTAINER_IP=false
|
|
|
|
if [[ "${DATABASE_HOST}" == "postgres" || "${DATABASE_HOST}" == "postgres-tickettracker" ]]; then
|
|
if ! getent hosts "${DATABASE_HOST}" >/dev/null 2>&1; then
|
|
SHOULD_USE_CONTAINER_IP=true
|
|
fi
|
|
elif [[ "${DATABASE_HOST}" =~ ^172\. ]] && [[ "${DATABASE_HOST}" != "${POSTGRES_CONTAINER_IP}" ]]; then
|
|
SHOULD_USE_CONTAINER_IP=true
|
|
fi
|
|
|
|
if [[ "${SHOULD_USE_CONTAINER_IP}" == "true" ]]; then
|
|
export DATABASE_URL="$(
|
|
DATABASE_HOST="${POSTGRES_CONTAINER_IP}" node -e 'const url = new URL(process.env.DATABASE_URL); url.hostname = process.env.DATABASE_HOST; process.stdout.write(url.toString())'
|
|
)"
|
|
echo "Nutze Docker-Postgres ${POSTGRES_CONTAINER} unter ${POSTGRES_CONTAINER_IP}:${DATABASE_PORT} für den lokalen Start."
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
NODE_MAJOR="$(node -p 'Number(process.versions.node.split(".")[0])' 2>/dev/null || echo 0)"
|
|
|
|
if [[ "${NODE_MAJOR}" -lt 20 ]]; then
|
|
echo "Das Next/shadcn-Framework braucht lokal Node >= 20.9, empfohlen Node 22."
|
|
echo "Aktuell ist Node ${NODE_MAJOR:-unbekannt} aktiv."
|
|
echo "Es wird kein Docker-Container gebaut oder gestartet."
|
|
exit 1
|
|
fi
|
|
|
|
npm run build
|
|
|
|
cleanup() {
|
|
if [[ -n "${BACKEND_PID:-}" ]]; then
|
|
kill "${BACKEND_PID}" 2>/dev/null || true
|
|
fi
|
|
}
|
|
trap cleanup EXIT INT TERM
|
|
|
|
echo "Starte Backend auf Port ${BACKEND_PORT}"
|
|
BACKEND_LOG="${TMPDIR:-/tmp}/tickettracker-backend-local.log"
|
|
rm -f "${BACKEND_LOG}"
|
|
SERVE_FRONTEND=false PORT="${BACKEND_PORT}" npm run start --workspace backend >"${BACKEND_LOG}" 2>&1 &
|
|
BACKEND_PID=$!
|
|
|
|
echo "Warte auf Backend ${API_PROXY_TARGET}"
|
|
for _ in $(seq 1 50); do
|
|
if ! kill -0 "${BACKEND_PID}" 2>/dev/null; then
|
|
echo "Backend konnte nicht gestartet werden:"
|
|
cat "${BACKEND_LOG}"
|
|
exit 1
|
|
fi
|
|
|
|
if curl -fsS "${API_PROXY_TARGET}/api/debug/status" >/dev/null 2>&1; then
|
|
break
|
|
fi
|
|
|
|
sleep 0.2
|
|
done
|
|
|
|
if ! curl -fsS "${API_PROXY_TARGET}/api/debug/status" >/dev/null 2>&1; then
|
|
echo "Backend antwortet nicht unter ${API_PROXY_TARGET}."
|
|
echo "Letzte Backend-Ausgabe:"
|
|
tail -n 80 "${BACKEND_LOG}" 2>/dev/null || true
|
|
exit 1
|
|
fi
|
|
|
|
echo "Starte Frontend auf http://localhost:${APP_PORT}"
|
|
PORT="${APP_PORT}" npm run start --workspace frontend
|