Pin Minecraft 26.3 and add safe Orion managed deployment support
This commit is contained in:
1 parent
dff2b5a9c4
commit
008120dbad
40 files changed
+1877
-490
No files matched your search
+10
-48
@@ -1,57 +1,19 @@
|
||||
# Backups & restore
|
||||
# Backups and restore
|
||||
|
||||
## What runs automatically
|
||||
The backup sidecar archives server data every 24 hours by default and keeps seven days locally. It flushes the world through RCON first and excludes temporary files, caches and logs. Manual panel backups wait for a newly created archive to pass complete gzip/tar validation. A request acknowledgment alone is not backup success.
|
||||
|
||||
The `backup` sidecar (itzg/mc-backup) tars the entire server data directory to
|
||||
`data/backups/world-<timestamp>.tgz`:
|
||||
Config and mod Apply require a successful safety backup; failure cancels the operation. Standalone world reset does too. Orion managed mode rejects configuration changes and world reset entirely; upgrades are reviewed in homelab-infra.
|
||||
|
||||
- flushes the world to disk first (`save-all`), safe while players are online
|
||||
- interval: `BACKUP_INTERVAL` in `.env` (default `24h`)
|
||||
- retention: `BACKUP_RETENTION_DAYS` (default `7`) — older tars are pruned
|
||||
- excludes caches and logs
|
||||
## Same-release world restore
|
||||
|
||||
Safety backups are also taken automatically before config applies (when enabled) and
|
||||
world resets.
|
||||
Use the Backups page, or `scripts/restore.sh /absolute/path/backup.tgz` as the standalone fallback. Orion's fallback takes the extra arguments `/opt/minecraft/project /opt/minecraft/data`.
|
||||
|
||||
## Manual backup
|
||||
The panel stops Minecraft and the backup writer, validates archive paths and the managed release lock, extracts a clean staging tree, and moves the existing data into a retained `restore-*/previous` directory. It preserves the bind-mount root and correct server ownership. Files that only existed in the newer world are not left active. On failure the writers remain stopped for inspection. The shell fallback also stops the panel to avoid competing requests.
|
||||
|
||||
- Panel: Backups page → **Back up now**
|
||||
- CLI: `docker exec mc-backup backup now`
|
||||
Do not overlay an archive with `tar -xzf` onto a populated world. Keep the world and staging workspace under a common parent mount, on the same filesystem. Reserve disk for the active world, staged copy and retained previous data, and remove retained copies only after confirming a successful recovery.
|
||||
|
||||
## Restoring
|
||||
## Complete recovery
|
||||
|
||||
Panel: Backups page → **Restore** → type `restore`. The panel stops the server,
|
||||
extracts the tar over the data directory, and starts the server again. Everything since
|
||||
that backup is lost.
|
||||
A world archive contains Minecraft and EasyAuth state. It does not contain CraftDeck's database, deployment config, proxy secret or panel credentials. For Orion use `homelab-infra/stacks/minecraft/cold-backup.sh`: it stops the stack and captures the complete deployment plus an export of the pinned panel image. Copy the secret-bearing backup off-host with private permissions.
|
||||
|
||||
CLI fallback (panel down):
|
||||
|
||||
```bash
|
||||
./scripts/restore.sh data/backups/world-20260710-050000.tgz
|
||||
```
|
||||
|
||||
## Off-site copies (recommended)
|
||||
|
||||
`data/backups/` is just files — sync it anywhere:
|
||||
|
||||
```bash
|
||||
# example: nightly rsync to another machine (add to the host's crontab)
|
||||
0 6 * * * rsync -a --delete /path/to/minecraft/data/backups/ backup-host:/srv/mc-backups/
|
||||
```
|
||||
|
||||
You can also download any backup from the panel (⬇ button) before risky experiments.
|
||||
|
||||
## Disaster recovery (new machine)
|
||||
|
||||
```bash
|
||||
git clone <repo> minecraft && cd minecraft
|
||||
./scripts/setup.sh # fresh secrets — friends keep their passwords,
|
||||
# those live in the world data, not in .env
|
||||
mkdir -p data/backups && cp <your-backup>.tgz data/backups/
|
||||
docker compose up -d # let it initialize once
|
||||
./scripts/restore.sh data/backups/<your-backup>.tgz
|
||||
```
|
||||
|
||||
The backup contains the world, mods, configs, and the EasyAuth database, so player
|
||||
registrations survive. Panel state (approval history, metrics) lives in
|
||||
`data/dashboard/` — include it in your off-site sync if you want it back too.
|
||||
Restore a different release only with its matching complete backup, release lock and image. Keep the failed state recoverable, restore into a clean directory and recreate containers when replacing mount roots. Do not downgrade Minecraft against a newer world. Test the complete restore in isolation before relying on it. See [orion.md](orion.md) and the infrastructure runbook for the release workflow.
|
||||
@@ -54,3 +54,7 @@ setup and add a `caddy` service; the panel works fine behind a reverse proxy
|
||||
Performance & Lag page. Server-side lag shows as low TPS / high MSPT (affects everyone
|
||||
equally); player-side lag shows as high ping for that player only. The page gives a
|
||||
plain-English verdict and per-player ping history so you can settle the argument.
|
||||
|
||||
## Orion integration
|
||||
|
||||
Orion uses the dedicated managed Compose file in homelab-infra, with TCPShield and OPNsense. Follow [orion.md](orion.md) and [tcpshield.md](tcpshield.md); standalone direct-port examples above do not describe that ingress path.
|
||||
@@ -0,0 +1,23 @@
|
||||
# Orion managed deployment
|
||||
|
||||
The authoritative Compose file, release lock, initial preparation script and OPNsense instructions are in `geneticglitch1/homelab-infra`, under `stacks/minecraft/`. Deploy that stack through Komodo on Orion. Do not deploy this repository's root Compose file on top of it.
|
||||
|
||||
The release selects Minecraft 26.3, Java 25, Fabric loader 0.19.5, launcher 1.1.2 and exact Modrinth version IDs. Velocity 4.2.0 build 30 consumes TCPShield PROXY protocol; FabricProxy-Lite handles authenticated modern forwarding to the private backend. Offline mode, EasyAuth and the whitelist remain the existing authentication model. Check player UUIDs against a copied world before a migration.
|
||||
|
||||
CraftDeck uses `PANEL_MANAGED=true`. Config, mod and file writes, Compose apply and world reset are rejected by the backend. The UI identifies managed mode. Console, player administration, metrics, power controls and backups remain available. These admin controls still have broad authority; managed mode prevents accidental configuration drift and is not a security boundary around the Docker socket.
|
||||
|
||||
Persistent state lives in `/opt/minecraft/data/{mc,backups,dashboard,restore}`. CraftDeck mounts their common parent at `/server-data`; this is necessary for Linux rename operations during restore. The deployment lives in `/opt/minecraft/project`, mounted read-only at the same path. Never put a world under a disposable Komodo source checkout.
|
||||
|
||||
Build the reviewed source commit on Orion using the infrastructure preparation script. It records Docker's local immutable image ID. Komodo uses that ID with `pull_policy: never`; a restart cannot pull a newer panel. Preparation refuses existing containers or an unknown world. It does not accept the Minecraft EULA or start services.
|
||||
|
||||
The panel listens only at `192.168.1.88:8080`, reachable through LAN/VPN and the host firewall. Never forward this port on OPNsense or publish it with NPM. The Docker socket grants host control; keep the panel credentials private.
|
||||
|
||||
## Restore and upgrade behavior
|
||||
|
||||
A required safety backup failure aborts the operation. A backup request is successful only after a newly created archive passes a complete gzip/tar validation. Power, backup, restore and Compose operations share one reentrant queue within the panel process.
|
||||
|
||||
Restores stop both Minecraft and the backup sidecar, validate paths and the managed deployment lock, unpack into a clean staging directory, then move the previous data aside without replacing the bind-mount root. Newer-only files are removed from the active world and retained with the previous data. Failure leaves writers stopped; inspect the recorded restore directory before recovery. Restored files retain the current server directory's ownership.
|
||||
|
||||
The panel accepts only backups with the current release lock. For a different release, use a complete stopped backup and the matching deployment/image, following the infrastructure runbook. A world archive does not include the panel database, proxy state or host secrets. Use `cold-backup.sh` for the complete deployment and copy it off Orion.
|
||||
|
||||
The root standalone Compose file uses the same restore mount layout. Existing standalone installs must recreate the dashboard with the new mounts and set `PROJECT_DIR` to the absolute host checkout path before using Apply or Restore. `scripts/setup.sh` fills that path for new installs. The manual restore fallback is documented in `scripts/restore.sh`; it stops the panel too, avoiding concurrency with web requests.
|
||||
+8
-77
@@ -1,84 +1,15 @@
|
||||
# TCPShield (DDoS protection + real player IPs)
|
||||
# TCPShield on Orion
|
||||
|
||||
[TCPShield](https://tcpshield.com) sits in front of the server: players connect to
|
||||
your TCPShield domain, and your real server IP stays hidden and DDoS-protected.
|
||||
The catch: without extra setup, every connection appears to come from TCPShield's
|
||||
proxies, so the Security page, IP bans, and connection logs are useless.
|
||||
Use the maintained runbook in `homelab-infra/stacks/minecraft/TCPSHIELD.md` for the exact OPNsense and host firewall steps.
|
||||
|
||||
TCPShield's own RealIP plugin is Bukkit/Bungee/Velocity-only — it does not exist
|
||||
for Fabric. The working path for this stack is **PROXY protocol v2** plus the
|
||||
**Proxy Protocol Support** Fabric mod.
|
||||
Traffic flows: player → TCPShield → OPNsense source-restricted TCP 25565 DNAT → Orion Velocity → private Fabric backend. Enable PROXY protocol in TCPShield and `haproxy-protocol = true` in Velocity. Velocity then uses modern forwarding, with the same secret as `FABRIC_PROXY_SECRET` in FabricProxy-Lite.
|
||||
|
||||
## Setup
|
||||
The reviewed deployment pins Minecraft 26.3 and Velocity 4.2.0 build 30. The direct Fabric `proxy-protocol-support` mod did not advertise 26.3 support at review time, so it is not used. The old `config/patches` files are legacy and are no longer mounted by the standalone Compose file. Do not combine that legacy direct-server guide with the Velocity deployment.
|
||||
|
||||
1. **TCPShield panel** → your backend → enable **Proxy Protocol**.
|
||||
2. **Mods page** → Recommended → add **Proxy Protocol Support** → Apply
|
||||
(or append `proxy-protocol-support` to `MODRINTH_PROJECTS` in `.env` and
|
||||
`docker compose up -d mc`).
|
||||
3. Nothing else — the mod's configuration is **enforced automatically on every
|
||||
boot** by `config/patches/patch-set.json` (see below). Restart once after
|
||||
installing so the patch applies:
|
||||
OPNsense must preserve the TCPShield source address and permit only the official IPv4 ranges from https://tcpshield.com/v4/. Host DOCKER-USER rules enforce the same restriction before trusted-LAN exceptions. Do not add game port 25565 to unrestricted public ports. Do not expose the backend, RCON, panel or a map port.
|
||||
|
||||
```bash
|
||||
docker compose restart mc
|
||||
```
|
||||
The public Minecraft hostname is a DNS-only CNAME to the hostname assigned by TCPShield. An ordinary Cloudflare orange-cloud HTTP proxy is not a Minecraft proxy. Use the public protected hostname even from home; direct LAN joins intentionally fail on the protected proxy port.
|
||||
|
||||
## Verifying it works
|
||||
Verify an external join, real player IP, EasyAuth registration, whitelist/UUID continuity and direct-origin rejection before inviting players. Configure TCPShield for the exact protected hostname and backend; account/plan controls and any account-specific verification steps must be completed in its dashboard.
|
||||
|
||||
Watch the startup log (`docker compose logs -f mc`). You must see all three:
|
||||
|
||||
```
|
||||
Proxy Protocol Support is enabled!
|
||||
TCPShield integration enabled! Fetching official IPs...
|
||||
Successfully added 2 TCPShield IPs to the trusted proxy list.
|
||||
```
|
||||
|
||||
Then join through your TCPShield domain — the console shows your **real IP**, and
|
||||
`docker compose ps` shows `mc` **healthy**.
|
||||
|
||||
## How the config is managed (don't hand-edit!)
|
||||
|
||||
The mod rewrites `config/proxy_protocol_support.json` at every startup, which
|
||||
silently clobbers hand edits. Instead, the server image applies
|
||||
`config/patches/patch-set.json` from this repo **before every server start**,
|
||||
enforcing:
|
||||
|
||||
| Setting | Value | Why |
|
||||
|---|---|---|
|
||||
| `enableProxyProtocol` | `true` | decode PROXY protocol headers |
|
||||
| `whitelistTCPShieldServers` | `true` | auto-fetch TCPShield's proxy IP ranges — no hardcoding, survives their infra changes |
|
||||
| `proxyServerIPs` | `127.0.0.1` | (TCPShield's ranges are added automatically at runtime) |
|
||||
| `directAccessIPs` | localhost (`127.0.0.1`, `::1`) + private ranges (`10/8`, `172.16/12`, `192.168/16`) | container healthcheck + LAN/panel access |
|
||||
|
||||
To change a value, edit the patch file in the repo and `docker compose up -d mc`.
|
||||
|
||||
**First-boot note:** on a brand-new install the mod's config file doesn't exist
|
||||
yet when patches run, so the very first boot uses mod defaults; every boot after
|
||||
that is patched. One `docker compose restart mc` after first install settles it.
|
||||
|
||||
## Security model
|
||||
|
||||
PROXY protocol headers carry no signature, so anyone who finds your raw server IP
|
||||
could spoof client IPs — the mod prevents this with default-deny:
|
||||
|
||||
- PROXY headers are only accepted from **TCPShield's published ranges** (auto-fetched)
|
||||
- Direct, header-less connections are only accepted from **localhost + LAN**
|
||||
- Everything else → `REJECTED unauthorized direct connection` in the log
|
||||
|
||||
So occasional `REJECTED` lines from random public IPs are the wall working —
|
||||
that's scanner bots hitting your raw IP and bouncing. A `REJECTED ... /0:0:0:0:0:0:0:1`
|
||||
(IPv6 localhost) every few seconds means the container healthcheck is being
|
||||
blocked — that's exactly what the `::1` entry in the patch prevents; if you see
|
||||
it, the patch didn't apply (check `docker compose logs mc | head -50`).
|
||||
|
||||
For belt-and-braces, also enable TCPShield's Advanced Firewall (panel → Network →
|
||||
Firewall), and consider host-firewalling port 25565 to TCPShield's ranges
|
||||
(`curl tcpshield.com/v4`) once everything works.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **Friends must connect via the TCPShield domain** — direct-IP connections from
|
||||
outside your LAN are rejected by design once this is active.
|
||||
- If real players start bouncing with `REJECTED`, TCPShield may have changed
|
||||
their IP ranges *and* the auto-fetch failed at boot — restart the server so it
|
||||
re-fetches.
|
||||
Sources: [TCPShield documentation](https://docs.tcpshield.com/), [Velocity forwarding](https://docs.papermc.io/velocity/player-information-forwarding/), [OPNsense NAT](https://docs.opnsense.org/manual/nat.html).
|
||||
+6
-34
@@ -1,39 +1,11 @@
|
||||
# Updating
|
||||
# Reviewed updates
|
||||
|
||||
## Upgrading Minecraft (e.g. 26.2 → 26.3)
|
||||
For Orion, edit `homelab-infra/stacks/minecraft/release-lock.json` and Compose together. Verify the Minecraft, Java, Fabric, mod and Velocity compatibility matrix against upstream releases. Build and test the exact CraftDeck commit; record its immutable local image ID. No production setting should use `latest` without an image digest or an unversioned mod slug.
|
||||
|
||||
1. **Configuration** page → change `Minecraft version` → **Save**
|
||||
2. **Apply** with *"Take a safety backup first"* enabled
|
||||
3. The server container is recreated: the new server jar, a matching Fabric loader, and
|
||||
fresh builds of every managed mod are downloaded automatically
|
||||
Before an update, make a complete stopped backup with the infrastructure `cold-backup.sh`, copy it off-host, and verify a restore in an isolated instance. Start the candidate on a disposable world and a copy of existing state first. Confirm authentication UUIDs, whitelist, registration, proxy IP forwarding and resource headroom.
|
||||
|
||||
If a managed mod has no build for the new version yet, the server won't start — check
|
||||
the Console page for which one, remove it from the Mods page (or wait a few days), and
|
||||
Apply again. Worlds upgrade forward automatically; **there is no downgrade** — that's
|
||||
what the safety backup is for.
|
||||
After approval, stop through Komodo, materialize the reviewed files, preserve the previous project/lock and image, and update the world's `.deployment-lock.json` to the candidate release. Do not use the initial preparation script to overwrite an existing installation. Deploy manually and run the acceptance checks in the infrastructure README.
|
||||
|
||||
Command-line equivalent:
|
||||
Rollback means restoring the matching complete data backup, panel database, secrets, proxy configuration and previous image/lock. Downgrading a version setting against a newer world is not a rollback. Managed panel restores deliberately refuse mismatched release locks.
|
||||
|
||||
```bash
|
||||
sed -i 's/^MC_VERSION=.*/MC_VERSION=26.3/' .env
|
||||
docker exec mc-backup backup now
|
||||
docker compose up -d mc
|
||||
```
|
||||
|
||||
## Updating mods only
|
||||
|
||||
Mods page → **Update all & restart**. (Any server restart re-resolves managed mods.)
|
||||
|
||||
## Updating the panel / images
|
||||
|
||||
```bash
|
||||
git pull
|
||||
docker compose pull # new itzg server + backup images
|
||||
docker compose build dashboard
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## Snapshots / release candidates
|
||||
|
||||
`MC_VERSION` accepts any version the launcher knows (`26.3-rc-1`, `26.3-snapshot-3`…).
|
||||
Mods rarely support snapshots — expect to trim the mod list if you try them.
|
||||
For the standalone setup, `PROJECT_DIR` must equal the absolute host checkout. Update the explicit image, Minecraft, loader and Modrinth pins together. Config/mod Apply takes a required backup and aborts on failure. Newly added unversioned mod slugs remain a standalone convenience; pin their reviewed Modrinth version IDs before treating that installation as a locked release.
|
||||
Reference in new issue
Block a user