20 KiB
Minecraft Servers
Minecraft servers running on docker-host2 via Crafty Controller 4.
Servers Overview
| Server | Address | Port | Version | Status |
|---|---|---|---|---|
| Hutworld | hutworld.htsn.io | 25565 | Paper 1.21.11 | Running |
| Backrooms | backrooms.htsn.io | 25566 | Paper 1.21.4 | Running |
Web Map
| Setting | Value |
|---|---|
| URL | https://map.htsn.io |
| Username | hutworld |
| Password | Suwanna123 |
| Plugin | BlueMap 5.15 |
| Port | 8100 (exposed via Docker) |
Quick Reference
Hutworld (Main Server)
| Setting | Value |
|---|---|
| Web GUI | https://mc.htsn.io |
| Game Server (Java) | hutworld.htsn.io:25565 |
| Game Server (Bedrock) | hutworld.htsn.io:19132 |
| Host | docker-host2 (10.10.10.207) |
| Server Type | Paper 1.21.11 |
| World Name | hutworld |
| Memory | 4GB min / 8GB max |
Backrooms (Horror/Exploration)
| Setting | Value |
|---|---|
| Web GUI | https://mc.htsn.io |
| Game Server (Java) | backrooms.htsn.io:25566 |
| Host | docker-host2 (10.10.10.207) |
| Server Type | Paper 1.21.4 |
| World Name | backrooms |
| Memory | 512MB min / 1.5GB max |
| Datapack | The Backrooms v2.2.0 |
Backrooms Features:
- 50+ custom dimensions based on Backrooms lore
- Use
/execute in backrooms:level0 run tp @s ~ ~ ~to travel to Level 0 - Horror-themed exploration gameplay
- No client mods required (datapack only)
Crafty Controller Access
| Setting | Value |
|---|---|
| URL | https://mc.htsn.io |
| Username | admin |
| Password | See /crafty/data/config/default-creds.txt on docker-host2 |
Get password:
ssh docker-host2 'cat ~/crafty/data/config/default-creds.txt'
Current Status
Completed
- Crafty Controller 4.4.7 deployed on docker-host2
- Traefik reverse proxy configured (mc.htsn.io → 10.10.10.207:8443)
- DNS A record created for hutworld.htsn.io (non-proxied, points to public IP)
- Port forwarding configured via UniFi API:
- TCP/UDP 25565 → 10.10.10.207 (Java Edition)
- UDP 19132 → 10.10.10.207 (Bedrock via Geyser)
- Server files transferred from Windows PC (D:\Minecraft\mcss\servers\hutworld)
- Server imported into Crafty and running
- Paper upgraded from 1.21.5 to 1.21.11
- Plugins updated (GSit 3.1.1, LuckPerms 5.5.22)
- Orphaned plugin data cleaned up
- LuckPerms database restored with original permissions
- Automated backups to TrueNAS configured (every 6 hours)
Pending
- Install SilkSpawners plugin (allows mining spawners with Silk Touch)
- Change Crafty admin password to something memorable
- Test external connectivity from outside network
Import Instructions
To import the hutworld server in Crafty:
- Go to Servers → Click + Create New Server
- Select Import Server tab
- Fill in:
- Server Name:
Hutworld - Import Path:
/crafty/import/hutworld - Server JAR:
paper.jar - Min RAM:
2048(2GB) - Max RAM:
6144(6GB) - Server Port:
25565
- Server Name:
- Click Import Server
- Go to server → Click Start
Server Configuration
World Data
| World | Description |
|---|---|
| hutworld | Main overworld |
| hutworld_nether | Nether dimension |
| hutworld_the_end | End dimension |
Installed Plugins
| Plugin | Version | Purpose |
|---|---|---|
| EssentialsX | 2.20.1 | Core server commands |
| EssentialsXChat | 2.20.1 | Chat formatting |
| EssentialsXSpawn | 2.20.1 | Spawn management |
| Geyser-Spigot | Latest | Bedrock Edition support |
| floodgate | Latest | Bedrock authentication |
| GSit | 3.1.1 | Sit/lay/crawl animations |
| LuckPerms | 5.5.22 | Permissions management |
| PluginPortal | 2.2.2 | Plugin management |
| Vault | 1.7.3 | Economy/permissions API |
| ViaVersion | Latest | Multi-version support |
| ViaBackwards | 5.2.1 | Older client support |
| randomtp | Latest | Random teleportation |
| BlueMap | 5.15 | 3D web map with player tracking |
| WorldEdit | 7.3.10 | World editing and terraforming |
Removed plugins (cleaned up 2026-01-03):
- GriefPrevention, Multiverse-Core, Multiverse-Portals, ProtocolLib, WorldGuard (disabled/orphaned)
Docker Configuration
Location: ~/crafty/docker-compose.yml on docker-host2
services:
crafty:
image: registry.gitlab.com/crafty-controller/crafty-4:4.4.7
container_name: crafty
restart: unless-stopped
environment:
- TZ=America/New_York
ports:
- "8443:8443" # Web GUI (HTTPS)
- "8123:8123" # Crafty HTTP
- "25565:25565" # Minecraft Java
- "25566:25566" # Additional server
- "19132:19132/udp" # Minecraft Bedrock (Geyser)
- "8100:8100" # BlueMap web server
volumes:
- ./data/backups:/crafty/backups
- ./data/logs:/crafty/logs
- ./data/servers:/crafty/servers
- ./data/config:/crafty/app/config
- ./data/import:/crafty/import
Traefik Configuration
File: /etc/traefik/conf.d/crafty.yaml on CT 202 (10.10.10.250)
http:
routers:
crafty-secure:
entryPoints:
- websecure
rule: "Host(`mc.htsn.io`)"
service: crafty
tls:
certResolver: cloudflare
priority: 50
services:
crafty:
loadBalancer:
servers:
- url: "https://10.10.10.207:8443"
serversTransport: crafty-transport@file
serversTransports:
crafty-transport:
insecureSkipVerify: true
Port Forwarding (UniFi)
Configured via UniFi controller on UCG-Fiber (10.10.10.1):
| Rule Name | Port | Protocol | Destination | Status |
|---|---|---|---|---|
| Minecraft Java | 25565 | TCP/UDP | 10.10.10.207:25565 | Active |
| Minecraft Bedrock | 19132 | UDP | 10.10.10.207:19132 | Active |
| Minecraft Backrooms | 25566 | TCP/UDP | 10.10.10.207:25566 | Active |
DNS Records (Cloudflare)
| Record | Type | Value | Proxied |
|---|---|---|---|
| mc.htsn.io | CNAME | htsn.io | Yes (for web GUI) |
| hutworld.htsn.io | A | 70.237.94.174 | No (direct for game traffic) |
| backrooms.htsn.io | A | 70.237.94.174 | No (direct for game traffic) |
Note: Game traffic (25565, 25566, 19132) cannot be proxied through Cloudflare - only HTTP/HTTPS works with Cloudflare proxy.
LuckPerms Web Editor
After server is running:
- Open Crafty console for Hutworld server
- Run command:
/lp editor - A unique URL will be generated (cloud-hosted by LuckPerms)
- Open the URL in browser to manage permissions
The editor is hosted by LuckPerms, so no additional port forwarding is needed.
Backup Configuration
Automated Backups to TrueNAS
Backups run automatically every 2 hours and are stored on TrueNAS for both servers.
| Setting | Value |
|---|---|
| Destination | TrueNAS (10.10.10.200) |
| Path | /mnt/vault/users/backups/minecraft/ |
| Frequency | Every 2 hours (12 backups per day) |
| Retention | 30 backups per server (~2.5 days of history) |
| Hutworld Size | ~2-7 GB per backup |
| Backrooms Size | ~100-150 MB per backup |
| Script | /home/hutson/minecraft-backup-all.sh on docker-host2 |
| Log | /home/hutson/minecraft-backup.log on docker-host2 |
Backup Scripts
Main Script: ~/minecraft-backup-all.sh on docker-host2 (backs up both servers)
Legacy Script: ~/minecraft-backup.sh on docker-host2 (Hutworld only)
#!/bin/bash
# Minecraft Server Backup Script
# Backs up Crafty server data to TrueNAS
BACKUP_SRC="$HOME/crafty/data/servers/19f604a9-f037-442d-9283-0761c73cfd60"
BACKUP_DEST="hutson@10.10.10.200:/mnt/vault/users/backups/minecraft"
DATE=$(date +%Y-%m-%d_%H%M)
BACKUP_NAME="hutworld-$DATE.tar.gz"
LOCAL_BACKUP="/tmp/$BACKUP_NAME"
# Create compressed backup (exclude large unnecessary files)
tar -czf "$LOCAL_BACKUP" \
--exclude="*.jar" \
--exclude="cache" \
--exclude="libraries" \
--exclude=".paper-remapped" \
-C "$HOME/crafty/data/servers" \
19f604a9-f037-442d-9283-0761c73cfd60
# Transfer to TrueNAS
sshpass -p 'GrilledCh33s3#' scp -o StrictHostKeyChecking=no "$LOCAL_BACKUP" "$BACKUP_DEST/"
# Clean up local temp file
rm -f "$LOCAL_BACKUP"
# Keep only last 30 backups on TrueNAS
sshpass -p 'GrilledCh33s3#' ssh -o StrictHostKeyChecking=no hutson@10.10.10.200 '
cd /mnt/vault/users/backups/minecraft
ls -t hutworld-*.tar.gz 2>/dev/null | tail -n +31 | xargs -r rm -f
'
Cron Schedule
# View current schedule
ssh docker-host2 'crontab -l | grep minecraft'
# Output: 0 */2 * * * /home/hutson/minecraft-backup-all.sh >> /home/hutson/minecraft-backup.log 2>&1
Manual Backup Commands
# Run backup manually
ssh docker-host2 '~/minecraft-backup.sh'
# Check backup log
ssh docker-host2 'tail -20 ~/minecraft-backup.log'
# List backups on TrueNAS
sshpass -p 'GrilledCh33s3#' ssh -o StrictHostKeyChecking=no hutson@10.10.10.200 \
'ls -lh /mnt/vault/users/backups/minecraft/'
Restore from Backup
# 1. Stop the server in Crafty web UI
# 2. Copy backup from TrueNAS
sshpass -p 'GrilledCh33s3#' scp -o StrictHostKeyChecking=no \
hutson@10.10.10.200:/mnt/vault/users/backups/minecraft/hutworld-YYYY-MM-DD_HHMM.tar.gz \
/tmp/
# 3. Extract to server directory (backup existing first)
ssh docker-host2 'cd ~/crafty/data/servers && \
mv 19f604a9-f037-442d-9283-0761c73cfd60 19f604a9-f037-442d-9283-0761c73cfd60.old && \
tar -xzf /tmp/hutworld-YYYY-MM-DD_HHMM.tar.gz'
# 4. Start server in Crafty web UI
Admin Commands
Give Mob Spawner (1.21+ Syntax)
In Minecraft 1.21+, the NBT syntax changed. Use minecraft:give to bypass Essentials:
minecraft:give <player> spawner[block_entity_data={id:"minecraft:mob_spawner",SpawnData:{entity:{id:"minecraft:<mob_type>"}}}]
Examples:
# Magma cube spawner
minecraft:give suwann spawner[block_entity_data={id:"minecraft:mob_spawner",SpawnData:{entity:{id:"minecraft:magma_cube"}}}]
# Zombie spawner
minecraft:give suwann spawner[block_entity_data={id:"minecraft:mob_spawner",SpawnData:{entity:{id:"minecraft:zombie"}}}]
# Skeleton spawner
minecraft:give suwann spawner[block_entity_data={id:"minecraft:mob_spawner",SpawnData:{entity:{id:"minecraft:skeleton"}}}]
# Blaze spawner
minecraft:give suwann spawner[block_entity_data={id:"minecraft:mob_spawner",SpawnData:{entity:{id:"minecraft:blaze"}}}]
Note: Must use minecraft:give prefix to use vanilla command instead of Essentials /give.
RCON Access
For remote console access to the server:
| Setting | Value |
|---|---|
| Host | 10.10.10.207 |
| Port | 25575 |
| Password | HutworldRCON2026 |
Example using mcrcon:
mcrcon -H 10.10.10.207 -P 25575 -p HutworldRCON2026
BlueMap Commands
# Start full world render
/bluemap render
# Pause rendering
/bluemap pause
# Resume rendering
/bluemap resume
# Check render status
/bluemap status
# Reload BlueMap config
/bluemap reload
Common Tasks
Start/Stop Server
Via Crafty web UI at https://mc.htsn.io, or:
# Check Crafty container status
ssh docker-host2 'docker ps | grep crafty'
# Restart Crafty container
ssh docker-host2 'cd ~/crafty && docker compose restart'
# View Crafty logs
ssh docker-host2 'docker logs -f crafty'
Backup Server
See Backup Configuration for full details.
# Run backup manually
ssh docker-host2 '~/minecraft-backup.sh'
# Check recent backups
sshpass -p 'GrilledCh33s3#' ssh -o StrictHostKeyChecking=no hutson@10.10.10.200 \
'ls -lht /mnt/vault/users/backups/minecraft/ | head -5'
Update Plugins
- Download new plugin JAR
- Upload via Crafty Files tab, or:
scp plugin.jar docker-host2:~/crafty/data/servers/hutworld/plugins/
- Restart server in Crafty
Check Server Logs
Via Crafty web UI (Logs tab), or:
ssh docker-host2 'tail -f ~/crafty/data/servers/hutworld/logs/latest.log'
Troubleshooting
Plugin Permission Issues (IMPORTANT)
Root Cause: Crafty Docker container requires all files to be owned by <user>:root (not <user>:<user>) for permissions to work correctly.
Permanent Fix:
# Fix all permissions immediately
ssh docker-host2 'sudo chown -R hutson:root ~/crafty/data/servers/ && \
sudo find ~/crafty/data/servers/ -type d -exec chmod 2775 {} \; && \
sudo find ~/crafty/data/servers/ -type f -exec chmod 664 {} \;'
Prevention:
- Always upload plugins through Crafty web UI - this ensures correct permissions
- Or use the import directory: Copy to
~/crafty/data/import/then restart container - Never directly copy files to the servers directory
Check for permission issues:
# Use the permission check script (recommended)
ssh docker-host2 '~/check-crafty-permissions.sh'
# Or manually check for wrong group ownership
ssh docker-host2 'find ~/crafty/data/servers -type f ! -group root -ls'
ssh docker-host2 'find ~/crafty/data/servers -type d ! -group root -ls'
Permission Check Script: Located at ~/check-crafty-permissions.sh on docker-host2
- Automatically detects permission issues
- Offers to fix them with one command
- Ignores temporary files that are expected to have different permissions
Crafty Shows Server Offline or "Another Instance Running"
Cause: This happens when the server was started manually (not through Crafty) or when Crafty loses track of the server process.
Fix:
# 1. Kill any orphaned server processes
ssh docker-host2 'docker exec crafty pkill -f "paper.jar"'
# 2. Restart Crafty container to clear state
ssh docker-host2 'cd ~/crafty && docker compose restart'
# 3. Wait 30-60 seconds - Crafty will auto-start the server
Prevention:
- Always use Crafty web UI to start/stop servers
- Never manually start the server with java command
- If you must restart, use the container restart method above
Server won't start
# Check Crafty container logs
ssh docker-host2 'docker logs crafty --tail 50'
# Check server logs
ssh docker-host2 'cat ~/crafty/data/servers/hutworld/logs/latest.log | tail -100'
# Check Java version in container
ssh docker-host2 'docker exec crafty java -version'
Can't connect externally
- Verify port forwarding is active:
ssh root@10.10.10.1 'iptables -t nat -L -n | grep 25565'
- Test from external network:
nc -zv hutworld.htsn.io 25565
- Check if server is listening:
ssh docker-host2 'netstat -tlnp | grep 25565'
Bedrock players can't connect
- Verify Geyser plugin is installed and enabled
- Check Geyser config:
~/crafty/data/servers/hutworld/plugins/Geyser-Spigot/config.yml - Ensure UDP 19132 is forwarded and not blocked
Corrupted plugin JARs (ZipException)
If you see java.util.zip.ZipException: zip END header not found:
- Check all plugins for corruption:
ssh docker-host2 'cd ~/crafty/data/servers/19f604a9-f037-442d-9283-0761c73cfd60/plugins && \
for jar in *.jar; do unzip -t "$jar" > /dev/null 2>&1 && echo "OK: $jar" || echo "CORRUPT: $jar"; done'
-
Re-download corrupted plugins from Hangar/Modrinth/SpigotMC
-
Restart server
Session lock errors
If server fails with session.lock: already locked:
# Kill stale Java processes and remove locks
ssh docker-host2 'docker exec crafty bash -c "pkill -f paper.jar; rm -f /crafty/servers/*/hutworld*/session.lock"'
Permission denied errors in Docker
If world files show AccessDeniedException:
# Fix permissions (crafty user is UID 1000)
ssh docker-host2 'docker exec crafty bash -c "chown -R 1000:0 /crafty/servers/19f604a9-f037-442d-9283-0761c73cfd60/ && chmod -R u+rwX /crafty/servers/19f604a9-f037-442d-9283-0761c73cfd60/"'
LuckPerms missing users/permissions
If LuckPerms shows a fresh database (missing users like Suwan):
- Check if original database exists:
ssh docker-host2 'ls -la ~/crafty/data/import/hutworld/plugins/LuckPerms/*.db'
- Restore from import backup:
# Stop server in Crafty UI first
ssh docker-host2 'cp ~/crafty/data/import/hutworld/plugins/LuckPerms/luckperms-h2-v2.mv.db \
~/crafty/data/servers/19f604a9-f037-442d-9283-0761c73cfd60/plugins/LuckPerms/'
- Or restore from TrueNAS backup:
# List available backups
sshpass -p 'GrilledCh33s3#' ssh -o StrictHostKeyChecking=no hutson@10.10.10.200 \
'ls -lt /mnt/vault/users/backups/minecraft/'
# Extract LuckPerms database from backup
sshpass -p 'GrilledCh33s3#' scp hutson@10.10.10.200:/mnt/vault/users/backups/minecraft/hutworld-YYYY-MM-DD_HHMM.tar.gz /tmp/
tar -xzf /tmp/hutworld-*.tar.gz -C /tmp --strip-components=2 \
'*/plugins/LuckPerms/luckperms-h2-v2.mv.db'
- Restart server in Crafty UI
Migration History
2026-01-04: Backup System (Updated 2026-01-13)
- Configured automated backups to TrueNAS
- Updated frequency: Every 2 hours (was 6 hours)
- Updated retention: 30 backups (~2.5 days) (was 14 backups)
- Created backup script with compression and cleanup
- Storage:
/mnt/vault/users/backups/minecraft/
2026-01-03: Server Fixes & Updates
Updates:
- Upgraded Paper from 1.21.5 to 1.21.11 (build 69)
- Updated GSit from 2.3.2 to 3.1.1
- Fixed corrupted LuckPerms JAR (re-downloaded 5.5.22)
- Restored original LuckPerms database with user permissions
Cleanup:
- Removed disabled plugins: Dynmap, Graves
- Removed orphaned data folders: GriefPreventionData, SilkSpawners_v2, Graves, ViaRewind
Fixes:
- Fixed memory allocation (was attempting 2TB, set to 2GB min / 4GB max)
- Fixed file permissions for Docker container access
2026-01-03: Initial Migration
Source: Windows PC (10.10.10.150) - D:\Minecraft\mcss\servers\hutworld
Steps completed:
- Compressed hutworld folder on Windows (2.4GB zip)
- Transferred via SCP to docker-host2
- Unzipped to ~/crafty/data/import/hutworld
- Downloaded Paper 1.21.5 JAR (later upgraded to 1.21.11)
- Imported server into Crafty Controller
- Configured port forwarding (updated existing 25565 rule, added 19132)
- Created DNS record for hutworld.htsn.io
Original MCSS config preserved: mcss_server_config.json
Related Documentation
- IP Assignments - Network configuration
- Traefik - Reverse proxy setup
- VMs - docker-host2 details
- Gateway - UCG-Fiber configuration
Resources
Last Updated: 2026-01-11
Migration History (Hutworld)
2026-01-13: Server Infrastructure Upgrades ✅
- RAM Upgraded: Increased from 2GB/4GB to 4GB/8GB (min/max)
- Storage Expanded: VM disk increased from 32GB to 64GB (33% used)
- RCON Enabled: Remote console access configured on port 25575 - TESTED & WORKING
- WorldEdit Installed: Version 7.3.10 for world editing capabilities
- Auto-Start Configured: Server auto-starts with Crafty container
- Docker Cleanup: Freed 1.1GB by removing unused images and containers
- Container Fixed: Recreated with proper port mappings for RCON access
2026-01-11: BlueMap Web Map Added
- Installed BlueMap 5.15 plugin (supports MC 1.21.11)
- Exposed port 8100 in docker-compose.yml for BlueMap web server
- Configured Traefik routing: map.htsn.io → 10.10.10.207:8100
- Added basic auth password protection via Traefik middleware
- Fixed corrupted ViaVersion/ViaBackwards plugins (re-downloaded from Hangar)
- Fixed Docker file permission issues (chown to UID 1000)
- Documented 1.21+ spawner give command syntax
Migration History (Backrooms)
2026-01-05: Backrooms Server Created
- Created new Backrooms server in Crafty Controller
- Installed Paper 1.21.4 build 232 (recommended version for datapack)
- Installed The Backrooms datapack v2.2.0 from Modrinth
- DNS record created for backrooms.htsn.io
- Memory configured for 512MB-1.5GB (VM memory constrained)
- Server running on port 25566
- Pending: Port forwarding for external access