@@ -10,6 +10,64 @@ YELLOW='\033[1;33m'
1010CYAN=' \033[0;36m'
1111NC=' \033[0m'
1212
13+ MEDIA_DIR=" $HOME /Media"
14+ INSTALL_DIR=" $HOME /mac-media-stack"
15+ NON_INTERACTIVE=false
16+
17+ usage () {
18+ cat << EOF
19+ Usage: bash bootstrap.sh [OPTIONS]
20+
21+ Options:
22+ --media-dir DIR Media root path (default: ~/Media)
23+ --install-dir DIR Repo install directory (default: ~/mac-media-stack)
24+ --non-interactive Skip interactive prompts (manual Seerr wiring required)
25+ --help Show this help message
26+
27+ Examples:
28+ bash bootstrap.sh
29+ bash bootstrap.sh --media-dir /Volumes/T9/Media
30+ bash bootstrap.sh --media-dir /Volumes/T9/Media --non-interactive
31+ EOF
32+ }
33+
34+ while [[ $# -gt 0 ]]; do
35+ case " $1 " in
36+ --media-dir)
37+ if [[ $# -lt 2 || " $2 " == --* ]]; then
38+ echo " Missing value for --media-dir"
39+ exit 1
40+ fi
41+ MEDIA_DIR=" $2 "
42+ shift 2
43+ ;;
44+ --install-dir)
45+ if [[ $# -lt 2 || " $2 " == --* ]]; then
46+ echo " Missing value for --install-dir"
47+ exit 1
48+ fi
49+ INSTALL_DIR=" $2 "
50+ shift 2
51+ ;;
52+ --non-interactive)
53+ NON_INTERACTIVE=true
54+ shift
55+ ;;
56+ --help|-h)
57+ usage
58+ exit 0
59+ ;;
60+ * )
61+ echo " Unknown option: $1 "
62+ usage
63+ exit 1
64+ ;;
65+ esac
66+ done
67+
68+ MEDIA_DIR=" ${MEDIA_DIR/# \~ / $HOME } "
69+ INSTALL_DIR=" ${INSTALL_DIR/# \~ / $HOME } "
70+
1371echo " "
1472echo " =============================="
1573echo " Mac Media Stack Installer"
@@ -51,6 +109,26 @@ detect_running_runtime() {
51109 fi
52110}
53111
112+ wait_for_service () {
113+ local name=" $1 "
114+ local url=" $2 "
115+ local max_attempts=" ${3:- 45} "
116+ local attempt=0
117+
118+ while [[ $attempt -lt $max_attempts ]]; do
119+ status=$( curl -s -o /dev/null -w " %{http_code}" --max-time 3 " $url " 2> /dev/null || true)
120+ if [[ " $status " =~ ^(200| 301| 302| 401| 403)$ ]]; then
121+ echo -e " ${GREEN} OK${NC} $name is reachable"
122+ return 0
123+ fi
124+ sleep 2
125+ attempt=$(( attempt + 1 ))
126+ done
127+
128+ echo -e " ${YELLOW} WARN${NC} $name is not reachable yet (continuing anyway)"
129+ return 1
130+ }
131+
54132INSTALLED_RUNTIME=$( detect_installed_runtime)
55133
56134if ! docker info & > /dev/null; then
@@ -85,10 +163,12 @@ if ! command -v git &>/dev/null; then
85163 exit 1
86164fi
87165
166+ echo " "
167+ echo " Install dir: $INSTALL_DIR "
168+ echo " Media dir: $MEDIA_DIR "
88169echo " "
89170
90171# Clone
91- INSTALL_DIR=" $HOME /mac-media-stack"
92172if [[ -d " $INSTALL_DIR " ]]; then
93173 echo -e " ${YELLOW} Note:${NC} $INSTALL_DIR already exists. Pulling latest..."
94174 if ! git -C " $INSTALL_DIR " pull --ff-only; then
@@ -107,46 +187,69 @@ echo ""
107187
108188# Setup
109189echo -e " ${CYAN} Running setup...${NC} "
110- bash scripts/setup.sh
190+ bash scripts/setup.sh --media-dir " $MEDIA_DIR "
111191
112192echo " "
113193
114194# VPN keys
115195if grep -q " your_wireguard_private_key_here" .env 2> /dev/null; then
116- echo -e " ${CYAN} VPN Configuration${NC} "
117- echo " "
118- echo " You need your ProtonVPN WireGuard credentials."
119- echo " If someone gave you a private key and address, enter them now."
120- echo " "
121- read -s -p " WireGuard Private Key: " vpn_key
122- echo " "
123- read -p " WireGuard Address (e.g. 10.2.0.2/32): " vpn_addr
124-
125- if [[ -n " $vpn_key " && -n " $vpn_addr " ]]; then
126- sed -i ' ' " s|WIREGUARD_PRIVATE_KEY=.*|WIREGUARD_PRIVATE_KEY=$vpn_key |" .env
127- sed -i ' ' " s|WIREGUARD_ADDRESSES=.*|WIREGUARD_ADDRESSES=$vpn_addr |" .env
128- echo -e " ${GREEN} VPN keys saved${NC} "
196+ if [[ " $NON_INTERACTIVE " == true ]]; then
197+ echo -e " ${YELLOW} WARN${NC} Non-interactive mode: VPN placeholders still present in .env"
198+ echo " Update WIREGUARD_PRIVATE_KEY and WIREGUARD_ADDRESSES before using the stack."
129199 else
130- echo -e " ${YELLOW} Skipped.${NC} Edit .env manually before starting."
131- echo " Run: open -a TextEdit $INSTALL_DIR /.env"
200+ echo -e " ${CYAN} VPN Configuration${NC} "
201+ echo " "
202+ echo " You need your ProtonVPN WireGuard credentials."
203+ echo " If someone gave you a private key and address, enter them now."
204+ echo " "
205+ read -s -p " WireGuard Private Key: " vpn_key
206+ echo " "
207+ read -p " WireGuard Address (e.g. 10.2.0.2/32): " vpn_addr
208+
209+ if [[ -n " $vpn_key " && -n " $vpn_addr " ]]; then
210+ sed -i ' ' " s|WIREGUARD_PRIVATE_KEY=.*|WIREGUARD_PRIVATE_KEY=$vpn_key |" .env
211+ sed -i ' ' " s|WIREGUARD_ADDRESSES=.*|WIREGUARD_ADDRESSES=$vpn_addr |" .env
212+ echo -e " ${GREEN} VPN keys saved${NC} "
213+ else
214+ echo -e " ${YELLOW} Skipped.${NC} Edit .env manually before starting."
215+ echo " Run: open -a TextEdit $INSTALL_DIR /.env"
216+ fi
132217 fi
133218fi
134219
135220echo " "
136221
222+ # Preflight
223+ echo -e " ${CYAN} Running preflight checks...${NC} "
224+ if ! bash scripts/doctor.sh --media-dir " $MEDIA_DIR " ; then
225+ echo " "
226+ echo -e " ${RED} Preflight checks failed.${NC} Fix the FAIL items above, then re-run bootstrap."
227+ exit 1
228+ fi
229+
230+ echo " "
231+
137232# Start stack
138233echo -e " ${CYAN} Starting media stack...${NC} "
139234echo " (First run downloads ~2-3 GB, this may take a few minutes)"
140235echo " "
141236docker compose up -d
142237
143238echo " "
144- echo " Waiting 30 seconds for services to initialize..."
145- sleep 30
239+ echo " Waiting for core services..."
240+ wait_for_service " qBittorrent" " http://localhost:8080" || true
241+ wait_for_service " Prowlarr" " http://localhost:9696" || true
242+ wait_for_service " Radarr" " http://localhost:7878" || true
243+ wait_for_service " Sonarr" " http://localhost:8989" || true
244+ wait_for_service " Seerr" " http://localhost:5055" || true
146245
147246# Configure
148247echo " "
149- bash scripts/configure.sh
248+ if [[ " $NON_INTERACTIVE " == true ]]; then
249+ bash scripts/configure.sh --non-interactive
250+ else
251+ bash scripts/configure.sh
252+ fi
150253
151254# Auto-heal
152255echo " "
@@ -161,7 +264,9 @@ echo ""
161264echo " Seerr (browse/request): http://localhost:5055"
162265echo " Plex (watch): http://localhost:32400/web"
163266echo " "
267+ echo " Media location: $MEDIA_DIR "
268+ echo " "
164269echo " Next: Set up Plex libraries (Settings > Libraries > Add)"
165- echo " - Movies: ~/Media /Movies"
166- echo " - TV Shows: ~/Media /TV Shows"
270+ echo " - Movies: $MEDIA_DIR /Movies"
271+ echo " - TV Shows: $MEDIA_DIR /TV Shows"
167272echo " "
0 commit comments