Packwiz-Abdelpak-hosting-kit/README.md

145 lines
5.3 KiB
Markdown

# mc-packwiz-deploy
Self-hosted NeoForge Minecraft server with a packwiz modpack that clients pull
automatically on every launch. Mods are served from an HTTP mirror of the
server's own mods directory — no Modrinth or CurseForge dependency.
Everything lives on a ZFS dataset mounted at `/minecraft`.
## Quick start
```bash
./deploy.sh -n "Opengames" -a themiro \
-u https://games.abdelbaki.eu/mods \
--accept-eula
```
Add `-p 25599` to run on a non-default port. It's written into
`server.properties`, opened in firewalld, and shown in the player guides — which
print a bare hostname on 25565 and `host:port` on anything else, since Minecraft
assumes the default and a needless `:25565` confuses people.
The NeoForge version is resolved automatically — the newest stable build in the
series matching your Minecraft version, from the NeoForged maven. Pin one with
`-N 21.1.248` if you'd rather not track latest.
Then:
```bash
sudo systemctl start minecraft
journalctl -u minecraft -f
```
Send the players `https://<your-host>/setup-windows-packwiz.html` or
`setup-linux-packwiz.html`. Those are generated with your real pack URL and
server address already filled in.
## Re-running
`deploy.sh` is safe to run repeatedly, and re-running is the intended way to
apply changed settings — a port change, a different heap size, or a run that
failed partway and left things half-applied.
Each run:
1. Snapshots the dataset (`<pool>@predeploy-<timestamp>`)
2. Stops the server if it was running
3. Rewrites `server.properties`, `user_jvm_args.txt` and both unit files
4. Moves any existing pack to `<pack>.bak.<timestamp>` and rebuilds it
5. Regenerates the player guides
6. Starts the server again if it had been running
**The world and `/minecraft/mods` are never touched.** The pack is moved aside
rather than deleted, so hand-edited `.pw.toml` files and any git history in the
pack directory survive.
`--keep-pack` skips the pack rebuild; `--no-snapshot` skips step 1.
## What's in here
| Script | Runs as | Does |
|---|---|---|
| `deploy.sh` | you | Runs the two setup scripts in order |
| `mc-service-setup.sh` | root | `minecraft` user, NeoForge server, systemd units |
| `packwiz-setup.sh` | you | packwiz install, pack init, mod index, player guides |
| `mc-refresh-restart.sh` | you | Re-sync the pack after changing mods, then restart |
| `build.sh` | you | Builds the release zip |
## Memory
The heap defaults to 10 GB (`-X`/`-x` to change it). `-XX:+AlwaysPreTouch` means
the JVM commits the whole heap at startup rather than growing into it, so the
number you set is the number actually taken.
On a ZFS host, cap the ARC to go with it — ZFS defaults to using up to half of
RAM for cache, and will otherwise contend with the JVM for the same pages:
```bash
echo "options zfs zfs_arc_max=2147483648" | sudo tee /etc/modprobe.d/zfs.conf
sudo dracut --force && sudo reboot
```
That pins the ARC to 2 GB. On a 16 GB box that leaves roughly 4 GB for the OS
and anything else the host runs, which is comfortable.
## Requirements
- Fedora (or any systemd distro; `dnf` calls need swapping otherwise)
- A ZFS dataset mounted at `/minecraft`
- Java 21
- A web server already publishing `/minecraft``/mods` and `/packs` must be
reachable over HTTP
Every script refuses to run if `/minecraft` isn't a mountpoint. An unmounted
dataset leaves it as an empty directory on the root filesystem, and writing a
world or a mod mirror there fills the root disk instead of the pool.
## Day-to-day
Add or remove a jar in `/minecraft/mods`, then:
```bash
./mc-refresh-restart.sh
```
That registers new mods, re-pins any whose file changed, drops metadata for
deleted ones, takes a ZFS snapshot, restarts the server, and prunes to the
8 most recent snapshots. Players get the change on their next launch.
It refuses to restart if any mod failed to register, so the server never comes
up on a half-synced pack. Edit the config block at the top first — `PACK_DIR`,
`BASE_URL`, and `PACK_URL` need to match your deployment.
## The server unit
`minecraft.service` pairs with `minecraft.socket`, a console FIFO at
`/run/minecraft-console`. That's what makes a clean shutdown possible:
```bash
sudo systemctl stop minecraft # sends "stop", world saves properly
echo "say hello" | sudo tee /run/minecraft-console
journalctl -u minecraft -f # console output
```
Without the FIFO, systemd would SIGTERM the JVM and risk cutting a world save
in half.
## Web server
`/minecraft` needs to be served over HTTP. Serve `pack.toml` and `index.toml`
with `Cache-Control: no-cache` — a caching proxy will otherwise hand clients a
stale pack while the server runs the new one. `mc-refresh-restart.sh` checks for
exactly that and stops before restarting if it finds it.
## Caveats
- `packwiz-setup.sh` probes `packwiz --help` at runtime rather than assuming
flag names, since the NeoForge options have moved between builds. If it bails
with an interface complaint, the installed packwiz differs from what's
expected.
- Mod names come from filenames with the trailing version stripped
(`create-1.21.1-6.0.4.jar` → `create`). It's a heuristic; rename the
generated `.pw.toml` files if you don't like the result.
- Hashes are pinned. Replacing a jar in place under the same filename requires
a re-sync, or clients fail the hash check.