Files
mc-lan-party/server/setup-server.sh
T
Mykhailo Ivanchenko cd694a67b6 Move file distribution to Gitea, deploy server on mivanchenko.de
Drops the standalone fileserver systemd unit from setup-server.sh in
favor of Gitea's already-public raw-file serving. Adds VR (Vivecraft)
and quest (FTB Quests) mod docs, the DH/Chunky server-side crash
warning, and documents the real deployment target (always-on homelab
box, not a venue-local machine).
2026-10-23 15:01:00 +02:00

126 lines
4.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# One-time setup for the LAN party's dedicated box: installs a Forge 1.20.1
# Minecraft server and wraps it in lazymc (auto-sleep when empty / auto-wake
# on connect), as a systemd service so it runs unattended for the 3 days.
#
# File distribution (install.sh/install.ps1/modpack.zip) is NOT handled by
# this script — see HOSTING.md, it's served from Gitea instead.
#
# Target: a Linux machine (Debian/Ubuntu/etc with systemd) at the venue.
# Run as a normal user with sudo rights: ./setup-server.sh
set -euo pipefail
# ---- EDIT ME ----
FORGE_MC_VERSION="1.20.1"
FORGE_BUILD="47.4.28" # current recommended build for 1.20.1 — check files.minecraftforge.net if this is stale
MC_PUBLIC_PORT=25565 # what players connect to (lazymc listens here)
MC_INTERNAL_PORT=25566 # real server listens here, lazymc proxies to it
SLEEP_AFTER="5m" # idle time before lazymc stops the real server
MIN_RAM="2G"
MAX_RAM="6G" # 5-8 players; see ../HOSTING.md sizing table — bump to 8G (9-12p) or 10-12G (13-15p)
# ------------------
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SERVER_DIR="$BASE_DIR/mcserver"
FORGE_VERSION="${FORGE_MC_VERSION}-${FORGE_BUILD}"
command -v java >/dev/null || { echo "Java not found. Install a Java 17+ JDK (e.g. 'sudo apt install -y openjdk-17-jre-headless') then re-run."; exit 1; }
mkdir -p "$SERVER_DIR"
# ---- 1. Install the Forge server ----
if [[ ! -f "$SERVER_DIR/run.sh" ]]; then
echo "==> Downloading Forge $FORGE_VERSION installer"
installer_url="https://maven.minecraftforge.net/net/minecraftforge/forge/${FORGE_VERSION}/forge-${FORGE_VERSION}-installer.jar"
curl -fsSL -o "$SERVER_DIR/forge-installer.jar" "$installer_url"
read -rp "Do you accept the Minecraft EULA (https://aka.ms/MinecraftEULA)? [y/N] " eula_ans
[[ "$eula_ans" =~ ^[Yy]$ ]] || { echo "EULA not accepted, aborting."; exit 1; }
echo "==> Running Forge server installer"
(cd "$SERVER_DIR" && java -jar forge-installer.jar --installServer)
echo "eula=true" > "$SERVER_DIR/eula.txt"
else
echo "==> Forge server already installed, skipping"
fi
# server.properties: lazymc will rewrite host/port/rcon itself, we just set gameplay-relevant bits
touch "$SERVER_DIR/server.properties"
for kv in "online-mode=false" "motd=LAN Party - Create & Delight" "difficulty=normal" "max-players=20"; do
key="${kv%%=*}"
if grep -q "^${key}=" "$SERVER_DIR/server.properties" 2>/dev/null; then
sed -i "s/^${key}=.*/${kv}/" "$SERVER_DIR/server.properties"
else
echo "$kv" >> "$SERVER_DIR/server.properties"
fi
done
mkdir -p "$SERVER_DIR/mods"
echo "==> NOTE: copy the same mod jars from your client modpack's mods/ folder into $SERVER_DIR/mods/ (Create, Flywheel, Farmer's Delight + addons, JEI, etc.) before first boot."
# ---- 2. Install lazymc ----
if [[ ! -x "$BASE_DIR/lazymc" ]]; then
echo "==> Downloading latest lazymc"
api_url="https://api.github.com/repos/timvisee/lazymc/releases/latest"
release_json="$(curl -fsSL "$api_url")"
asset_url="$(echo "$release_json" | grep -oE '"browser_download_url": *"[^"]+linux-x64"' | cut -d'"' -f4 | head -n1)"
[[ -n "$asset_url" ]] || { echo "Could not find linux-x64 lazymc asset" >&2; exit 1; }
curl -fsSL -o "$BASE_DIR/lazymc" "$asset_url"
chmod +x "$BASE_DIR/lazymc"
else
echo "==> lazymc already present, skipping"
fi
cat > "$BASE_DIR/lazymc.toml" <<EOF
[server]
directory = "$SERVER_DIR"
command = "bash run.sh nogui -Xms${MIN_RAM} -Xmx${MAX_RAM}"
address = "127.0.0.1:${MC_INTERNAL_PORT}"
freeze_process = false
wake_whitelist = false
[public]
address = "0.0.0.0:${MC_PUBLIC_PORT}"
[time]
sleep_after = "${SLEEP_AFTER}"
minimum_online_time = "1m"
[motd]
sleeping = "☀ Server is asleep, join to wake it up"
starting = "⏳ Server is starting, hang tight..."
[rcon]
enabled = true
port = 25575
EOF
echo "==> Wrote lazymc.toml (sleeps after ${SLEEP_AFTER} empty, public port ${MC_PUBLIC_PORT} -> internal ${MC_INTERNAL_PORT})"
# ---- 3. systemd services ----
sudo tee /etc/systemd/system/mc-lazymc.service >/dev/null <<EOF
[Unit]
Description=LAN party Minecraft server (via lazymc)
After=network.target
[Service]
Type=simple
WorkingDirectory=${BASE_DIR}
ExecStart=${BASE_DIR}/lazymc
Restart=on-failure
User=${USER}
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now mc-lazymc.service
echo "==> Done."
echo " - Minecraft server: public port ${MC_PUBLIC_PORT}, sleeps after ${SLEEP_AFTER} idle, wakes on connect."
echo " - Install scripts + modpack.zip are served from Gitea, not this box — see ../HOSTING.md."
echo " - Copy your client mod jars into ${SERVER_DIR}/mods/ if you haven't yet, then: sudo systemctl restart mc-lazymc"
if command -v ufw >/dev/null && sudo ufw status | grep -q "Status: active"; then
echo "==> ufw is active — opening ${MC_PUBLIC_PORT}/tcp"
sudo ufw allow "${MC_PUBLIC_PORT}/tcp"
fi