472 lines
21 KiB
Bash
472 lines
21 KiB
Bash
#!/usr/bin/env bash
|
|
# ────────────────────────────────────────────────
|
|
# Clawith — First-time Setup Script
|
|
# Sets up backend, frontend, database, and seed data.
|
|
# ────────────────────────────────────────────────
|
|
set -e
|
|
|
|
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[0;33m'; CYAN='\033[0;36m'; NC='\033[0m'
|
|
ROOT="$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
# Parse arguments
|
|
INSTALL_DEV=false
|
|
for arg in "$@"; do
|
|
case $arg in
|
|
--dev) INSTALL_DEV=true ;;
|
|
esac
|
|
done
|
|
|
|
# --- Helper: detect server IP ---
|
|
get_server_ip() {
|
|
# Try hostname -I (Linux), then ifconfig (macOS), then fallback
|
|
local ip
|
|
ip=$(hostname -I 2>/dev/null | awk '{print $1}')
|
|
[ -z "$ip" ] && ip=$(ifconfig 2>/dev/null | grep 'inet ' | grep -v '127.0.0.1' | head -1 | awk '{print $2}')
|
|
[ -z "$ip" ] && ip="<your-server-ip>"
|
|
echo "$ip"
|
|
}
|
|
|
|
# --- Check Python version (>= 3.12 required) ---
|
|
PYTHON_BIN="${PYTHON_BIN:-python3}"
|
|
if command -v "$PYTHON_BIN" &>/dev/null; then
|
|
PY_VER=$("$PYTHON_BIN" -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
|
|
PY_MAJOR=$(echo "$PY_VER" | cut -d. -f1)
|
|
PY_MINOR=$(echo "$PY_VER" | cut -d. -f2)
|
|
if [ "$PY_MAJOR" -lt 3 ] || ([ "$PY_MAJOR" -eq 3 ] && [ "$PY_MINOR" -lt 12 ]); then
|
|
echo -e "${RED}Python $PY_VER detected, but Clawith requires Python >= 3.12.${NC}"
|
|
echo ""
|
|
echo " Please install Python 3.12+:"
|
|
echo " Ubuntu: sudo apt install python3.12 python3.12-venv"
|
|
echo " CentOS: sudo dnf install python3.12"
|
|
echo " macOS: brew install python@3.12"
|
|
echo " Conda: conda create -n clawith python=3.12"
|
|
echo ""
|
|
echo " Or set PYTHON_BIN to point to a valid python3.12+ binary:"
|
|
echo " PYTHON_BIN=/path/to/python3.12 bash setup.sh"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# --- Optional package mirror overrides ---
|
|
PIP_INSTALL_ARGS=()
|
|
if [ -n "${CLAWITH_PIP_INDEX_URL:-}" ]; then
|
|
PIP_INSTALL_ARGS+=(--index-url "$CLAWITH_PIP_INDEX_URL")
|
|
fi
|
|
if [ -n "${CLAWITH_PIP_TRUSTED_HOST:-}" ]; then
|
|
PIP_INSTALL_ARGS+=(--trusted-host "$CLAWITH_PIP_TRUSTED_HOST")
|
|
fi
|
|
NPM_MIRROR="--registry https://registry.npmmirror.com"
|
|
|
|
echo ""
|
|
echo -e "${CYAN}═══════════════════════════════════════${NC}"
|
|
echo -e "${CYAN} 🦞 Clawith — First-time Setup${NC}"
|
|
echo -e "${CYAN}═══════════════════════════════════════${NC}"
|
|
echo ""
|
|
|
|
# ── 1. Environment file ──────────────────────────
|
|
echo -e "${YELLOW}[1/6]${NC} Checking environment file..."
|
|
if [ ! -f "$ROOT/.env" ]; then
|
|
cp "$ROOT/.env.example" "$ROOT/.env"
|
|
echo -e " ${GREEN}✓${NC} Created .env from .env.example"
|
|
echo -e " ${YELLOW}⚠${NC} Please edit .env to set SECRET_KEY and JWT_SECRET_KEY before production use."
|
|
else
|
|
echo -e " ${GREEN}✓${NC} .env already exists"
|
|
fi
|
|
|
|
# ── 2. PostgreSQL setup ──────────────────────────
|
|
echo ""
|
|
echo -e "${YELLOW}[2/6]${NC} Setting up PostgreSQL..."
|
|
|
|
# --- Helper: find psql binary ---
|
|
find_psql() {
|
|
# Check PATH first
|
|
if command -v psql &>/dev/null; then
|
|
command -v psql
|
|
return 0
|
|
fi
|
|
# Search common non-standard locations
|
|
local search_paths=(
|
|
"/www/server/pgsql/bin"
|
|
"/usr/local/pgsql/bin"
|
|
"/usr/lib/postgresql/15/bin"
|
|
"/usr/lib/postgresql/14/bin"
|
|
"/usr/lib/postgresql/16/bin"
|
|
"/opt/homebrew/opt/postgresql@15/bin"
|
|
"/opt/homebrew/opt/postgresql/bin"
|
|
)
|
|
for dir in "${search_paths[@]}"; do
|
|
if [ -x "$dir/psql" ]; then
|
|
echo "$dir"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# --- Helper: find a free port starting from $1 ---
|
|
find_free_port() {
|
|
local port=$1
|
|
while ss -tlnp 2>/dev/null | grep -q ":${port} " || \
|
|
lsof -iTCP:${port} -sTCP:LISTEN 2>/dev/null | grep -q LISTEN; do
|
|
echo -e " ${YELLOW}⚠${NC} Port $port is in use, trying $((port+1))..."
|
|
port=$((port+1))
|
|
done
|
|
echo "$port"
|
|
}
|
|
|
|
PG_PORT=5432
|
|
PG_MANAGED_BY_US=false
|
|
|
|
if PG_BIN_DIR=$(find_psql 2>/dev/null); then
|
|
# If find_psql returned a directory (not a full path), add to PATH
|
|
if [ -d "$PG_BIN_DIR" ]; then
|
|
export PATH="$PG_BIN_DIR:$PATH"
|
|
fi
|
|
echo -e " ${GREEN}✓${NC} Found psql: $(which psql)"
|
|
|
|
# Check if PG is running and we can connect
|
|
if pg_isready -h localhost -p 5432 -q 2>/dev/null; then
|
|
echo -e " ${GREEN}✓${NC} PostgreSQL is running on port 5432"
|
|
PG_PORT=5432
|
|
|
|
# Try to create role and database
|
|
ROLE_EXISTS=false
|
|
if psql -h localhost -p $PG_PORT -U "$USER" -d postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='clawith'" 2>/dev/null | grep -q 1; then
|
|
ROLE_EXISTS=true
|
|
echo -e " ${GREEN}✓${NC} Role 'clawith' already exists"
|
|
elif sudo -u postgres psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='clawith'" 2>/dev/null | grep -q 1; then
|
|
ROLE_EXISTS=true
|
|
echo -e " ${GREEN}✓${NC} Role 'clawith' already exists"
|
|
fi
|
|
|
|
if [ "$ROLE_EXISTS" = false ]; then
|
|
# Try 1: as current user
|
|
if createuser -h localhost -p $PG_PORT clawith 2>/dev/null; then
|
|
psql -h localhost -p $PG_PORT -U "$USER" -d postgres -c "ALTER ROLE clawith WITH LOGIN PASSWORD 'clawith';" &>/dev/null
|
|
echo -e " ${GREEN}✓${NC} Created PostgreSQL role: clawith"
|
|
# Try 2: via sudo -u postgres (standard Linux setup)
|
|
elif sudo -u postgres createuser clawith 2>/dev/null && \
|
|
sudo -u postgres psql -c "ALTER ROLE clawith WITH LOGIN PASSWORD 'clawith';" &>/dev/null; then
|
|
echo -e " ${GREEN}✓${NC} Created PostgreSQL role: clawith (via sudo)"
|
|
else
|
|
echo -e " ${YELLOW}⚠${NC} Could not create role in existing PG — will init a local instance"
|
|
PG_BIN_DIR="" # Force local PG setup below
|
|
fi
|
|
fi
|
|
|
|
if [ -n "$PG_BIN_DIR" ] || command -v psql &>/dev/null; then
|
|
DB_EXISTS=false
|
|
if psql -h localhost -p $PG_PORT -U "$USER" -lqt 2>/dev/null | cut -d\| -f1 | grep -qw clawith; then
|
|
DB_EXISTS=true
|
|
elif sudo -u postgres psql -lqt 2>/dev/null | cut -d\| -f1 | grep -qw clawith; then
|
|
DB_EXISTS=true
|
|
fi
|
|
|
|
if [ "$DB_EXISTS" = true ]; then
|
|
echo -e " ${GREEN}✓${NC} Database 'clawith' already exists"
|
|
else
|
|
if createdb -h localhost -p $PG_PORT -O clawith clawith 2>/dev/null || \
|
|
sudo -u postgres createdb -O clawith clawith 2>/dev/null; then
|
|
echo -e " ${GREEN}✓${NC} Created database: clawith"
|
|
fi
|
|
fi
|
|
fi
|
|
else
|
|
echo -e " ${YELLOW}⚠${NC} PostgreSQL binaries found but service is not running on port 5432"
|
|
echo " Will set up a local instance..."
|
|
PG_BIN_DIR="" # Force local PG setup below
|
|
fi
|
|
fi
|
|
|
|
# --- Local PG instance: install + initdb if needed ---
|
|
if [ -z "$PG_BIN_DIR" ] && ! (PGPASSWORD=clawith psql -h localhost -p 5432 -U clawith -d clawith -c "SELECT 1" &>/dev/null); then
|
|
echo -e " ${CYAN}↓${NC} No usable PostgreSQL found — setting up a local instance..."
|
|
PG_MANAGED_BY_US=true
|
|
PGDATA="$ROOT/.pgdata"
|
|
PG_LOCAL="$ROOT/.pg"
|
|
|
|
# Strategy 1: Install via system package manager (most reliable)
|
|
if [ ! -x "$PG_LOCAL/bin/psql" ]; then
|
|
INSTALLED_VIA_PKG=false
|
|
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
|
|
|
|
if [ "$OS" = "darwin" ]; then
|
|
if command -v brew &>/dev/null; then
|
|
echo " Installing PostgreSQL via Homebrew..."
|
|
brew install postgresql@15 2>/dev/null && brew services start postgresql@15 2>/dev/null && INSTALLED_VIA_PKG=true
|
|
else
|
|
echo -e " ${YELLOW}⚠${NC} On macOS, please install Homebrew first, then:"
|
|
echo " brew install postgresql@15 && brew services start postgresql@15"
|
|
echo " Then re-run: bash setup.sh"
|
|
exit 1
|
|
fi
|
|
elif [ "$OS" = "linux" ]; then
|
|
# Check if sudo is available
|
|
CAN_SUDO=false
|
|
if command -v sudo &>/dev/null; then
|
|
if sudo -n true 2>/dev/null || (echo "" | sudo -S true 2>/dev/null); then
|
|
CAN_SUDO=true
|
|
fi
|
|
fi
|
|
|
|
if [ "$CAN_SUDO" = true ]; then
|
|
if command -v apt-get &>/dev/null; then
|
|
echo " Installing PostgreSQL via apt..."
|
|
sudo apt-get update -qq 2>/dev/null
|
|
sudo apt-get install -y -qq postgresql postgresql-client 2>/dev/null && INSTALLED_VIA_PKG=true
|
|
elif command -v yum &>/dev/null; then
|
|
echo " Installing PostgreSQL via yum..."
|
|
sudo yum install -y -q postgresql-server postgresql 2>/dev/null && \
|
|
sudo postgresql-setup --initdb 2>/dev/null; \
|
|
sudo systemctl start postgresql 2>/dev/null && INSTALLED_VIA_PKG=true
|
|
elif command -v dnf &>/dev/null; then
|
|
echo " Installing PostgreSQL via dnf..."
|
|
sudo dnf install -y -q postgresql-server postgresql 2>/dev/null && \
|
|
sudo postgresql-setup --initdb 2>/dev/null; \
|
|
sudo systemctl start postgresql 2>/dev/null && INSTALLED_VIA_PKG=true
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [ "$INSTALLED_VIA_PKG" = true ]; then
|
|
echo -e " ${GREEN}✓${NC} PostgreSQL installed via package manager"
|
|
# Re-find psql after install
|
|
if PG_BIN_DIR=$(find_psql 2>/dev/null); then
|
|
if [ -d "$PG_BIN_DIR" ]; then
|
|
export PATH="$PG_BIN_DIR:$PATH"
|
|
fi
|
|
fi
|
|
# Wait for PG to be ready
|
|
for i in $(seq 1 10); do
|
|
if pg_isready -h localhost -p 5432 -q 2>/dev/null; then
|
|
PG_PORT=5432
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
# Create role and database
|
|
if command -v psql &>/dev/null; then
|
|
if ! psql -h localhost -p $PG_PORT -U postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='clawith'" 2>/dev/null | grep -q 1; then
|
|
sudo -u postgres createuser clawith 2>/dev/null || createuser -h localhost -p $PG_PORT clawith 2>/dev/null || true
|
|
sudo -u postgres psql -c "ALTER ROLE clawith WITH LOGIN PASSWORD 'clawith';" 2>/dev/null || \
|
|
psql -h localhost -p $PG_PORT -U postgres -c "ALTER ROLE clawith WITH LOGIN PASSWORD 'clawith';" 2>/dev/null || true
|
|
echo -e " ${GREEN}✓${NC} Created role: clawith"
|
|
fi
|
|
if ! psql -h localhost -p $PG_PORT -U postgres -lqt 2>/dev/null | cut -d\| -f1 | grep -qw clawith; then
|
|
sudo -u postgres createdb -O clawith clawith 2>/dev/null || createdb -h localhost -p $PG_PORT -O clawith clawith 2>/dev/null || true
|
|
echo -e " ${GREEN}✓${NC} Created database: clawith"
|
|
fi
|
|
PG_MANAGED_BY_US=false # System manages PG now
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Strategy 2: Use system PG binaries from non-standard paths for user-space initdb
|
|
if [ "$INSTALLED_VIA_PKG" != true ] || [ "$PG_MANAGED_BY_US" = true ]; then
|
|
if [ ! -x "$PG_LOCAL/bin/initdb" ]; then
|
|
# Try to link from common system paths
|
|
for dir in /www/server/pgsql /usr/local/pgsql /usr/lib/postgresql/15 /usr/lib/postgresql/14 /usr/lib/postgresql/16; do
|
|
if [ -x "$dir/bin/initdb" ]; then
|
|
mkdir -p "$PG_LOCAL"
|
|
ln -sf "$dir/bin" "$PG_LOCAL/bin" 2>/dev/null || cp -r "$dir/bin" "$PG_LOCAL/bin" 2>/dev/null
|
|
if [ -d "$dir/lib" ]; then
|
|
ln -sf "$dir/lib" "$PG_LOCAL/lib" 2>/dev/null || cp -r "$dir/lib" "$PG_LOCAL/lib" 2>/dev/null
|
|
fi
|
|
if [ -d "$dir/share" ]; then
|
|
ln -sf "$dir/share" "$PG_LOCAL/share" 2>/dev/null || cp -r "$dir/share" "$PG_LOCAL/share" 2>/dev/null
|
|
fi
|
|
echo -e " ${GREEN}✓${NC} Found system PG binaries at $dir"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [ -x "$PG_LOCAL/bin/initdb" ]; then
|
|
export PATH="$PG_LOCAL/bin:$PATH"
|
|
export LD_LIBRARY_PATH="$PG_LOCAL/lib:${LD_LIBRARY_PATH:-}"
|
|
|
|
# Find a free port
|
|
PG_PORT=$(find_free_port 5432)
|
|
|
|
# Initialize data directory
|
|
if [ ! -f "$PGDATA/PG_VERSION" ]; then
|
|
echo " Initializing database cluster..."
|
|
initdb -D "$PGDATA" -U postgres --auth=trust -E UTF8 --locale=C >/dev/null 2>&1
|
|
# Configure port (handle both GNU and BSD sed)
|
|
sed -i "s/#port = 5432/port = $PG_PORT/" "$PGDATA/postgresql.conf" 2>/dev/null || \
|
|
sed -i '' "s/#port = 5432/port = $PG_PORT/" "$PGDATA/postgresql.conf" 2>/dev/null
|
|
sed -i "s/#listen_addresses = 'localhost'/listen_addresses = 'localhost'/" "$PGDATA/postgresql.conf" 2>/dev/null || \
|
|
sed -i '' "s/#listen_addresses = 'localhost'/listen_addresses = 'localhost'/" "$PGDATA/postgresql.conf" 2>/dev/null
|
|
echo -e " ${GREEN}✓${NC} Database cluster initialized (port $PG_PORT)"
|
|
else
|
|
# Read configured port from existing cluster
|
|
PG_PORT=$(grep "^port = " "$PGDATA/postgresql.conf" 2>/dev/null | awk '{print $3}')
|
|
PG_PORT=${PG_PORT:-5432}
|
|
echo -e " ${GREEN}✓${NC} Existing data directory found (port $PG_PORT)"
|
|
fi
|
|
|
|
# Start PostgreSQL
|
|
if ! pg_isready -h localhost -p "$PG_PORT" -q 2>/dev/null; then
|
|
pg_ctl -D "$PGDATA" -l "$PGDATA/pg.log" start >/dev/null 2>&1
|
|
sleep 2
|
|
if pg_isready -h localhost -p "$PG_PORT" -q 2>/dev/null; then
|
|
echo -e " ${GREEN}✓${NC} PostgreSQL started on port $PG_PORT"
|
|
else
|
|
echo -e " ${RED}✗${NC} Failed to start PostgreSQL. Check $PGDATA/pg.log"
|
|
exit 1
|
|
fi
|
|
else
|
|
echo -e " ${GREEN}✓${NC} PostgreSQL already running on port $PG_PORT"
|
|
fi
|
|
|
|
# Create role and database
|
|
if ! psql -h localhost -p "$PG_PORT" -U postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='clawith'" 2>/dev/null | grep -q 1; then
|
|
createuser -h localhost -p "$PG_PORT" -U postgres clawith 2>/dev/null || true
|
|
psql -h localhost -p "$PG_PORT" -U postgres -c "ALTER ROLE clawith WITH LOGIN PASSWORD 'clawith';" &>/dev/null
|
|
echo -e " ${GREEN}✓${NC} Created role: clawith"
|
|
fi
|
|
if ! psql -h localhost -p "$PG_PORT" -U postgres -lqt 2>/dev/null | cut -d\| -f1 | grep -qw clawith; then
|
|
createdb -h localhost -p "$PG_PORT" -U postgres -O clawith clawith 2>/dev/null
|
|
echo -e " ${GREEN}✓${NC} Created database: clawith"
|
|
fi
|
|
else
|
|
echo -e " ${RED}✗${NC} Could not set up PostgreSQL automatically."
|
|
echo ""
|
|
echo " Please install PostgreSQL manually:"
|
|
echo ""
|
|
echo " Ubuntu/Debian: sudo apt install postgresql"
|
|
echo " CentOS/RHEL: sudo yum install postgresql-server"
|
|
echo " macOS: brew install postgresql@15"
|
|
echo ""
|
|
echo " Then re-run: bash setup.sh"
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Ensure DATABASE_URL is correct in .env
|
|
DB_URL="postgresql+asyncpg://clawith:clawith@localhost:${PG_PORT}/clawith?ssl=disable"
|
|
if grep -q "^DATABASE_URL=" "$ROOT/.env" 2>/dev/null; then
|
|
# Update existing DATABASE_URL
|
|
sed -i "s|^DATABASE_URL=.*|DATABASE_URL=${DB_URL}|" "$ROOT/.env" 2>/dev/null || \
|
|
sed -i '' "s|^DATABASE_URL=.*|DATABASE_URL=${DB_URL}|" "$ROOT/.env" 2>/dev/null
|
|
elif grep -q "^# DATABASE_URL=" "$ROOT/.env" 2>/dev/null; then
|
|
# Uncomment and set
|
|
sed -i "s|^# DATABASE_URL=.*|DATABASE_URL=${DB_URL}|" "$ROOT/.env" 2>/dev/null || \
|
|
sed -i '' "s|^# DATABASE_URL=.*|DATABASE_URL=${DB_URL}|" "$ROOT/.env" 2>/dev/null
|
|
else
|
|
echo "DATABASE_URL=${DB_URL}" >> "$ROOT/.env"
|
|
fi
|
|
echo -e " ${GREEN}✓${NC} DATABASE_URL set (port $PG_PORT)"
|
|
|
|
# ── 3. Backend setup ─────────────────────────────
|
|
echo ""
|
|
echo -e "${YELLOW}[3/6]${NC} Setting up backend..."
|
|
cd "$ROOT/backend"
|
|
|
|
if [ ! -d ".venv" ]; then
|
|
echo " Creating Python virtual environment..."
|
|
$PYTHON_BIN -m venv .venv
|
|
echo -e " ${GREEN}✓${NC} Virtual environment created"
|
|
fi
|
|
|
|
if [ "$INSTALL_DEV" = true ]; then
|
|
PIP_TARGET=".[dev]"
|
|
echo " Installing dependencies with dev extras (this may take 2-5 minutes)..."
|
|
else
|
|
PIP_TARGET="."
|
|
echo " Installing dependencies (this may take 1-2 minutes)..."
|
|
fi
|
|
if .venv/bin/pip install -e "$PIP_TARGET" "${PIP_INSTALL_ARGS[@]}" 2>&1; then
|
|
echo -e " ${GREEN}✓${NC} Backend dependencies installed"
|
|
else
|
|
echo -e " ${RED}✗${NC} Failed to install backend dependencies."
|
|
echo " Try manually: cd backend && .venv/bin/pip install -e '$PIP_TARGET'"
|
|
exit 1
|
|
fi
|
|
|
|
# ── 4. Frontend setup ────────────────────────────
|
|
echo ""
|
|
echo -e "${YELLOW}[4/6]${NC} Setting up frontend..."
|
|
cd "$ROOT/frontend"
|
|
|
|
if [ ! -d "node_modules" ]; then
|
|
if ! command -v npm &>/dev/null; then
|
|
echo -e " ${YELLOW}⚠${NC} npm not found. Skipping frontend dependency install."
|
|
echo -e " ${YELLOW}⚠${NC} Install Node.js 20+ to enable frontend dev server."
|
|
echo -e " ${YELLOW}⚠${NC} You can still use pre-built dist/ or Docker for frontend."
|
|
else
|
|
echo " Installing npm packages..."
|
|
npm install --silent $NPM_MIRROR 2>&1 | tail -1
|
|
echo -e " ${GREEN}✓${NC} Frontend dependencies installed"
|
|
fi
|
|
else
|
|
echo -e " ${GREEN}✓${NC} Frontend dependencies already installed"
|
|
fi
|
|
|
|
# ── 5. Database setup ────────────────────────────
|
|
echo ""
|
|
echo -e "${YELLOW}[5/6]${NC} Setting up database..."
|
|
cd "$ROOT/backend"
|
|
|
|
# Source .env for DATABASE_URL
|
|
if [ -f "$ROOT/.env" ]; then
|
|
set -a
|
|
source "$ROOT/.env"
|
|
set +a
|
|
fi
|
|
|
|
# ── 6. Seed data ─────────────────────────────────
|
|
echo ""
|
|
echo -e "${YELLOW}[6/6]${NC} Running database seed..."
|
|
|
|
if .venv/bin/python seed.py 2>&1 | while IFS= read -r line; do echo " $line"; done; then
|
|
echo ""
|
|
else
|
|
echo ""
|
|
echo -e " ${RED}✗ Seed failed.${NC}"
|
|
echo " Common fixes:"
|
|
echo " 1. Make sure PostgreSQL is running"
|
|
echo " 2. Set DATABASE_URL in .env, e.g.:"
|
|
echo " DATABASE_URL=postgresql+asyncpg://clawith:clawith@localhost:5432/clawith?ssl=disable"
|
|
echo " 3. Create the database first:"
|
|
echo " createdb clawith"
|
|
echo " 4. If you see 'Ident authentication failed', configure pg_hba.conf:"
|
|
echo " Add this line BEFORE other host rules:"
|
|
echo " host all clawith 127.0.0.1/32 md5"
|
|
echo " Then reload: sudo systemctl reload postgresql"
|
|
echo ""
|
|
echo " After fixing, re-run: bash setup.sh"
|
|
exit 1
|
|
fi
|
|
|
|
# ── Summary ──────────────────────────────────────
|
|
SERVER_IP=$(get_server_ip)
|
|
|
|
echo ""
|
|
echo -e "${GREEN}═══════════════════════════════════════${NC}"
|
|
echo -e "${GREEN} 🎉 Setup complete!${NC}"
|
|
echo -e "${GREEN}═══════════════════════════════════════${NC}"
|
|
echo ""
|
|
echo " To start the application:"
|
|
echo ""
|
|
echo -e " ${CYAN}Option A: One-command start${NC}"
|
|
echo " bash restart.sh"
|
|
echo ""
|
|
echo -e " ${CYAN}Option B: Manual start${NC}"
|
|
echo " # Terminal 1 — Backend"
|
|
echo " cd backend && .venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 8008"
|
|
echo ""
|
|
echo " # Terminal 2 — Frontend"
|
|
echo " cd frontend && npx vite --host 0.0.0.0 --port 3008"
|
|
echo ""
|
|
echo -e " ${CYAN}Option C: Docker${NC}"
|
|
echo " docker compose up -d"
|
|
echo ""
|
|
echo -e " ${CYAN}Access URLs:${NC}"
|
|
echo " Local: http://localhost:3008"
|
|
echo " Network: http://${SERVER_IP}:3008"
|
|
echo ""
|
|
echo " The first user to register becomes the platform admin."
|
|
echo ""
|