Repository navigation
Expand file tree
/
Copy pathstart.sh
More file actions
executable file
·158 lines (140 loc) · 5.59 KB
/
Copy pathstart.sh
File metadata and controls
executable file
·158 lines (140 loc) · 5.59 KB
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/usr/bin/env bash
set -e
# HeartMuLa Studio — Start Script
# Starts both backend (FastAPI) and frontend (Next.js) servers
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PIDFILE_BACKEND="$SCRIPT_DIR/.backend.pid"
PIDFILE_FRONTEND="$SCRIPT_DIR/.frontend.pid"
BACKEND_PORT=8000
FRONTEND_PORT=3000
BACKEND_HOST="0.0.0.0"
RED='\033[0;31m'
GREEN='\033[0;32m'
CYAN='\033[0;36m'
YELLOW='\033[1;33m'
BOLD='\033[1m'
NC='\033[0m'
echo ""
echo -e "${CYAN}${BOLD} ╔══════════════════════════════════════╗${NC}"
echo -e "${CYAN}${BOLD} ║ HeartMuLa Studio v0.1.0 ║${NC}"
echo -e "${CYAN}${BOLD} ║ AI Music Generation Studio ║${NC}"
echo -e "${CYAN}${BOLD} ╚══════════════════════════════════════╝${NC}"
echo ""
# Check for existing processes
if [ -f "$PIDFILE_BACKEND" ] && kill -0 "$(cat "$PIDFILE_BACKEND")" 2>/dev/null; then
echo -e "${YELLOW}Backend is already running (PID $(cat "$PIDFILE_BACKEND"))${NC}"
echo -e "Run ${BOLD}./stop.sh${NC} first to restart."
exit 1
fi
if [ -f "$PIDFILE_FRONTEND" ] && kill -0 "$(cat "$PIDFILE_FRONTEND")" 2>/dev/null; then
echo -e "${YELLOW}Frontend is already running (PID $(cat "$PIDFILE_FRONTEND"))${NC}"
echo -e "Run ${BOLD}./stop.sh${NC} first to restart."
exit 1
fi
# Check dependencies
echo -e "${BOLD}Checking dependencies...${NC}"
if ! command -v uv &>/dev/null; then
echo -e "${RED}Error: uv is not installed. Install it: https://docs.astral.sh/uv/${NC}"
exit 1
fi
if ! command -v pnpm &>/dev/null; then
echo -e "${RED}Error: pnpm is not installed. Install it: npm install -g pnpm${NC}"
exit 1
fi
echo -e " ${GREEN}✓${NC} uv $(uv --version 2>/dev/null | head -1)"
echo -e " ${GREEN}✓${NC} pnpm $(pnpm --version 2>/dev/null)"
echo ""
# Ensure dependencies are installed
echo -e "${BOLD}Installing backend dependencies...${NC}"
echo -e " ${YELLOW}(This may take a while on first run — PyTorch is ~2GB)${NC}"
(cd "$SCRIPT_DIR/backend" && uv sync)
echo -e " ${GREEN}✓${NC} Backend dependencies"
echo ""
echo -e "${BOLD}Installing frontend dependencies...${NC}"
(cd "$SCRIPT_DIR/frontend" && pnpm install)
echo -e " ${GREEN}✓${NC} Frontend dependencies"
echo ""
# Create data directories
mkdir -p "$SCRIPT_DIR/backend/data/outputs" "$SCRIPT_DIR/backend/data/uploads"
# Start backend
echo -e "${BOLD}Starting backend...${NC}"
cd "$SCRIPT_DIR/backend"
PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True \
uv run uvicorn app.main:app --host "$BACKEND_HOST" --port "$BACKEND_PORT" \
> "$SCRIPT_DIR/.backend.log" 2>&1 &
BACKEND_PID=$!
echo "$BACKEND_PID" > "$PIDFILE_BACKEND"
# Wait for backend to be ready
echo -e " Waiting for backend (loading model, may take 1-2 min)..."
ELAPSED=0
for i in $(seq 1 120); do
if curl -sf "http://127.0.0.1:$BACKEND_PORT/api/health" > /dev/null 2>&1; then
echo -e " ${GREEN}✓${NC} Backend running (PID $BACKEND_PID) — ready in ${ELAPSED}s"
break
fi
# Check if process died
if ! kill -0 "$BACKEND_PID" 2>/dev/null; then
echo -e " ${RED}✗ Backend process died after ${ELAPSED}s${NC}"
echo -e " ${RED} Last log lines:${NC}"
tail -5 "$SCRIPT_DIR/.backend.log" 2>/dev/null | sed 's/^/ /'
rm -f "$PIDFILE_BACKEND"
exit 1
fi
# Show last log line periodically so user knows it's working
if [ $((i % 5)) -eq 0 ]; then
LAST_LINE=$(tail -1 "$SCRIPT_DIR/.backend.log" 2>/dev/null | cut -c1-80)
if [ -n "$LAST_LINE" ]; then
echo -e " ${CYAN}[${ELAPSED}s]${NC} $LAST_LINE"
fi
fi
sleep 2
ELAPSED=$((ELAPSED + 2))
if [ "$i" -eq 120 ]; then
echo -e " ${RED}✗ Backend timed out after ${ELAPSED}s${NC}"
echo -e " ${RED} Last log lines:${NC}"
tail -5 "$SCRIPT_DIR/.backend.log" 2>/dev/null | sed 's/^/ /'
kill "$BACKEND_PID" 2>/dev/null
rm -f "$PIDFILE_BACKEND"
exit 1
fi
done
# Start frontend
echo -e "${BOLD}Starting frontend...${NC}"
cd "$SCRIPT_DIR/frontend"
pnpm dev --port "$FRONTEND_PORT" > "$SCRIPT_DIR/.frontend.log" 2>&1 &
FRONTEND_PID=$!
echo "$FRONTEND_PID" > "$PIDFILE_FRONTEND"
# Wait for frontend to be ready
echo -n " Waiting for frontend"
for i in $(seq 1 30); do
if curl -sf "http://127.0.0.1:$FRONTEND_PORT" > /dev/null 2>&1; then
echo ""
echo -e " ${GREEN}✓${NC} Frontend running (PID $FRONTEND_PID)"
break
fi
echo -n "."
sleep 1
if [ "$i" -eq 30 ]; then
echo ""
echo -e " ${YELLOW}! Frontend may still be compiling. Check .frontend.log${NC}"
break
fi
done
# Get local IP
LOCAL_IP=$(hostname -I 2>/dev/null | awk '{print $1}' || echo "127.0.0.1")
# Print summary
echo ""
echo -e "${GREEN}${BOLD} ┌──────────────────────────────────────┐${NC}"
echo -e "${GREEN}${BOLD} │ Studio is ready! │${NC}"
echo -e "${GREEN}${BOLD} └──────────────────────────────────────┘${NC}"
echo ""
echo -e " ${BOLD}Frontend:${NC} http://localhost:${FRONTEND_PORT}"
echo -e " ${BOLD}Backend:${NC} http://localhost:${BACKEND_PORT}"
echo -e " ${BOLD}API Docs:${NC} http://localhost:${BACKEND_PORT}/docs"
if [ "$LOCAL_IP" != "127.0.0.1" ]; then
echo -e " ${BOLD}Network:${NC} http://${LOCAL_IP}:${FRONTEND_PORT}"
fi
echo ""
echo -e " ${BOLD}Logs:${NC} .backend.log / .frontend.log"
echo -e " ${BOLD}Stop:${NC} ./stop.sh"
echo ""