- Updated docker-compose.yml to include environment variable support for services, enhancing flexibility in configuration. - Refactored Dockerfile to utilize build arguments for VITE environment variables, allowing for better customization during builds. - Improved Nginx configuration to handle larger video uploads by increasing client_max_body_size to 5GB. - Enhanced backend Dockerfile to include wget for health checks and improved startup logging for database migrations. - Added validation for critical environment variables in the backend to ensure necessary configurations are present before application startup. - Updated content streaming logic to support direct HLS URL construction, improving streaming reliability and user experience. - Refactored various components and services to streamline access checks and improve error handling during content playback.
310 lines
12 KiB
Bash
Executable File
310 lines
12 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ──────────────────────────────────────────────────────────────
|
|
# IndeeHub — Full-stack development launcher
|
|
#
|
|
# Starts everything you need for local development:
|
|
# 1. Infrastructure (Postgres, Redis, MinIO) — Homebrew or Docker
|
|
# 2. Local Nostr relay (nak) — optional
|
|
# 3. Backend API (NestJS on port 4000)
|
|
# 4. Frontend dev server (Vite on port 5174)
|
|
#
|
|
# Usage:
|
|
# bash scripts/dev.sh # start everything
|
|
# bash scripts/dev.sh --no-docker # skip Docker (use Homebrew services)
|
|
# bash scripts/dev.sh --no-seed # skip Nostr relay seeding
|
|
#
|
|
# Press Ctrl+C to stop everything cleanly.
|
|
# ──────────────────────────────────────────────────────────────
|
|
set -e
|
|
|
|
# ── Configuration ────────────────────────────────────────────
|
|
RELAY_PORT=7777
|
|
RELAY_URL="ws://localhost:$RELAY_PORT"
|
|
VITE_PORT=5174
|
|
BACKEND_PORT=4000
|
|
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
BACKEND_DIR="$ROOT_DIR/backend"
|
|
|
|
SKIP_DOCKER=false
|
|
SKIP_SEED=false
|
|
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--no-docker) SKIP_DOCKER=true ;;
|
|
--no-seed) SKIP_SEED=true ;;
|
|
esac
|
|
done
|
|
|
|
# ── Colours ──────────────────────────────────────────────────
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
CYAN='\033[0;36m'
|
|
BOLD='\033[1m'
|
|
NC='\033[0m' # No Colour
|
|
|
|
# ── PID tracking for cleanup ────────────────────────────────
|
|
PIDS=()
|
|
MINIO_PID=""
|
|
|
|
cleanup() {
|
|
echo ""
|
|
echo -e "${YELLOW}Shutting down all services...${NC}"
|
|
|
|
for pid in "${PIDS[@]}"; do
|
|
if kill -0 "$pid" 2>/dev/null; then
|
|
kill "$pid" 2>/dev/null
|
|
fi
|
|
done
|
|
|
|
# Stop MinIO if we started it
|
|
if [ -n "$MINIO_PID" ] && kill -0 "$MINIO_PID" 2>/dev/null; then
|
|
kill "$MINIO_PID" 2>/dev/null
|
|
fi
|
|
|
|
# Stop Docker infrastructure (if we used Docker)
|
|
if [ "$SKIP_DOCKER" = false ] && command -v docker &>/dev/null; then
|
|
echo -e "${CYAN}Stopping Docker services...${NC}"
|
|
docker compose -f "$ROOT_DIR/docker-compose.dev.yml" stop postgres redis minio minio-init mailpit 2>/dev/null || true
|
|
fi
|
|
|
|
# Kill anything still on relay port
|
|
lsof -ti :$RELAY_PORT 2>/dev/null | xargs kill -9 2>/dev/null || true
|
|
|
|
echo -e "${GREEN}All services stopped.${NC}"
|
|
exit 0
|
|
}
|
|
trap cleanup SIGINT SIGTERM EXIT
|
|
|
|
# ── Prefixed output helper ───────────────────────────────────
|
|
prefix_output() {
|
|
local label="$1"
|
|
local colour="$2"
|
|
while IFS= read -r line; do
|
|
echo -e "${colour}[${label}]${NC} $line"
|
|
done
|
|
}
|
|
|
|
# ── Pre-flight checks ───────────────────────────────────────
|
|
echo -e "${BOLD}${CYAN}"
|
|
echo "╔══════════════════════════════════════════╗"
|
|
echo "║ IndeeHub Dev Environment ║"
|
|
echo "╚══════════════════════════════════════════╝"
|
|
echo -e "${NC}"
|
|
|
|
# Check required tools
|
|
MISSING=()
|
|
command -v node &>/dev/null || MISSING+=("node")
|
|
command -v npm &>/dev/null || MISSING+=("npm")
|
|
|
|
if [ ${#MISSING[@]} -gt 0 ]; then
|
|
echo -e "${RED}Missing required tools: ${MISSING[*]}${NC}"
|
|
echo "Install them and try again."
|
|
exit 1
|
|
fi
|
|
|
|
HAS_NAK=true
|
|
if ! command -v nak &>/dev/null; then
|
|
HAS_NAK=false
|
|
echo -e "${YELLOW}Warning: 'nak' not installed. Skipping local Nostr relay.${NC}"
|
|
echo -e "${YELLOW}Install with: brew install nak${NC}"
|
|
echo ""
|
|
fi
|
|
|
|
HAS_DOCKER=false
|
|
if command -v docker &>/dev/null; then
|
|
HAS_DOCKER=true
|
|
fi
|
|
|
|
# ═════════════════════════════════════════════════════════════
|
|
# STEP 1 — Infrastructure (Homebrew or Docker)
|
|
# ═════════════════════════════════════════════════════════════
|
|
if [ "$SKIP_DOCKER" = true ] || [ "$HAS_DOCKER" = false ]; then
|
|
echo -e "${CYAN}[1/4] Starting infrastructure via Homebrew...${NC}"
|
|
|
|
# Postgres
|
|
if command -v pg_isready &>/dev/null || [ -f /opt/homebrew/opt/postgresql@15/bin/pg_isready ]; then
|
|
PG_ISREADY="${PG_ISREADY:-$(command -v pg_isready 2>/dev/null || echo /opt/homebrew/opt/postgresql@15/bin/pg_isready)}"
|
|
if $PG_ISREADY -h localhost -p 5432 -q 2>/dev/null; then
|
|
echo -e "${GREEN} Postgres is already running.${NC}"
|
|
else
|
|
echo -e "${CYAN} Starting Postgres...${NC}"
|
|
brew services start postgresql@15 2>/dev/null || true
|
|
sleep 2
|
|
fi
|
|
else
|
|
echo -e "${RED} Postgres not found. Install with: brew install postgresql@15${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Redis
|
|
if command -v redis-cli &>/dev/null; then
|
|
if redis-cli ping 2>/dev/null | grep -q PONG; then
|
|
echo -e "${GREEN} Redis is already running.${NC}"
|
|
else
|
|
echo -e "${CYAN} Starting Redis...${NC}"
|
|
brew services start redis 2>/dev/null || true
|
|
sleep 1
|
|
fi
|
|
else
|
|
echo -e "${RED} Redis not found. Install with: brew install redis${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# MinIO
|
|
if command -v minio &>/dev/null; then
|
|
if curl -s -o /dev/null http://localhost:9000/minio/health/live 2>/dev/null; then
|
|
echo -e "${GREEN} MinIO is already running.${NC}"
|
|
else
|
|
echo -e "${CYAN} Starting MinIO...${NC}"
|
|
mkdir -p /tmp/minio-data
|
|
MINIO_ROOT_USER=minioadmin MINIO_ROOT_PASSWORD=minioadmin123 \
|
|
minio server /tmp/minio-data --console-address ":9001" --address ":9000" \
|
|
> /tmp/minio.log 2>&1 &
|
|
MINIO_PID=$!
|
|
sleep 2
|
|
|
|
# Create buckets if mc is available
|
|
if command -v mc &>/dev/null; then
|
|
mc alias set local http://localhost:9000 minioadmin minioadmin123 2>/dev/null || true
|
|
mc mb local/indeedhub-private --ignore-existing 2>/dev/null || true
|
|
mc mb local/indeedhub-public --ignore-existing 2>/dev/null || true
|
|
mc anonymous set download local/indeedhub-public 2>/dev/null || true
|
|
echo -e "${GREEN} MinIO buckets configured.${NC}"
|
|
fi
|
|
fi
|
|
else
|
|
echo -e "${YELLOW} MinIO not found (optional). Install with: brew install minio/stable/minio${NC}"
|
|
fi
|
|
|
|
# Ensure the Postgres database exists
|
|
PSQL="${PSQL:-$(command -v psql 2>/dev/null || echo /opt/homebrew/opt/postgresql@15/bin/psql)}"
|
|
CREATEDB="${CREATEDB:-$(command -v createdb 2>/dev/null || echo /opt/homebrew/opt/postgresql@15/bin/createdb)}"
|
|
CREATEUSER="${CREATEUSER:-$(command -v createuser 2>/dev/null || echo /opt/homebrew/opt/postgresql@15/bin/createuser)}"
|
|
|
|
# Create user if not exists
|
|
if ! $PSQL -U "$(whoami)" -d postgres -tc "SELECT 1 FROM pg_roles WHERE rolname='indeedhub'" 2>/dev/null | grep -q 1; then
|
|
$CREATEUSER -U "$(whoami)" --superuser indeedhub 2>/dev/null || true
|
|
$PSQL -U "$(whoami)" -d postgres -c "ALTER USER indeedhub WITH PASSWORD 'indeedhub_dev_2026';" 2>/dev/null || true
|
|
fi
|
|
|
|
# Create database if not exists
|
|
if ! $PSQL -U "$(whoami)" -d postgres -tc "SELECT 1 FROM pg_database WHERE datname='indeedhub'" 2>/dev/null | grep -q 1; then
|
|
$CREATEDB -U "$(whoami)" -O indeedhub indeedhub 2>/dev/null || true
|
|
fi
|
|
|
|
echo -e "${GREEN} Homebrew infrastructure is ready.${NC}"
|
|
|
|
else
|
|
echo -e "${CYAN}[1/4] Starting Docker infrastructure...${NC}"
|
|
|
|
docker compose -f "$ROOT_DIR/docker-compose.dev.yml" up -d \
|
|
postgres redis minio minio-init mailpit 2>&1 | prefix_output "docker" "$CYAN"
|
|
|
|
echo -e "${CYAN} Waiting for Postgres...${NC}"
|
|
for i in $(seq 1 30); do
|
|
if docker compose -f "$ROOT_DIR/docker-compose.dev.yml" exec -T postgres pg_isready -U indeedhub -q 2>/dev/null; then
|
|
echo -e "${GREEN} Postgres is ready.${NC}"
|
|
break
|
|
fi
|
|
if [ "$i" -eq 30 ]; then
|
|
echo -e "${RED} Postgres did not become healthy in time.${NC}"
|
|
exit 1
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
echo -e "${GREEN} Docker infrastructure is up.${NC}"
|
|
fi
|
|
|
|
# ═════════════════════════════════════════════════════════════
|
|
# STEP 2 — Local Nostr relay
|
|
# ═════════════════════════════════════════════════════════════
|
|
if [ "$HAS_NAK" = true ]; then
|
|
echo -e "${CYAN}[2/4] Starting local Nostr relay on port $RELAY_PORT...${NC}"
|
|
|
|
# Kill existing process on the port
|
|
if lsof -i :$RELAY_PORT -P &>/dev/null; then
|
|
lsof -ti :$RELAY_PORT | xargs kill -9 2>/dev/null || true
|
|
sleep 1
|
|
fi
|
|
|
|
nak serve --port $RELAY_PORT > /dev/null 2>&1 &
|
|
PIDS+=($!)
|
|
|
|
# Wait for relay
|
|
for i in $(seq 1 20); do
|
|
if curl -s -o /dev/null http://localhost:$RELAY_PORT 2>/dev/null; then
|
|
echo -e "${GREEN} Relay is ready at $RELAY_URL${NC}"
|
|
break
|
|
fi
|
|
sleep 0.5
|
|
done
|
|
|
|
# Seed relay
|
|
if [ "$SKIP_SEED" = false ]; then
|
|
if [ -f "$ROOT_DIR/scripts/seed-profiles.ts" ]; then
|
|
echo -e "${CYAN} Seeding test profiles...${NC}"
|
|
(cd "$ROOT_DIR" && npx tsx scripts/seed-profiles.ts 2>&1 | prefix_output "seed" "$CYAN") || true
|
|
fi
|
|
if [ -f "$ROOT_DIR/scripts/seed-activity.ts" ]; then
|
|
echo -e "${CYAN} Seeding activity...${NC}"
|
|
(cd "$ROOT_DIR" && npx tsx scripts/seed-activity.ts 2>&1 | prefix_output "seed" "$CYAN") || true
|
|
fi
|
|
fi
|
|
else
|
|
echo -e "${YELLOW}[2/4] Skipping Nostr relay (nak not installed).${NC}"
|
|
fi
|
|
|
|
# ═════════════════════════════════════════════════════════════
|
|
# STEP 3 — Backend API
|
|
# ═════════════════════════════════════════════════════════════
|
|
echo -e "${CYAN}[3/4] Starting backend API on port $BACKEND_PORT...${NC}"
|
|
|
|
# Override Docker service hostnames → localhost so the backend
|
|
# can reach services from the host machine.
|
|
export DATABASE_HOST=localhost
|
|
export QUEUE_HOST=localhost
|
|
export S3_ENDPOINT=http://localhost:9000
|
|
export SMTP_HOST=localhost
|
|
|
|
(cd "$BACKEND_DIR" && npm run start:dev 2>&1 | prefix_output "api" "$GREEN") &
|
|
PIDS+=($!)
|
|
|
|
# Wait for the API to respond
|
|
echo -e "${CYAN} Waiting for API...${NC}"
|
|
for i in $(seq 1 60); do
|
|
if curl -s -o /dev/null "http://localhost:$BACKEND_PORT" 2>/dev/null; then
|
|
echo -e "${GREEN} Backend API is ready at http://localhost:$BACKEND_PORT${NC}"
|
|
break
|
|
fi
|
|
if [ "$i" -eq 60 ]; then
|
|
echo -e "${YELLOW} Backend is still starting (check logs above for errors).${NC}"
|
|
fi
|
|
sleep 2
|
|
done
|
|
|
|
# ═════════════════════════════════════════════════════════════
|
|
# STEP 4 — Frontend dev server
|
|
# ═════════════════════════════════════════════════════════════
|
|
echo ""
|
|
echo -e "${BOLD}${GREEN}"
|
|
echo "════════════════════════════════════════════"
|
|
echo " All services launching! "
|
|
echo ""
|
|
echo " Frontend: http://localhost:$VITE_PORT"
|
|
echo " Backend: http://localhost:$BACKEND_PORT"
|
|
echo " MinIO: http://localhost:9001"
|
|
[ "$HAS_NAK" = true ] && echo " Relay: $RELAY_URL"
|
|
echo ""
|
|
echo " Mock mode: OFF (VITE_USE_MOCK_DATA=false)"
|
|
echo " BTCPay: ${BTCPAY_URL:-from backend/.env}"
|
|
echo ""
|
|
echo " Press Ctrl+C to stop everything"
|
|
echo "════════════════════════════════════════════"
|
|
echo -e "${NC}"
|
|
|
|
# Run Vite in the foreground so Ctrl+C propagates cleanly
|
|
cd "$ROOT_DIR"
|
|
npx vite --port $VITE_PORT 2>&1 | prefix_output "vite" "$YELLOW"
|