server / start.sh
pabla1322's picture
Upload 17 files
722781c verified
Raw
History Blame Contribute Delete
8.49 kB
#!/bin/bash
# Minecraft Bedrock server startup script for HuggingFace Spaces
# No set -e — we handle errors explicitly
LOG_DIR="/data/logs"
MC_DIR="/data/bedrock-server"
SCRIPTS_DIR="/data/scripts"
PLAYIT_LOG="$PLAYIT_HOME/playit.log"
MC_LOG="$LOG_DIR/minecraft.log"
STATUS_FILE="/tmp/mc_status.json"
mkdir -p "$LOG_DIR"
# ── Write initial status ──────────────────────────────────────────────
write_status() {
cat > "$STATUS_FILE" <<EOF
{
"mc_online": ${MC_ONLINE:-false},
"playit_online": ${PLAYIT_ONLINE:-false},
"tunnel_address": "${TUNNEL_ADDR:-}",
"started_at": "${STARTED_AT:-}",
"uptime": "$(uptime -p 2>/dev/null || echo 'unknown')"
}
EOF
}
MC_ONLINE=false
PLAYIT_ONLINE=false
TUNNEL_ADDR=""
STARTED_AT=$(date -Iseconds)
write_status
# ── Graceful shutdown handler ─────────────────────────────────────────
shutdown_handler() {
echo ""
echo "$(date) [SHUTDOWN] Signal received — shutting down gracefully..."
# Stop Minecraft
if [ -n "$MC_PID" ] && kill -0 "$MC_PID" 2>/dev/null; then
echo "$(date) [SHUTDOWN] Stopping Minecraft (PID $MC_PID)..."
kill -SIGTERM "$MC_PID"
wait "$MC_PID" 2>/dev/null
echo "$(date) [SHUTDOWN] Minecraft stopped."
fi
# Stop playit
if [ -n "$PLAYIT_PID" ] && kill -0 "$PLAYIT_PID" 2>/dev/null; then
echo "$(date) [SHUTDOWN] Stopping playit (PID $PLAYIT_PID)..."
kill -SIGTERM "$PLAYIT_PID"
wait "$PLAYIT_PID" 2>/dev/null
fi
# Final backup before exit
echo "$(date) [SHUTDOWN] Running final backup..."
bash "$SCRIPTS_DIR/backup.sh" || true
echo "$(date) [SHUTDOWN] Done. Goodbye!"
exit 0
}
trap 'shutdown_handler' SIGTERM SIGINT SIGHUP
# ── Banner ────────────────────────────────────────────────────────────
echo "======================================================="
echo " ⛏️ Alpha MC — Minecraft Bedrock Server"
echo "======================================================="
echo " Started : $(date)"
echo " CPU : $(nproc) cores"
echo " RAM : $(free -h | awk '/Mem:/{print $3 " used / " $2 " total"}')"
echo " Disk : $(df -h /data | awk 'NR==2{print $3 " used / " $2 " total (" $5 " full)"}')"
echo "======================================================="
echo ""
# ── Validate SECRET_KEY ───────────────────────────────────────────────
if [ -z "$SECRET_KEY" ]; then
echo "╔══════════════════════════════════════════════════════╗"
echo "║ ⚠️ WARNING: SECRET_KEY is not set! ║"
echo "║ Tunnel will NOT work. ║"
echo "║ Add it in: Space Settings → Repository Secrets ║"
echo "╚══════════════════════════════════════════════════════╝"
fi
# ── Status dashboard on port 7860 (keeps HF from pausing) ────────────
echo "[*] Starting status dashboard on port 7860..."
python3 "$MC_DIR/status_server.py" > "$LOG_DIR/status_server.log" 2>&1 &
STATUS_PID=$!
echo "[OK] Status dashboard started (PID $STATUS_PID) → visit the Space URL!"
# ── Cron daemon ───────────────────────────────────────────────────────
service cron start 2>/dev/null && echo "[OK] Cron started" || echo "[!] Cron unavailable (non-fatal)"
crontab /data/crontab.txt 2>/dev/null || true
# ── Setup playit.gg tunnel ────────────────────────────────────────────
mkdir -p "$PLAYIT_HOME"
cat > "$PLAYIT_HOME/playit.toml" << 'EOF'
[tunnel.minecraft-bedrock]
type = "minecraft-bedrock"
local_ip = "127.0.0.1"
local_port = 19132
EOF
> "$PLAYIT_LOG"
echo "[*] Starting playit tunnel agent..."
playit --secret "$SECRET_KEY" >> "$PLAYIT_LOG" 2>&1 &
PLAYIT_PID=$!
echo "[OK] playit started (PID $PLAYIT_PID)"
# ── Wait for tunnel to establish ──────────────────────────────────────
echo ""
echo "══════════════ WAITING FOR PLAYIT TUNNEL ══════════════"
FOUND=0
for i in $(seq 2 2 180); do
sleep 2
if ! kill -0 "$PLAYIT_PID" 2>/dev/null; then
echo "[!] playit crashed. Log:"
tail -20 "$PLAYIT_LOG"
echo "[!] Will continue without tunnel — restart Space to retry."
break
fi
CLAIM=$(grep -oE 'https://playit\.gg/claim/[A-Za-z0-9_=+-]+' "$PLAYIT_LOG" 2>/dev/null | head -1)
if [ -n "$CLAIM" ]; then
echo ""
echo "╔══════════════════════════════════════════════════════╗"
echo "║ 🔗 CLAIM YOUR TUNNEL — open this URL: ║"
echo "║ $CLAIM"
echo "║ Tunnel will activate after you visit the link. ║"
echo "╚══════════════════════════════════════════════════════╝"
FOUND=1
PLAYIT_ONLINE=true
break
fi
ADDR=$(grep -oE '[a-z0-9-]+\.playit\.gg(:[0-9]+)?' "$PLAYIT_LOG" 2>/dev/null | head -1)
if [ -n "$ADDR" ]; then
echo ""
echo "╔══════════════════════════════════════════════════════╗"
echo "║ ✅ TUNNEL IS LIVE! ║"
echo "║ Connect in Minecraft: $ADDR"
echo "╚══════════════════════════════════════════════════════╝"
TUNNEL_ADDR="$ADDR"
FOUND=1
PLAYIT_ONLINE=true
break
fi
echo " [${i}s] waiting for tunnel..."
done
if [ "$FOUND" -eq 0 ]; then
echo "[!] No tunnel after 180s. Continuing anyway."
tail -20 "$PLAYIT_LOG"
fi
# ── Start Minecraft Bedrock server ────────────────────────────────────
echo ""
echo "[*] Starting Minecraft Bedrock server..."
cd "$MC_DIR"
./bedrock_server >> "$MC_LOG" 2>&1 &
MC_PID=$!
# Wait a moment and confirm it's running
sleep 3
if kill -0 "$MC_PID" 2>/dev/null; then
echo "[OK] Minecraft started (PID $MC_PID)"
MC_ONLINE=true
else
echo "[!] Minecraft failed to start. Check logs: $MC_LOG"
tail -20 "$MC_LOG"
fi
write_status
# ── Background services ───────────────────────────────────────────────
"$SCRIPTS_DIR/monitor.sh" &
echo "[OK] Monitor started (PID $!)"
"$SCRIPTS_DIR/health_check.sh" &
echo "[OK] Health check started (PID $!)"
echo ""
echo "══════════════════════════════════════════════════════"
echo " 🎮 Server is running! Dashboard at the Space URL."
echo "══════════════════════════════════════════════════════"
echo ""
# ── Keep container alive, refresh status every 30s ───────────────────
while true; do
sleep 30
# Update online status
if kill -0 "$MC_PID" 2>/dev/null; then
MC_ONLINE=true
else
MC_ONLINE=false
echo "$(date) [WARN] Minecraft not running — health_check.sh will restart it."
fi
if kill -0 "$PLAYIT_PID" 2>/dev/null; then
PLAYIT_ONLINE=true
else
PLAYIT_ONLINE=false
fi
write_status
done