File size: 20,686 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
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
# 📖 Alpha MC — Complete Setup Guide
> Everything explained: what every file does, how to set it up, and how it all works together.

---

## 📋 Table of Contents
1. [How It All Works](#how-it-all-works)
2. [File-by-File Explanation](#file-by-file-explanation)
3. [Step-by-Step Setup](#step-by-step-setup)
4. [HuggingFace Secrets Reference](#huggingface-secrets-reference)
5. [Google Drive Backup Setup](#google-drive-backup-setup)
6. [How to Connect and Play](#how-to-connect-and-play)
7. [Troubleshooting](#troubleshooting)
8. [FAQ](#faq)

---

## How It All Works

```
┌─────────────────────────────────────────────────────┐
│              HuggingFace Space (Docker)              │
│                                                      │
│  ┌──────────────┐    ┌─────────────────────────┐    │
│  │  Minecraft   │    │  Status Dashboard        │    │
│  │  Bedrock     │    │  (port 7860, HTTP)       │    │
│  │  Server      │    │  Shows: status, logs,    │    │
│  │  (UDP 19132) │    │  tunnel address, RAM/CPU │    │
│  └──────┬───────┘    └─────────────────────────┘    │
│         │                                            │
│  ┌──────▼───────┐    ┌─────────────────────────┐    │
│  │  playit.gg   │    │  Cron Jobs               │    │
│  │  agent       │    │  - Backup every 6 hours  │    │
│  │  (tunnel)    │    │  - Log rotation weekly   │    │
│  └──────┬───────┘    └─────────────────────────┘    │
└─────────┼───────────────────────────────────────────┘
          │ UDP tunnel

   playit.gg servers


   Your friends' Minecraft (anywhere in the world)
```

**Why playit.gg?** HuggingFace Spaces only expose HTTP (TCP) ports publicly. Minecraft Bedrock uses UDP, which HF doesn't support directly. playit.gg acts as a free UDP tunnel — the Minecraft server connects outward to playit.gg, and players connect to playit.gg's address.

**Why port 7860?** HuggingFace watches this port. If nothing responds on 7860, it marks your Space as "idle" and pauses it. Our status dashboard runs on 7860 and keeps it alive.

---

## File-by-File Explanation

### 🐳 `Dockerfile`
The main blueprint Docker uses to build your container.

**What it does, line by line:**
- `FROM ubuntu:22.04` — Starts with a clean Ubuntu Linux environment
- `ENV DEBIAN_FRONTEND=noninteractive` — Stops apt-get from asking questions during install
- `apt-get install` — Installs tools: curl/wget (downloading), unzip (extracting), python3 (status server + Drive backup), cron (scheduled jobs)
- `pip install` — Installs Python libraries for Google Drive API
- `mkdir -p` — Creates the folder structure: `/data/bedrock-server/`, `/data/scripts/`, `/data/logs/`, `/data/playit_gg/`
- `COPY prepare.sh ... && RUN bash prepare.sh` — Runs the download script at build time (downloads Minecraft + playit)
- `WORKDIR /data/bedrock-server` — Sets the default directory (fixes the path bug from before)
- `COPY server.properties allowlist.json permissions.json ./` — Copies game config INTO the server folder
- `COPY start.sh run.sh status_server.py ./` — Copies startup scripts into server folder
- `COPY backup.sh ... /data/scripts/` — Copies utility scripts to their own folder
- `chmod +x` — Makes all `.sh` scripts executable (runnable)
- `EXPOSE 7860 19132/udp 19133/udp` — Declares which ports the container uses
- `CMD ["bash", "/data/bedrock-server/start.sh"]` — The command that runs when the container starts

---

### 🔧 `prepare.sh`
Runs **once during Docker build** to download Minecraft and playit.

**What it does:**
1. Fetches the Minecraft.net download page with a browser-like User-Agent (so the site doesn't block it)
2. Tries 3 different URL patterns to extract the Bedrock server download link (in case the page layout changes)
3. Downloads the `.zip` with retry logic (retries up to 4 times with exponential backoff: 5s, 10s, 20s)
4. Extracts it to `/data/bedrock-server/`
5. Downloads the latest `playit-linux-amd64` binary from GitHub releases
6. Makes both executables

**Why it runs at build time:** So the Minecraft server binary is baked into the Docker image. Every time your Space restarts, Minecraft is already there — no download wait.

---

### 🚀 `start.sh`
The **main startup script** — this is what runs every time your Space starts.

**What it does, in order:**
1. **Sets up graceful shutdown** — catches SIGTERM signal (when HF stops the container), runs a final backup, stops Minecraft cleanly before exiting
2. **Prints a banner** with system info (CPU cores, RAM, disk)
3. **Warns if SECRET_KEY is missing** so you know immediately if the tunnel won't work
4. **Starts `status_server.py`** on port 7860 — the live dashboard (also prevents HF from pausing the Space)
5. **Starts cron daemon** for scheduled backups and log rotation
6. **Configures playit.toml** — tells playit.gg which local port to tunnel (19132 UDP)
7. **Starts the playit agent** with your SECRET_KEY
8. **Waits up to 180 seconds** for the tunnel to show a claim URL or live address, printing progress every 2 seconds
9. **Starts `bedrock_server`** (the actual Minecraft process), redirecting its output to `/data/logs/minecraft.log`
10. **Starts monitor.sh and health_check.sh** in the background
11. **Keeps running** in a loop, updating the status JSON file every 30 seconds and watching if Minecraft/playit are still alive

**Key fixes from original:**
- No `set -e` (crashes won't kill the whole script)
- Proper SIGTERM trap for graceful shutdown
- Status JSON written continuously so the dashboard has fresh data

---

### 🌐 `status_server.py`
A Python HTTP server that serves a **live web dashboard** on port 7860.

**What it shows:**
- 🟢/🔴 Server online/offline status
- RAM usage (used / total)
- Disk usage (used / total / percent)
- CPU load average
- Tunnel address to copy into Minecraft
- Last 40 lines of the Minecraft server log (auto-scrolled)

**How it works:**
- Reads `/tmp/mc_status.json` (written by `start.sh` every 30 seconds)
- Reads the last 40 lines of `/data/logs/minecraft.log` using the `tail` command
- Reads the playit log to extract the tunnel address
- Generates a full HTML page on every request
- Page auto-refreshes every 15 seconds via a `<meta refresh>` tag
- No dependencies needed beyond Python's built-in `http.server`

**Why this matters:** Without something running on port 7860, HuggingFace marks your Space as idle within minutes and pauses it. This keeps it alive 24/7.

---

### ⚙️ `server.properties`
The Minecraft Bedrock server configuration file.

| Setting | Value | Explanation |
|---|---|---|
| `server-name` | Gaganpreet's Minecraft Server | Name shown in the server browser |
| `gamemode` | survival | Players are in survival mode |
| `difficulty` | hard | Hard difficulty |
| `allow-cheats` | false | No commands like /gamemode |
| `max-players` | 20 | Up to 20 players at once |
| `online-mode` | true | Requires legitimate Xbox/Microsoft account |
| `white-list` | false | Anyone can join (set to true + edit allowlist.json to restrict) |
| `server-port` | 19132 | Main UDP port (IPv4) |
| `server-portv6` | 19133 | IPv6 UDP port |
| `view-distance` | 10 | Chunks loaded around each player |
| `tick-distance` | 4 | Active simulation distance |
| `player-idle-timeout` | 30 | Kick players idle for 30 minutes |
| `level-name` | Bedrock level | Name of the world folder |
| `level-seed` | *(blank)* | Random seed — fill in a number for a specific world |
| `server-authoritative-movement` | server-auth | Server controls player movement (anti-cheat) |

---

### 📋 `allowlist.json`
Controls who can join if `white-list=true` in server.properties.

**Default:** Empty array `[]` — whitelist is disabled so anyone can join.

**To add a player:**
```json
[
  {
    "ignoresPlayerLimit": false,
    "name": "PlayerGamerTag",
    "xuid": "2535123456789"
  }
]
```
Get a player's XUID from sites like xuidgrabber.com.

---

### 🔑 `permissions.json`
Sets operator/member/visitor permissions for specific players.

**Default:** Empty `[]` — everyone gets the `default-player-permission-level` from server.properties.

**To make someone an operator:**
```json
[
  {
    "permission": "operator",
    "xuid": "2535123456789"
  }
]
```

---

### 💾 `backup.sh`
Creates world backups locally and optionally uploads to Google Drive.

**What it does:**
1. Checks if the worlds folder exists and has data
2. Creates a `.tar.gz` archive of the entire `worlds/` folder with a timestamp in the filename (e.g. `world_20240425_143000.tar.gz`)
3. Saves it to `/data/bedrock-server/backups/`
4. Prunes old backups — keeps only the 10 most recent
5. If `GDRIVE_SA_KEY` secret is set → calls `google_drive_backup.py` to upload the new backup to Google Drive
6. If `GDRIVE_SA_KEY` is not set → logs a helpful message and skips Drive upload gracefully

**Run manually:** `bash /data/scripts/backup.sh`

---

### ☁️ `google_drive_backup.py`
Uploads the latest backup `.tar.gz` to a Google Drive folder using a **Service Account** (no browser, works headlessly).

**How it's different from the original:**
- Original used `InstalledAppFlow` → needs a browser popup → **impossible in Docker**
- New version uses a **Service Account** → authenticates silently using a JSON key stored as a base64 HF Secret
- Supports **resumable uploads** with 5 MB chunks → handles large world files reliably
- Shows upload progress percentage
- Auto-deletes oldest Drive backups beyond 10 files
- Cleans up the temp credentials file after upload

**Required HF Secret:** `GDRIVE_SA_KEY` (base64-encoded service account JSON — see setup below)

---

### 🏥 `health_check.sh`
Runs in the background and **automatically restarts** Minecraft or playit if either crashes.

**What it does (every 30 seconds):**
1. Checks if `bedrock_server` process is running — if not, restarts it
2. Checks if `playit` process is running — if not, restarts it with your SECRET_KEY
3. Logs all events with timestamps to `/data/logs/health.log`

**Why this matters:** Without this, if Minecraft crashes at 3am while your friends are playing, the server stays down until you manually restart the Space. With this, it auto-recovers within 30 seconds.

---

### 📊 `monitor.sh`
Logs system resource stats every 60 seconds to `/data/logs/monitor.log`.

**Each log line contains:** timestamp, CPU load average, RAM used/total, disk used/total, Minecraft PID, playit PID.

Useful for diagnosing performance issues or seeing exactly when the server went down.

---

### 🔄 `auto_restart.sh`
A simple utility script to restart Minecraft after a delay.

**Usage:** `bash /data/scripts/auto_restart.sh 10` — restarts after 10 seconds
Called automatically by health_check.sh when needed.

---

### 🕐 `crontab.txt`
Schedules automatic recurring tasks using cron.

```
0 */6 * * *   bash /data/scripts/backup.sh
```
→ Runs backup.sh every 6 hours (at 00:00, 06:00, 12:00, 18:00)

```
0 0 * * 0   truncate -s 0 /data/logs/*.log
```
→ Every Sunday at midnight, clears all log files so they don't grow forever

---

### 🗺️ `run.sh`
A simple wrapper that changes directory to the Minecraft server folder and runs `start.sh`. Kept for compatibility.

---

### 🔧 `setup_google_drive.sh`
Run this **on your own computer** (not on HuggingFace) to walk through the Google Cloud setup and generate your `GDRIVE_SA_KEY`. It even base64-encodes the key file for you automatically if `service-account.json` is in the same folder.

---

## Step-by-Step Setup

### Step 1 — Upload all files to HuggingFace

1. Go to your Space: `https://huggingface.co/spaces/Gagan1322/alpha_mc`
2. Click **Files** tab → **Add file****Upload files**
3. Upload ALL of these files:
   ```
   Dockerfile
   README.md
   prepare.sh
   start.sh
   run.sh
   status_server.py
   server.properties
   allowlist.json
   permissions.json
   backup.sh
   monitor.sh
   health_check.sh
   auto_restart.sh
   crontab.txt
   google_drive_backup.py
   setup_google_drive.sh
   ```
4. Commit the changes

---

### Step 2 — Add your playit Secret Key

1. Go to your Space → **Settings** tab → **Repository secrets**
2. Click **New secret**
3. Name: `SECRET_KEY`
4. Value: your playit agent secret key from `https://playit.gg/account/agents`
   - **Regenerate your key first!** The old one was exposed in a screenshot.
5. Click **Add secret**

---

### Step 3 — Restart the Space

1. Go to the **App** tab of your Space
2. Click the **⋮** (three dots) menu → **Restart Space**
3. Wait 2-3 minutes for the Docker image to build (first time only)
4. The Space URL will show your live status dashboard

---

### Step 4 — Get the Tunnel Address

1. Open the Space URL in your browser
2. Look at the dashboard — when the tunnel is live, the **Connect Address** section shows something like:
   ```
   abc123.playit.gg:12345
   ```
3. If it shows a **claim URL** instead:
   - Click that URL → sign into playit.gg → accept the tunnel
   - Wait 10 seconds → the dashboard will show the live address

---

### Step 5 — Connect in Minecraft

1. Open Minecraft Bedrock Edition on your phone/PC/console
2. Go to **Play****Servers** tab → **Add Server**
3. Server Address: paste the `*.playit.gg` address
4. Port: paste the port number after the colon (or leave as 19132 if no port shown)
5. Click **Save** → Join!

---

## HuggingFace Secrets Reference

Add these in: Space → Settings → Repository Secrets

| Secret Name | Required? | Description |
|---|---|---|
| `SECRET_KEY` | ✅ Yes | Your playit.gg agent secret key. Without this, nobody can join. |
| `GDRIVE_SA_KEY` | ❌ Optional | Base64-encoded Google Service Account JSON. Enables Drive backups. |

---

## Google Drive Backup Setup

### Why Service Account instead of OAuth?
The old `credentials.json` approach uses OAuth's "installed app" flow which **opens a browser to sign in**. Docker containers have no browser. It can never work headlessly. A Service Account authenticates with a static JSON key — no browser, no interaction, just works.

### Step-by-Step

**1. Create a Google Cloud Project**
- Go to https://console.cloud.google.com
- Top bar → Select project → New Project → name it `alpha-mc` → Create

**2. Enable Google Drive API**
- APIs & Services → Library → search "Google Drive API" → Enable

**3. Create a Service Account**
- IAM & Admin → Service Accounts → Create Service Account
- Name: `minecraft-backup` → Done
- Click the new account → **Keys** tab → Add Key → Create new key → **JSON** → Download
- This downloads something like `alpha-mc-abc123.json` — rename it to `service-account.json`

**4. Share a Drive Folder with the Service Account**
- Open Google Drive → New folder → name it exactly: `Minecraft-Bedrock-Backups`
- Right-click the folder → Share
- Open `service-account.json` and find the `"client_email"` field — copy that email address
- Paste it in the share dialog → role: **Editor** → Share

**5. Generate the GDRIVE_SA_KEY**

On your computer (Linux/Mac terminal or Git Bash on Windows):
```bash
base64 -w 0 service-account.json
```
This prints a long string of random-looking characters. Copy ALL of it.

On Windows (PowerShell):
```powershell
[Convert]::ToBase64String([IO.File]::ReadAllBytes("service-account.json"))
```

**6. Add to HuggingFace**
- Space → Settings → Repository Secrets → New secret
- Name: `GDRIVE_SA_KEY`
- Value: paste the base64 string
- Add secret → Restart Space

**7. Verify**
- Check `/data/logs/backup.log` after 6 hours
- Should show: `Google Drive upload successful!`
- Check your Google Drive folder — the backup `.tar.gz` should appear there

### Security Rules
- ❌ NEVER commit `service-account.json` to git
- ❌ NEVER upload credentials/key files to HuggingFace files tab
- ❌ NEVER share your service account JSON publicly
- ✅ ONLY store it as a HF Secret (encrypted, not visible in git history)

---

## How to Connect and Play

### Finding the Address
The address is shown in two places:
1. **Status Dashboard** — open the Space URL in any browser
2. **Space Logs** — in the App tab logs, look for `TUNNEL IS LIVE`

### Sharing with Friends
Just give them the `*.playit.gg:PORT` address. They need:
- Minecraft Bedrock Edition (any platform — mobile, PC, Xbox, PlayStation, Switch)
- Add Server → paste address → join

### Adding Friends to Allowlist (optional)
If you want only specific people to join:
1. Set `white-list=true` in `server.properties`
2. Edit `allowlist.json` to add their gamertags and XUIDs
3. Re-upload both files and restart the Space

---

## Troubleshooting

### Space shows "Paused"
- Click the Space → click **Run** or **Restart**
- Make sure `SECRET_KEY` is set in secrets
- The status dashboard on port 7860 should prevent future pausing

### "Tunnel not found" / no address shown
- Check that `SECRET_KEY` is correct (regenerate on playit.gg if needed)
- Open Space logs → look for playit errors
- If you see a claim URL → click it and accept the tunnel on playit.gg website

### Build fails (Docker build error)
- Check that ALL files listed in Step 1 are uploaded
- The most common cause: a file is missing so `COPY` fails
- Check the build logs for which `COPY` line failed

### Server starts but nobody can join
- Make sure you're using the playit.gg address (NOT the HuggingFace URL)
- The HF URL is HTTP only — Minecraft needs the playit.gg address
- Check `online-mode` in server.properties — if `true`, players need a valid Microsoft account

### Minecraft crashes (server goes offline)
- `health_check.sh` should auto-restart it within 30 seconds
- Check `/data/logs/minecraft.log` for the crash reason
- Common causes: out of RAM (HF free tier has limited RAM), corrupted world

### Google Drive backup fails
- Check that `GDRIVE_SA_KEY` is set in HF Secrets
- Verify the Drive folder is named exactly `Minecraft-Bedrock-Backups`
- Verify the folder is shared with the service account email
- Check `/data/logs/backup.log` for the specific error message

### Dashboard not loading / Space gets paused
- `status_server.py` might have crashed
- It should auto-recover but if not, restart the Space
- Check `/data/logs/status_server.log` for Python errors

---

## FAQ

**Q: Is this free?**
A: Yes! HuggingFace Spaces (free tier) + playit.gg (free tier) = $0/month. The limitation is HF's free tier has limited RAM (~16GB shared) and CPU.

**Q: Will the world be lost if the Space restarts?**
A: No! HuggingFace persistent storage keeps `/data` between restarts. Your world is safe. Backups are extra insurance.

**Q: How many players can join?**
A: Up to 20 (set in server.properties). The actual limit depends on the HF server's available RAM — more players = more RAM.

**Q: Can I use mods / behaviour packs?**
A: Yes! Upload your pack files to the Space and place them in the correct Minecraft Bedrock folder under `/data/bedrock-server/`. This requires a bit of manual setup.

**Q: How do I update the Minecraft server version?**
A: Rebuild the Space (Settings → Factory reboot). `prepare.sh` always downloads the latest version from Minecraft.net.

**Q: Can I change the world seed?**
A: Yes — set `level-seed=` in `server.properties` to any number before the world is first created. Once a world exists, changing the seed has no effect.

**Q: How do I give myself operator (admin) permissions?**
A: Edit `permissions.json` with your XUID and set `"permission": "operator"`. Alternatively, if you're the first person to join, type your gamertag in the server console — but there's no easy console access on HF.

**Q: The playit address changes every restart — how do I get a permanent address?**
A: Upgrade to playit.gg Pro ($3/month) for a permanent subdomain. On the free tier the address changes each time.

---

*Alpha MC Setup Guide — All files written and debugged for HuggingFace Spaces + playit.gg*