server / SETUP_GUIDE.md
pabla1322's picture
Upload 17 files
722781c verified
|
Raw
History Blame Contribute Delete
20.7 kB
# 📖 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*