Last active
July 5, 2025 20:26
-
-
Save CraigWilsonOZ/22bf4bc9a48e75970bbebc2de95f1dea to your computer and use it in GitHub Desktop.
Minecraft Fabric Server Setup Script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| #============================================================================== | |
| # Minecraft Fabric Server Setup Script | |
| # | |
| # Author: Craig Wilson | |
| # Version: 2.1 (Fabric Edition) | |
| # Last Modified: 2025-07-05 | |
| # | |
| # Description: | |
| # This script automates the setup of a Minecraft Fabric server on a | |
| # Debian-based system. It is designed to be rerunnable; it will check the | |
| # system state and only perform actions that are necessary. | |
| # | |
| # Readme: | |
| # https://craigwilson.blog/post/2025/2025-06-22-minecraftserverfabric/ | |
| # | |
| #============================================================================== | |
| # --- Script Configuration and Preamble --- | |
| # Exit immediately if a command exits with a non-zero status. | |
| set -euo pipefail | |
| # Set DEBIAN_FRONTEND to noninteractive to prevent prompts. | |
| export DEBIAN_FRONTEND=noninteractive | |
| # --- Function Definitions --- | |
| # | |
| # Performs initial checks to ensure script can run successfully. | |
| # | |
| initial_checks() { | |
| echo "▶ Performing initial checks..." | |
| # Check for root privileges | |
| if [ "$EUID" -ne 0 ]; then | |
| echo "ERROR: Please run this script as root or using sudo." >&2 | |
| exit 1 | |
| fi | |
| } | |
| # | |
| # Displays the help message for the script. | |
| # | |
| display_help() { | |
| cat << EOF | |
| Minecraft Fabric Server Setup Script - v2.1 | |
| This script automates the setup of a Minecraft Fabric server on a Debian-based system. | |
| It is rerunnable and will skip steps that are already completed. | |
| Usage: | |
| sudo ./setup-fabric.sh | |
| Options: | |
| -h, --help Display this help message and exit. | |
| The script must be run with root (sudo) privileges. All server configuration | |
| can be adjusted in the '== Configuration ==' section of the script file. | |
| EOF | |
| } | |
| # === Configuration === | |
| MINECRAFT_USER="mcfabric" | |
| INSTALL_DIR="/opt/mcfabric" | |
| SERVER_DIR="$INSTALL_DIR/server" | |
| TOOLS_DIR="$INSTALL_DIR/tools" | |
| LOGS="$INSTALL_DIR/logs" | |
| BACKUP_DIR="$INSTALL_DIR/backup" | |
| MCRCON_DIR="$TOOLS_DIR/mcrcon" | |
| # --- Fabric & Minecraft Configuration --- | |
| # These three versions are linked. Get compatible versions from https://fabricmc.net/use/server/ | |
| MINECRAFT_VERSION="1.21.7" | |
| FABRIC_LOADER_VERSION="0.16.14" | |
| FABRIC_INSTALLER_VERSION="1.1.0" | |
| # This URL is now built from the versions above using the official Fabric Meta API. | |
| FABRIC_INSTALLER_URL="https://meta.fabricmc.net/v2/versions/loader/${MINECRAFT_VERSION}/${FABRIC_LOADER_VERSION}/${FABRIC_INSTALLER_VERSION}/server/jar" | |
| FABRIC_INSTALLER_JAR="fabric-installer.jar" | |
| FABRIC_SERVER_JAR="fabric-server-launch.jar" | |
| # --- General Server Configuration --- | |
| PASSWORD=$(date +%s | sha256sum | base64 | head -c 32 ; echo) | |
| MAX_MEMORY="8192M" | |
| MIN_MEMORY="8192M" | |
| MINECRAFT_PORT="25565" | |
| RCON_PORT="25575" | |
| MAX_PLAYERS="20" | |
| JDK_VERSION="openjdk-21-jre-headless" | |
| # --- Script Execution --- | |
| # Parse command-line options for help flag | |
| if [[ "${1-}" =~ ^(-h|--help)$ ]]; then | |
| display_help | |
| exit 0 | |
| fi | |
| # Call the initial checks function. | |
| initial_checks | |
| echo "[+] Starting Minecraft Fabric Server Setup for user '$MINECRAFT_USER'" | |
| # === Install Dependencies === | |
| echo "▶ Installing dependencies..." | |
| sudo apt-get update | |
| sudo apt-get install -y $JDK_VERSION git build-essential cron wget | |
| # === Create User and Directories === | |
| echo "▶ Ensuring user and directories exist..." | |
| sudo useradd -r -m -U -d "$INSTALL_DIR" -s /bin/bash "$MINECRAFT_USER" || echo "✔ User '$MINECRAFT_USER' already exists." | |
| sudo mkdir -p "$SERVER_DIR" "$TOOLS_DIR" "$BACKUP_DIR" | |
| # Create a symbolic link for the logs | |
| if [ -d "$LOGS" ] && [ ! -L "$LOGS" ]; then | |
| sudo rmdir "$LOGS" | |
| fi | |
| if [ ! -e "$LOGS" ]; then | |
| echo "▶ Linking server logs directory..." | |
| sudo -u "$MINECRAFT_USER" ln -s "$SERVER_DIR/logs" "$LOGS" | |
| fi | |
| sudo chown -R "$MINECRAFT_USER":"$MINECRAFT_USER" "$INSTALL_DIR" | |
| sudo chown -h "$MINECRAFT_USER":"$MINECRAFT_USER" "$LOGS" | |
| # === Accept EULA === | |
| echo "▶ Ensuring EULA is accepted..." | |
| sudo -u "$MINECRAFT_USER" tee "$SERVER_DIR/eula.txt" > /dev/null <<EOF | |
| eula=true | |
| EOF | |
| # === Install Fabric Server === | |
| if [ ! -f "$SERVER_DIR/$FABRIC_SERVER_JAR" ]; then | |
| echo "▶ Fabric server not found. Starting installation..." | |
| echo "▶ Downloading Fabric Installer for Minecraft $MINECRAFT_VERSION..." | |
| sudo -u "$MINECRAFT_USER" wget --content-disposition -O "$SERVER_DIR/$FABRIC_INSTALLER_JAR" "$FABRIC_INSTALLER_URL" | |
| echo "▶ Running Fabric installer..." | |
| sudo -u "$MINECRAFT_USER" -H bash -c "cd '$SERVER_DIR' && /usr/bin/java -jar '$FABRIC_INSTALLER_JAR' server -mcversion '$MINECRAFT_VERSION' -loader '$FABRIC_LOADER_VERSION' -downloadMinecraft" | |
| else | |
| echo "✔ Fabric server JAR already exists. Skipping installation." | |
| fi | |
| # === Create Server Properties === | |
| echo "▶ Creating/updating server.properties..." | |
| sudo -u "$MINECRAFT_USER" tee "$SERVER_DIR/server.properties" > /dev/null <<EOF | |
| #Minecraft server properties | |
| accepts-transfers=false | |
| allow-flight=false | |
| allow-nether=true | |
| broadcast-console-to-ops=true | |
| broadcast-rcon-to-ops=true | |
| bug-report-link= | |
| difficulty=easy | |
| enable-command-block=false | |
| enable-jmx-monitoring=false | |
| enable-query=false | |
| enable-rcon=true | |
| enable-status=true | |
| enforce-secure-profile=true | |
| enforce-whitelist=false | |
| entity-broadcast-range-percentage=100 | |
| force-gamemode=false | |
| function-permission-level=2 | |
| gamemode=survival | |
| generate-structures=true | |
| generator-settings={} | |
| hardcore=false | |
| hide-online-players=false | |
| initial-disabled-packs= | |
| initial-enabled-packs=vanilla | |
| level-name=world | |
| level-seed= | |
| level-type=minecraft\:normal | |
| log-ips=true | |
| max-chained-neighbor-updates=1000000 | |
| max-players=$MAX_PLAYERS | |
| max-tick-time=60000 | |
| max-world-size=29999984 | |
| motd=A Minecraft Server | |
| network-compression-threshold=256 | |
| online-mode=true | |
| op-permission-level=4 | |
| pause-when-empty-seconds=60 | |
| player-idle-timeout=0 | |
| prevent-proxy-connections=false | |
| pvp=true | |
| query.port=$MINECRAFT_PORT | |
| rate-limit=0 | |
| rcon.password=$PASSWORD | |
| rcon.port=$RCON_PORT | |
| region-file-compression=deflate | |
| require-resource-pack=false | |
| resource-pack= | |
| resource-pack-id= | |
| resource-pack-prompt= | |
| resource-pack-sha1= | |
| server-ip= | |
| server-port=$MINECRAFT_PORT | |
| simulation-distance=10 | |
| spawn-monsters=true | |
| spawn-protection=16 | |
| sync-chunk-writes=true | |
| text-filtering-config= | |
| text-filtering-version=0 | |
| use-native-transport=true | |
| view-distance=10 | |
| white-list=false | |
| EOF | |
| # === Install and Build MCRCON === | |
| if [ ! -d "$MCRCON_DIR" ]; then | |
| echo "▶ Cloning and building mcrcon..." | |
| sudo -u "$MINECRAFT_USER" git clone https://github.com/Tiiffi/mcrcon.git "$MCRCON_DIR" | |
| sudo -u "$MINECRAFT_USER" bash -c "cd '$MCRCON_DIR' && gcc -std=gnu11 -pedantic -Wall -Wextra -O2 -s -o mcrcon mcrcon.c" | |
| else | |
| echo "✔ mcrcon directory already exists. Skipping clone and build." | |
| fi | |
| # === Create Helper Scripts === | |
| echo "▶ Creating/updating helper scripts..." | |
| sudo -u "$MINECRAFT_USER" tee "$TOOLS_DIR/connect-mcrcon.sh" > /dev/null <<EOF | |
| #!/bin/bash | |
| $MCRCON_DIR/mcrcon -H 127.0.0.1 -P $RCON_PORT -p "$PASSWORD" -t | |
| EOF | |
| sudo -u "$MINECRAFT_USER" tee "$TOOLS_DIR/backup-minecraft.sh" > /dev/null <<EOF | |
| #!/bin/bash | |
| function rcon { | |
| "$MCRCON_DIR/mcrcon" -H 127.0.0.1 -P $RCON_PORT -p "$PASSWORD" "\$1" | |
| } | |
| echo "Running Minecraft backup..." | |
| rcon "save-off"; rcon "save-all"; sleep 10 | |
| tar -cvpzf "$BACKUP_DIR/server-\$(date +%F-%H-%M).tar.gz" "$SERVER_DIR" | |
| rcon "save-on" | |
| echo "Backup complete." | |
| find "$BACKUP_DIR" -type f -mtime +31 -name '*.gz' -delete | |
| EOF | |
| sudo -u "$MINECRAFT_USER" tee "$TOOLS_DIR/start-minecraft.sh" > /dev/null <<EOF | |
| #!/bin/bash | |
| cd "$SERVER_DIR" || exit | |
| /usr/bin/java -Xmx$MAX_MEMORY -Xms$MIN_MEMORY -jar "$FABRIC_INSTALLER_JAR" nogui | |
| EOF | |
| # Make all shell scripts executable | |
| sudo chmod +x $TOOLS_DIR/*.sh | |
| # === Create Backup Cron Job === | |
| CRON_JOB="0 3 * * * $TOOLS_DIR/backup-minecraft.sh >> $LOGS/backup.log 2>&1" | |
| if ! (sudo -u "$MINECRAFT_USER" crontab -l 2>/dev/null || true) | grep -Fq "$CRON_JOB"; then | |
| echo "▶ Creating daily backup cron job..." | |
| (sudo -u "$MINECRAFT_USER" crontab -l 2>/dev/null || true; echo "$CRON_JOB") | sudo -u "$MINECRAFT_USER" crontab - | |
| else | |
| echo "✔ Backup cron job already exists. Skipping." | |
| fi | |
| # === Create Systemd Service === | |
| echo "▶ Creating/updating systemd service file..." | |
| sudo tee /etc/systemd/system/$MINECRAFT_USER.service > /dev/null <<EOF | |
| [Unit] | |
| Description=Minecraft Fabric Server | |
| After=network.target | |
| [Service] | |
| User=$MINECRAFT_USER | |
| WorkingDirectory=$SERVER_DIR | |
| ExecStart=/usr/bin/java -Xmx$MAX_MEMORY -Xms$MIN_MEMORY -jar "$SERVER_DIR/$FABRIC_INSTALLER_JAR" nogui | |
| ExecStop=$MCRCON_DIR/mcrcon -H 127.0.0.1 -P $RCON_PORT -p $PASSWORD stop | |
| Restart=on-failure | |
| SuccessExitStatus=0 1 | |
| [Install] | |
| WantedBy=multi-user.target | |
| EOF | |
| # === Enable and Start Service (Safely) === | |
| sudo systemctl daemon-reload | |
| if ! sudo systemctl is-active --quiet $MINECRAFT_USER; then | |
| echo "▶ Starting and enabling the minecraft service..." | |
| sudo systemctl enable --now $MINECRAFT_USER | |
| else | |
| echo "✔ Minecraft service is already active. Ensuring it is enabled on boot." | |
| sudo systemctl enable $MINECRAFT_USER | |
| echo "[!] The service definition or server properties may have changed. Run 'sudo systemctl restart $MINECRAFT_USER' to apply all changes." | |
| fi | |
| echo "" | |
| echo "[+] Setup Complete. Your Fabric server is running under user '$MINECRAFT_USER'." | |
| echo "[+] To add mods, place your .jar files in: $SERVER_DIR/mods" | |
| echo "[*] To connect to the server console, run: $TOOLS_DIR/connect-mcrcon.sh" | |
| echo "[*] Your RCON password is: $PASSWORD" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment