File size: 8,488 Bytes
722781c | 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 | #!/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
|