-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdocker_entrypoint.sh
More file actions
executable file
·676 lines (552 loc) · 26 KB
/
docker_entrypoint.sh
File metadata and controls
executable file
·676 lines (552 loc) · 26 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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
#!/bin/bash
set -e
# ==============================================================================
# Haven Start9 Entrypoint Script
# ==============================================================================
# Color codes for output
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
log_info() {
echo -e "${GREEN}[INFO]${NC} $1" >&2
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1" >&2
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1" >&2
}
log_debug() {
echo -e "${CYAN}[DEBUG]${NC} $1" >&2
}
# ==============================================================================
# Signal Handling for Graceful Shutdown
# ==============================================================================
cleanup() {
log_info "Received shutdown signal, cleaning up..."
# Kill Haven process gracefully
if [ ! -z "$HAVEN_PID" ] && kill -0 $HAVEN_PID 2>/dev/null; then
log_info "Stopping Haven..."
kill -TERM $HAVEN_PID
wait $HAVEN_PID 2>/dev/null || true
fi
# Kill Tor process
if [ ! -z "$TOR_PID" ] && kill -0 $TOR_PID 2>/dev/null; then
log_info "Stopping Tor..."
kill -TERM $TOR_PID
wait $TOR_PID 2>/dev/null || true
fi
log_info "Shutdown complete"
exit 0
}
trap cleanup SIGTERM SIGINT SIGQUIT
# ==============================================================================
# Environment File Generation
# ==============================================================================
generate_env_file() {
log_info "Generating Haven configuration from Start9 environment..."
cat > /app/.env <<EOF
# ==============================================================================
# Haven Configuration (Generated by Start9)
# ==============================================================================
# Owner Configuration
OWNER_NPUB=${OWNER_NPUB}
# Database Configuration
DB_ENGINE=${DB_ENGINE:-badger}
# Blossom Storage
BLOSSOM_PATH=/data/blossom/
# Relay Configuration
RELAY_URL=${TOR_ADDRESS}
RELAY_PORT=3355
RELAY_BIND_ADDRESS=0.0.0.0
RELAY_VERSION=${RELAY_VERSION:-1.2.3}
# Private Relay Configuration
PRIVATE_RELAY_NAME=${PRIVATE_RELAY_NAME:-Haven Private}
PRIVATE_RELAY_NPUB=${OWNER_NPUB}
PRIVATE_RELAY_DESCRIPTION=${PRIVATE_RELAY_DESCRIPTION:-My private relay}
PRIVATE_RELAY_ICON=${PRIVATE_RELAY_ICON:-}
# Chat Relay Configuration
CHAT_RELAY_NAME=${CHAT_RELAY_NAME:-Haven Chat}
CHAT_RELAY_NPUB=${OWNER_NPUB}
CHAT_RELAY_DESCRIPTION=${CHAT_RELAY_DESCRIPTION:-My chat relay}
CHAT_RELAY_ICON=${CHAT_RELAY_ICON:-}
CHAT_RELAY_WOT_DEPTH=${CHAT_RELAY_WOT_DEPTH:-2}
CHAT_RELAY_WOT_REFRESH_INTERVAL_HOURS=${CHAT_RELAY_WOT_REFRESH_INTERVAL_HOURS:-24}
CHAT_RELAY_MINIMUM_FOLLOWERS=${CHAT_RELAY_MINIMUM_FOLLOWERS:-10}
# Outbox Relay Configuration
OUTBOX_RELAY_NAME=${OUTBOX_RELAY_NAME:-Haven Outbox}
OUTBOX_RELAY_NPUB=${OWNER_NPUB}
OUTBOX_RELAY_DESCRIPTION=${OUTBOX_RELAY_DESCRIPTION:-My outbox relay}
OUTBOX_RELAY_ICON=${OUTBOX_RELAY_ICON:-}
# Inbox Relay Configuration
INBOX_RELAY_NAME=${INBOX_RELAY_NAME:-Haven Inbox}
INBOX_RELAY_NPUB=${OWNER_NPUB}
INBOX_RELAY_DESCRIPTION=${INBOX_RELAY_DESCRIPTION:-My inbox relay}
INBOX_RELAY_ICON=${INBOX_RELAY_ICON:-}
INBOX_PULL_INTERVAL_SECONDS=${INBOX_PULL_INTERVAL_SECONDS:-3600}
# Event Size Limits (in bytes)
PRIVATE_RELAY_MAX_EVENT_SIZE=${PRIVATE_RELAY_MAX_EVENT_SIZE:-131072}
CHAT_RELAY_MAX_EVENT_SIZE=${CHAT_RELAY_MAX_EVENT_SIZE:-131072}
OUTBOX_RELAY_MAX_EVENT_SIZE=${OUTBOX_RELAY_MAX_EVENT_SIZE:-131072}
INBOX_RELAY_MAX_EVENT_SIZE=${INBOX_RELAY_MAX_EVENT_SIZE:-131072}
# Kind-Specific Event Size Limits
PRIVATE_RELAY_ENABLE_KIND_SPECIFIC_LIMITS=${ENABLE_KIND_SPECIFIC_LIMITS:-true}
CHAT_RELAY_ENABLE_KIND_SPECIFIC_LIMITS=false
OUTBOX_RELAY_ENABLE_KIND_SPECIFIC_LIMITS=${ENABLE_KIND_SPECIFIC_LIMITS:-true}
INBOX_RELAY_ENABLE_KIND_SPECIFIC_LIMITS=${ENABLE_KIND_SPECIFIC_LIMITS:-true}
PRIVATE_RELAY_MAX_LONG_FORM_SIZE=${MAX_LONG_FORM_CONTENT_SIZE:-1048576}
CHAT_RELAY_MAX_LONG_FORM_SIZE=${MAX_LONG_FORM_CONTENT_SIZE:-1048576}
OUTBOX_RELAY_MAX_LONG_FORM_SIZE=${MAX_LONG_FORM_CONTENT_SIZE:-1048576}
INBOX_RELAY_MAX_LONG_FORM_SIZE=${MAX_LONG_FORM_CONTENT_SIZE:-1048576}
# Import Settings
IMPORT_START_DATE=${IMPORT_START_DATE:-}
IMPORT_OWNER_NOTES_FETCH_TIMEOUT_SECONDS=${IMPORT_OWNER_NOTES_TIMEOUT:-30}
IMPORT_TAGGED_NOTES_FETCH_TIMEOUT_SECONDS=${IMPORT_TAGGED_NOTES_TIMEOUT:-120}
IMPORT_QUERY_INTERVAL_SECONDS=${IMPORT_QUERY_INTERVAL:-360000}
IMPORT_SEED_RELAYS_FILE=/app/relays_import.json
BLASTR_RELAYS_FILE=/app/relays_blastr.json
# Backup Configuration
BACKUP_PROVIDER=${BACKUP_PROVIDER:-none}
BACKUP_INTERVAL_HOURS=${BACKUP_INTERVAL_HOURS:-24}
# Advanced Settings
WOT_FETCH_TIMEOUT_SECONDS=30
HAVEN_LOG_LEVEL=${LOG_LEVEL:-INFO}
EOF
log_info "Configuration file generated successfully"
}
# ==============================================================================
# Configuration Validation
# ==============================================================================
validate_config() {
log_info "Validating configuration..."
if [ -z "$OWNER_NPUB" ]; then
log_error "OWNER_NPUB is not set. Please configure your Nostr public key."
exit 1
fi
# Validate npub format (starts with npub1)
if [[ ! "$OWNER_NPUB" =~ ^npub1[a-z0-9]{58}$ ]]; then
log_error "Invalid OWNER_NPUB format. Must start with 'npub1' and be 63 characters long."
exit 1
fi
log_info "Configuration validated successfully"
}
# ==============================================================================
# Relay List Initialization
# ==============================================================================
initialize_relay_lists() {
log_info "Initializing relay lists..."
# Check if config file exists
if [ ! -f /data/start9/config.yaml ]; then
log_warn "Config file not found at /data/start9/config.yaml"
echo "[]" > /app/relays_import.json
echo "[]" > /app/relays_blastr.json
log_info "Relay lists initialized (no config)"
return
fi
# Import seed relays from config
log_info "Reading import seed relays configuration..."
local import_relays=""
import_relays=$(yq e '.["import-seed-relays"] // ""' /data/start9/config.yaml 2>&1)
local yq_exit=$?
log_debug "Import seed relays - yq exit code: $yq_exit"
log_debug "Raw import relays value: '$import_relays'"
if [ $yq_exit -eq 0 ] && [ -n "$import_relays" ] && [ "$import_relays" != "null" ]; then
log_info "Processing import seed relay list from config..."
local import_jq_result
import_jq_result=$(echo "$import_relays" | jq -R 'split(",") | map(gsub("^\\s+|\\s+$";"")) | map(select(length > 0))' 2>&1)
local import_jq_exit=$?
if [ $import_jq_exit -eq 0 ]; then
echo "$import_jq_result" > /app/relays_import.json
local import_relay_count=$(echo "$import_jq_result" | jq '. | length' 2>/dev/null || echo "0")
log_info "✅ Import seed relays configured: $import_relay_count relay(s)"
# Show relay list for debugging
log_debug "Import relay list details:"
echo "$import_jq_result" | jq -r '.[]' 2>/dev/null | while read -r relay; do
log_debug " • $relay"
done
else
log_error "Failed to parse import relay list with jq: $import_jq_result"
echo "[]" > /app/relays_import.json
fi
else
log_info "No import seed relays configured (empty or null)"
echo "[]" > /app/relays_import.json
fi
# Blastr relay list from config
log_info "Reading blastr relay configuration..."
# Check if config file exists
if [ ! -f /data/start9/config.yaml ]; then
log_warn "Config file not found at /data/start9/config.yaml"
echo "[]" > /app/relays_blastr.json
log_info "Relay lists initialized (no config)"
return
fi
log_debug "Config file exists, reading blastr-relays..."
# Read the raw config value
local blastr_relays=""
blastr_relays=$(yq e '.["blastr-relays"] // ""' /data/start9/config.yaml 2>&1)
local yq_exit=$?
log_debug "yq exit code: $yq_exit"
log_debug "Raw value from yq: '$blastr_relays'"
if [ $yq_exit -ne 0 ]; then
log_error "Failed to read config with yq: $blastr_relays"
echo "[]" > /app/relays_blastr.json
log_info "Relay lists initialized (yq error)"
return
fi
# Check if we got a valid value
if [ -z "$blastr_relays" ] || [ "$blastr_relays" = "null" ]; then
log_info "No blastr relays configured (empty or null)"
echo "[]" > /app/relays_blastr.json
log_info "Relay lists initialized (empty config)"
return
fi
log_info "Processing blastr relay list from config..."
log_info "Raw blastr_relays value: '$blastr_relays'"
# Convert comma-separated string to JSON array using jq
# Split by comma, trim whitespace, filter empty strings
local jq_result
jq_result=$(echo "$blastr_relays" | jq -R 'split(",") | map(gsub("^\\s+|\\s+$";"")) | map(select(length > 0))' 2>&1)
local jq_exit=$?
log_debug "jq exit code: $jq_exit"
log_debug "jq result: $jq_result"
if [ $jq_exit -eq 0 ]; then
echo "$jq_result" > /app/relays_blastr.json
local relay_count=$(echo "$jq_result" | jq '. | length' 2>/dev/null || echo "0")
log_info "✅ Blastr relays configured: $relay_count relay(s)"
log_info "Blastr relay list content: $(cat /app/relays_blastr.json)"
else
log_error "Failed to parse blastr relay list with jq: $jq_result"
echo "[]" > /app/relays_blastr.json
fi
# Ensure files have correct permissions
chmod 644 /app/relays_import.json /app/relays_blastr.json 2>/dev/null || true
log_info "Relay lists initialized"
}
# ==============================================================================
# IPv6 Connectivity Check
# ==============================================================================
check_ipv6() {
log_info "Checking IPv6 connectivity..."
# Check if IPv6 is available in the kernel
if [ -f /proc/net/if_inet6 ]; then
log_info "✅ IPv6 kernel support detected"
# Show IPv6 addresses
if command -v ip >/dev/null 2>&1; then
local ipv6_addrs=$(ip -6 addr show 2>/dev/null | grep -c "inet6")
if [ "$ipv6_addrs" -gt 0 ]; then
log_info "✅ IPv6 addresses configured: $ipv6_addrs"
ip -6 addr show 2>/dev/null | grep "inet6" | head -3 | while read line; do
log_debug " $line"
done
else
log_warn "⚠️ No IPv6 addresses found"
fi
fi
# Test IPv6 connectivity (optional, may timeout in some environments)
log_debug "Testing IPv6 connectivity to google.com..."
if ping6 -c 1 -W 2 google.com >/dev/null 2>&1; then
log_info "✅ IPv6 internet connectivity confirmed"
else
log_warn "⚠️ IPv6 internet connectivity test failed (may work through Tor)"
fi
else
log_warn "⚠️ IPv6 is NOT available (Blastr to IPv6-only relays will fail)"
log_warn "⚠️ This is normal in some Docker/Start9 environments"
fi
}
# ==============================================================================
# Tor Hidden Service Setup
# ==============================================================================
start_tor() {
log_info "Starting Tor Hidden Service..."
# Ensure /data/tor/haven directory exists with correct permissions
if [ ! -d /data/tor/haven ]; then
log_info "Creating Tor data directory at /data/tor/haven..."
mkdir -p /data/tor/haven
chown -R haven:haven /data/tor
chmod 700 /data/tor/haven
fi
# Check if this is a first-time setup or restore
if [ -f /data/tor/haven/hostname ]; then
log_info "Existing .onion address found (will reuse)"
else
log_info "No existing .onion address found (will generate new one)"
fi
# Start Tor in background as haven user
su-exec haven tor -f /etc/tor/torrc &
TOR_PID=$!
# Wait for Tor to generate/load .onion address (max 30 seconds)
TIMEOUT=30
ELAPSED=0
while [ ! -f /data/tor/haven/hostname ] && [ $ELAPSED -lt $TIMEOUT ]; do
log_debug "Waiting for Tor to generate .onion address... ($ELAPSED/$TIMEOUT seconds)"
sleep 2
ELAPSED=$((ELAPSED + 2))
done
if [ ! -f /data/tor/haven/hostname ]; then
log_error "Tor failed to generate .onion address within $TIMEOUT seconds"
exit 1
fi
# Read and export Tor address
export TOR_ADDRESS=$(cat /data/tor/haven/hostname)
log_info "Tor Hidden Service started"
log_info "Your .onion address: ${GREEN}${TOR_ADDRESS}${NC}"
# Try to write TOR address to file for properties script (optional)
if echo "$TOR_ADDRESS" > /data/tor_address.txt 2>/dev/null; then
log_info "Saved Tor address to /data/tor_address.txt"
else
log_warn "Could not write /data/tor_address.txt (will use environment variable instead)"
fi
}
# ==============================================================================
# Haven Application Startup
# ==============================================================================
start_haven() {
log_info "Starting Haven relay server..."
# Check if this is an import run
if [ "$RUN_IMPORT" = "true" ]; then
log_info "=========================================="
log_info " Running in IMPORT MODE"
log_info "=========================================="
log_info "Import configuration:"
log_info " • Start date: ${IMPORT_START_DATE:-not set}"
log_info " • Owner timeout: ${IMPORT_OWNER_NOTES_TIMEOUT:-30}s"
log_info " • Tagged timeout: ${IMPORT_TAGGED_NOTES_TIMEOUT:-120}s"
# Count relays from JSON file
if [ -f /app/relays_import.json ]; then
local relay_count=$(jq '. | length' /app/relays_import.json 2>/dev/null || echo "0")
log_info " • Seed relays: $relay_count"
if [ "$relay_count" -gt 0 ]; then
log_debug "Configured import relays:"
jq -r '.[]' /app/relays_import.json 2>/dev/null | while read -r relay; do
log_debug " → $relay"
done
fi
fi
log_info ""
log_info "This may take a long time depending on:"
log_info " • Amount of historical data"
log_info " • Number of seed relays"
log_info " • Network speed"
log_info ""
log_info "Starting import process..."
log_info "=========================================="
log_info ""
# Create a temporary log file to capture Haven output
IMPORT_LOG_FILE="/tmp/haven-import-$$.log"
# Start Haven in background and capture output
su-exec haven /app/haven --import 2>&1 | tee "$IMPORT_LOG_FILE" &
HAVEN_PID=$!
log_info "Haven import started with PID: $HAVEN_PID"
log_info "Monitoring import progress..."
# Monitor Haven logs for completion message
IMPORT_COMPLETE=false
TIMEOUT=7200 # 2 hours max
ELAPSED=0
while kill -0 $HAVEN_PID 2>/dev/null; do
sleep 5
ELAPSED=$((ELAPSED + 5))
# Check if import completion message appears in log
if [ -f "$IMPORT_LOG_FILE" ] && grep -q "tagged import complete" "$IMPORT_LOG_FILE"; then
log_info "✅ Import completion detected!"
IMPORT_COMPLETE=true
# Give Haven a moment to finish writing logs
sleep 5
# Stop Haven gracefully
log_info "Stopping Haven..."
kill -TERM $HAVEN_PID 2>/dev/null || true
sleep 3
# Force kill if still running
if kill -0 $HAVEN_PID 2>/dev/null; then
kill -KILL $HAVEN_PID 2>/dev/null || true
fi
break
fi
# Timeout check
if [ $ELAPSED -ge $TIMEOUT ]; then
log_error "Import timeout after ${TIMEOUT}s"
kill -TERM $HAVEN_PID 2>/dev/null || true
sleep 2
kill -KILL $HAVEN_PID 2>/dev/null || true
break
fi
done
# Cleanup temp log file
rm -f "$IMPORT_LOG_FILE"
log_info ""
log_info "=========================================="
if [ "$IMPORT_COMPLETE" = "true" ]; then
log_info "✅ Import completed successfully!"
# Remove import request flag
if [ -f /data/import-requested ]; then
rm -f /data/import-requested
log_info "Import flag cleared"
fi
log_info "Restarting Haven in normal mode..."
log_info "=========================================="
log_info ""
# Unset import flag and restart
unset RUN_IMPORT
# Re-execute entrypoint to start Haven normally
exec /usr/local/bin/docker_entrypoint.sh
else
log_error "❌ Import failed or timed out"
log_error "Import flag NOT cleared. Check logs and fix issues."
log_error "Restart Haven after fixing the issues."
log_info "=========================================="
exit 1
fi
fi
# Start Haven in background as haven user
su-exec haven /app/haven &
HAVEN_PID=$!
log_info "Haven started with PID: $HAVEN_PID"
log_info ""
log_info "=========================================="
log_info " 🚀 Haven is now running!"
log_info "=========================================="
log_info ""
log_info "Relay URLs:"
log_info " Outbox: ${CYAN}ws://${TOR_ADDRESS}${NC}"
log_info " Private: ${CYAN}ws://${TOR_ADDRESS}/private${NC}"
log_info " Chat: ${CYAN}ws://${TOR_ADDRESS}/chat${NC}"
log_info " Inbox: ${CYAN}ws://${TOR_ADDRESS}/inbox${NC}"
log_info ""
log_info "Blossom Server:"
log_info " URL: ${CYAN}http://${TOR_ADDRESS}${NC}"
log_info ""
log_info "=========================================="
log_info ""
# Wait for Haven process
wait $HAVEN_PID
EXIT_CODE=$?
log_info "Haven stopped with exit code: $EXIT_CODE"
return $EXIT_CODE
}
# ==============================================================================
# Main Execution
# ==============================================================================
main() {
log_info "=========================================="
log_info " Haven for Start9 Server"
log_info " Version: ${RELAY_VERSION:-1.2.3}"
log_info "=========================================="
log_info ""
# Setup /data directory permissions for haven user
log_info "Setting up data directory permissions..."
# Ensure /data is writable by haven user
chown -R haven:haven /data 2>/dev/null || log_warn "Could not change /data ownership (may be restricted by Start9)"
# Try to create subdirectories as root, then change ownership
for dir in db blossom backups start9 tor; do
if [ ! -d "/data/$dir" ]; then
mkdir -p "/data/$dir" 2>/dev/null && chown haven:haven "/data/$dir" 2>/dev/null || log_info "Directory /data/$dir will be created by Haven if needed"
fi
done
# Create symlink from /app/db to /data/db for database persistence
# Haven stores databases in ./db/ (relative to /app), but we need them in /data/db
log_info "Setting up database symlink..."
if [ ! -L /app/db ] && [ ! -d /app/db ]; then
ln -sf /data/db /app/db
log_info "Created symlink: /app/db -> /data/db"
elif [ -L /app/db ]; then
log_debug "Database symlink already exists"
elif [ -d /app/db ] && [ ! -L /app/db ]; then
log_warn "/app/db exists as directory, not symlink. Migrating..."
# Backup old db if it exists
if [ "$(ls -A /app/db 2>/dev/null)" ]; then
mv /app/db /app/db.backup.$(date +%s)
log_info "Backed up old /app/db directory"
else
rm -rf /app/db
fi
ln -sf /data/db /app/db
log_info "Created symlink: /app/db -> /data/db"
fi
# Load configuration from Start9 (standard location)
if [ -f /data/start9/config.yaml ]; then
log_info "Loading configuration from Start9..."
# Extract configuration values using yq
export OWNER_NPUB=$(yq e '.owner-npub' /data/start9/config.yaml)
export DB_ENGINE=$(yq e '.db-engine // "badger"' /data/start9/config.yaml)
export LMDB_MAPSIZE=$(yq e '.lmdb-mapsize // ""' /data/start9/config.yaml)
export RELAY_VERSION="1.2.3"
export PRIVATE_RELAY_NAME=$(yq e '.private-relay-name // "Haven Private"' /data/start9/config.yaml)
export PRIVATE_RELAY_DESCRIPTION=$(yq e '.private-relay-description // "My private relay"' /data/start9/config.yaml)
export CHAT_RELAY_NAME=$(yq e '.chat-relay-name // "Haven Chat"' /data/start9/config.yaml)
export CHAT_RELAY_DESCRIPTION=$(yq e '.chat-relay-description // "My chat relay"' /data/start9/config.yaml)
export CHAT_RELAY_WOT_DEPTH=$(yq e '.chat-wot-depth // "2"' /data/start9/config.yaml)
export CHAT_RELAY_WOT_REFRESH_INTERVAL_HOURS=$(yq e '.chat-wot-refresh-interval // "24"' /data/start9/config.yaml)
export CHAT_RELAY_MINIMUM_FOLLOWERS=$(yq e '.chat-minimum-followers // "10"' /data/start9/config.yaml)
export OUTBOX_RELAY_NAME=$(yq e '.outbox-relay-name // "Haven Outbox"' /data/start9/config.yaml)
export OUTBOX_RELAY_DESCRIPTION=$(yq e '.outbox-relay-description // "My outbox relay"' /data/start9/config.yaml)
export INBOX_RELAY_NAME=$(yq e '.inbox-relay-name // "Haven Inbox"' /data/start9/config.yaml)
export INBOX_RELAY_DESCRIPTION=$(yq e '.inbox-relay-description // "My inbox relay"' /data/start9/config.yaml)
export INBOX_PULL_INTERVAL_SECONDS=$(yq e '.inbox-pull-interval // "3600"' /data/start9/config.yaml)
# Max Event Sizes (convert from KB to bytes)
PRIVATE_MAX_KB=$(yq e '.private-relay-max-event-size // "128"' /data/start9/config.yaml)
export PRIVATE_RELAY_MAX_EVENT_SIZE=$((PRIVATE_MAX_KB * 1024))
CHAT_MAX_KB=$(yq e '.chat-relay-max-event-size // "128"' /data/start9/config.yaml)
export CHAT_RELAY_MAX_EVENT_SIZE=$((CHAT_MAX_KB * 1024))
OUTBOX_MAX_KB=$(yq e '.outbox-relay-max-event-size // "128"' /data/start9/config.yaml)
export OUTBOX_RELAY_MAX_EVENT_SIZE=$((OUTBOX_MAX_KB * 1024))
INBOX_MAX_KB=$(yq e '.inbox-relay-max-event-size // "128"' /data/start9/config.yaml)
export INBOX_RELAY_MAX_EVENT_SIZE=$((INBOX_MAX_KB * 1024))
# Kind-Specific Size Limits
export ENABLE_KIND_SPECIFIC_LIMITS=$(yq e '.enable-kind-specific-limits // "true"' /data/start9/config.yaml)
LONG_FORM_MAX_KB=$(yq e '.max-long-form-content-size // "1024"' /data/start9/config.yaml)
export MAX_LONG_FORM_CONTENT_SIZE=$((LONG_FORM_MAX_KB * 1024))
export IMPORT_START_DATE=$(yq e '.import-start-date // ""' /data/start9/config.yaml)
export IMPORT_SEED_RELAYS=$(yq e '.import-seed-relays // ""' /data/start9/config.yaml)
export IMPORT_OWNER_NOTES_TIMEOUT=$(yq e '.import-owner-notes-timeout // "30"' /data/start9/config.yaml)
export IMPORT_TAGGED_NOTES_TIMEOUT=$(yq e '.import-tagged-notes-timeout // "120"' /data/start9/config.yaml)
export IMPORT_QUERY_INTERVAL=$(yq e '.import-query-interval // "360000"' /data/start9/config.yaml)
export BACKUP_PROVIDER=$(yq e '.backup-provider // "none"' /data/start9/config.yaml)
export BACKUP_INTERVAL_HOURS=$(yq e '.backup-interval // "24"' /data/start9/config.yaml)
export LOG_LEVEL=$(yq e '.log-level // "INFO"' /data/start9/config.yaml)
log_info "Configuration loaded successfully"
else
log_warn "Start9 configuration file not found at /data/start9/config.yaml"
log_warn "Using default values and environment variables"
fi
# Check for action arguments
echo "DEBUG: Checking action arguments: \$1=$1" >&2
if [ "$1" = "import-notes" ]; then
log_info "Action: import-notes detected"
echo "DEBUG: Action matched! Preparing to run importNotes.sh" >&2
echo "DEBUG: Environment variables to be passed:" >&2
echo " OWNER_NPUB=${OWNER_NPUB}" >&2
echo " IMPORT_START_DATE=${IMPORT_START_DATE}" >&2
echo " IMPORT_SEED_RELAYS=${IMPORT_SEED_RELAYS}" >&2
echo " IMPORT_OWNER_NOTES_TIMEOUT=${IMPORT_OWNER_NOTES_TIMEOUT}" >&2
echo " IMPORT_TAGGED_NOTES_TIMEOUT=${IMPORT_TAGGED_NOTES_TIMEOUT}" >&2
# Export config for importNotes.sh
export CONFIG_FILE="/data/start9/config.yaml"
echo "DEBUG: CONFIG_FILE=${CONFIG_FILE}" >&2
echo "DEBUG: Executing importNotes.sh..." >&2
# Run import notes action
exec /usr/local/bin/importNotes.sh
fi
echo "DEBUG: No action matched, continuing with normal startup" >&2
# Check for import request flag
if [ -f /data/import-requested ]; then
log_info "Import request detected from action"
export RUN_IMPORT=true
fi
# Run initialization steps
validate_config
check_ipv6
initialize_relay_lists
# Start Tor (must start before generating .env since TOR_ADDRESS is needed)
start_tor
# Generate configuration after TOR_ADDRESS is available
generate_env_file
# Start Haven application
start_haven
# Exit with Haven's exit code
exit $?
}
# Run main function with arguments
main "$@"