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
  2. File-by-File Explanation
  3. Step-by-Step Setup
  4. HuggingFace Secrets Reference
  5. Google Drive Backup Setup
  6. How to Connect and Play
  7. Troubleshooting
  8. 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:

[
  {
    "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:

[
  {
    "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 fileUpload 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 PlayServers 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

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):

base64 -w 0 service-account.json

This prints a long string of random-looking characters. Copy ALL of it.

On Windows (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