File size: 4,097 Bytes
e1d8498
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/usr/bin/env bash
# ─────────────────────────────────────────────────────────────────────────────
# AI Gateway Hub β€” Quick Setup Script
# ─────────────────────────────────────────────────────────────────────────────
set -euo pipefail

BOLD="\033[1m"
GREEN="\033[32m"
CYAN="\033[36m"
YELLOW="\033[33m"
RED="\033[31m"
RESET="\033[0m"

header() { echo -e "\n${BOLD}${CYAN}β–Ά $1${RESET}"; }
ok()     { echo -e "  ${GREEN}βœ“${RESET} $1"; }
warn()   { echo -e "  ${YELLOW}⚠${RESET} $1"; }
err()    { echo -e "  ${RED}βœ—${RESET} $1"; exit 1; }

echo -e "${BOLD}${GREEN}"
cat <<'EOF'
   _   _____   _____       _                           _   _       _
  /_\ |_   _| |  __ \     | |                         | | | |     | |
 / _ \  | |   | |  \/ __ _| |_ _____      ____ _ _   _| |_| |_   _| |__
/ ___ \ | |   | | __ / _` | __/ _ \ \ /\ / / _` | | | |  _  | | | | '_ \
\/_/\_\|_|   | |_\ \ (_| | ||  __/\ V  V / (_| | |_| | | | | |_| | |_) |
             \____/\__,_|\__\___| \_/\_/ \__,_|\__, \_| |_/\__,_|_.__/
                                                __/ |
                                               |___/
EOF
echo -e "${RESET}"

header "Checking prerequisites"
command -v docker   &>/dev/null || err "Docker is not installed. https://docs.docker.com/get-docker/"
docker compose version &>/dev/null 2>&1 || \
  docker-compose version &>/dev/null 2>&1 || err "Docker Compose is not installed."
ok "Docker $(docker --version | awk '{print $3}' | tr -d ',')"
ok "Docker Compose available"

header "Setting up environment"
if [ ! -f .env ]; then
  cp .env.example .env

  # BUG FIX #11: The original fallback used `xxd` which is not present in many
  # minimal Linux images (Alpine, BusyBox-based). Replaced with `od` which is
  # POSIX-standard and universally available. The `openssl rand -hex` path is
  # still the primary method; `od` is only the fallback.
  gen_hex() {
    local bytes=$1
    openssl rand -hex "$bytes" 2>/dev/null || \
      od -An -N"$bytes" -tx1 /dev/urandom 2>/dev/null | tr -d ' \n'
  }

  MASTER_KEY="sk-gateway-$(gen_hex 16)"
  JWT_SECRET="$(gen_hex 32)"

  sed -i.bak "s/sk-gateway-master-key-change-me/${MASTER_KEY}/" .env
  sed -i.bak "s/super-secret-jwt-key-change-in-production/${JWT_SECRET}/" .env
  rm -f .env.bak
  ok ".env created with random secrets"
else
  warn ".env already exists β€” skipping"
fi

header "Creating SSL directory"
mkdir -p nginx/ssl
ok "nginx/ssl/ created"

header "Building and starting services"
docker compose pull litellm 2>/dev/null || true
docker compose build --parallel
docker compose up -d

header "Waiting for services to be healthy"
echo -n "  Waiting"
for i in $(seq 1 30); do
  sleep 2
  echo -n "."
  if curl -sf http://localhost/api/health &>/dev/null; then
    echo ""
    ok "Gateway is ready!"
    break
  fi
  if [ "$i" -eq 30 ]; then
    echo ""
    warn "Timeout waiting for health check. Check logs: docker compose logs"
  fi
done

echo ""
echo -e "${BOLD}${GREEN}═══════════════════════════════════════════════════${RESET}"
echo -e "${BOLD}  πŸš€ AI Gateway Hub is running!${RESET}"
echo ""
echo -e "  ${CYAN}Web UI:${RESET}         http://localhost"
echo -e "  ${CYAN}API Endpoint:${RESET}   http://localhost/v1"
echo -e "  ${CYAN}Management API:${RESET} http://localhost/api"
echo ""
echo -e "  ${YELLOW}Next steps:${RESET}"
echo -e "  1. Open http://localhost in your browser"
echo -e "  2. Click 'Add Model' to register your first AI model"
echo -e "  3. Use the generated endpoint with any OpenAI SDK"
echo -e "${BOLD}${GREEN}═══════════════════════════════════════════════════${RESET}"