The flag was gated on the admin database not existing yet, treating the file's presence as proof the admin user had been created. It is not: PZ creates the DB file in ServerWorldDatabase.create() before it creates the admin user, so a boot interrupted between the two leaves a database with no admin in it. After that the guard withheld -adminpassword on every subsequent start, the server fell back to an interactive "Enter new administrator password:" prompt, read EOF because a detached container has no stdin, and died with NoSuchElementException. systemd restarted it into exactly the same state, 50 times, which is how this was found. Passing it unconditionally costs nothing when the admin already exists and removes the deadlock entirely. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
103 lines
3.7 KiB
Django/Jinja
103 lines
3.7 KiB
Django/Jinja
#!/bin/bash
|
|
# Project Zomboid Build 42 Server Entrypoint
|
|
# Based on IndifferentBroccoli/projectzomboid-server-docker
|
|
set -e
|
|
|
|
# Configuration
|
|
INSTALL_DIR="/project-zomboid"
|
|
CONFIG_DIR="/project-zomboid-config"
|
|
STEAMCMD="/home/steam/steamcmd/steamcmd.sh"
|
|
SERVER_NAME="${SERVER_NAME:-zomboid}"
|
|
PUID="${PUID:-1000}"
|
|
PGID="${PGID:-1000}"
|
|
MIN_RAM="${MIN_RAM:-{{ zomboid_min_ram }}}"
|
|
MAX_RAM="${MAX_RAM:-{{ zomboid_max_ram }}}"
|
|
|
|
echo "=== Project Zomboid Build 42 Server ({{ zomboid_preset_version }}) ==="
|
|
echo "Server Name: ${SERVER_NAME}"
|
|
echo "RAM: ${MIN_RAM} - ${MAX_RAM}"
|
|
|
|
# Set user permissions (IndifferentBroccoli approach)
|
|
echo "=== Setting file permissions ==="
|
|
usermod -o -u "${PUID}" steam
|
|
groupmod -o -g "${PGID}" steam
|
|
for dir in "${INSTALL_DIR}" "${CONFIG_DIR}"; do
|
|
# Recursing is a full inode walk over the install tree -- with 256 workshop
|
|
# mods that is real SSD churn on every restart, and a no-op after the first.
|
|
if [ "$(stat -c %u "${dir}")" = "${PUID}" ]; then
|
|
echo "=== ${dir} already owned by ${PUID}, skipping recursive chown ==="
|
|
else
|
|
chown -R steam:steam "${dir}"
|
|
fi
|
|
done
|
|
# Only chown writable parts of /home/steam (not read-only mounts)
|
|
chown steam:steam /home/steam
|
|
chown -R steam:steam /home/steam/steamcmd 2>/dev/null || true
|
|
chown -R steam:steam /home/steam/Steam 2>/dev/null || true
|
|
|
|
# Create required directories
|
|
mkdir -p "${CONFIG_DIR}/Server"
|
|
mkdir -p "${CONFIG_DIR}/Saves"
|
|
mkdir -p "${CONFIG_DIR}/db"
|
|
|
|
# Update/Install PZ dedicated server from the default (stable) branch
|
|
if [ "${AUTO_UPDATE:-true}" = "true" ]; then
|
|
echo "=== Updating Project Zomboid Server (Build 42 stable) ==="
|
|
su -c "${STEAMCMD} +runscript /home/steam/install.scmd" steam
|
|
echo "=== Update complete ==="
|
|
fi
|
|
|
|
# Configure JVM memory settings in ProjectZomboid64.json (Build 42 uses JSON config)
|
|
configure_memory() {
|
|
local json_file="${INSTALL_DIR}/ProjectZomboid64.json"
|
|
|
|
if [ ! -f "$json_file" ]; then
|
|
echo "=== ProjectZomboid64.json not found, skipping memory config ==="
|
|
return 0
|
|
fi
|
|
|
|
echo "=== Configuring JVM memory: Xms=${MIN_RAM}, Xmx=${MAX_RAM} ==="
|
|
|
|
# Update Xmx
|
|
sed -i "s/-Xmx[0-9]*[gGmM]*/-Xmx${MAX_RAM}/g" "$json_file"
|
|
|
|
# Update or add Xms
|
|
if grep -q "\-Xms" "$json_file"; then
|
|
sed -i "s/-Xms[0-9]*[gGmM]*/-Xms${MIN_RAM}/g" "$json_file"
|
|
else
|
|
# Insert -Xms before -Xmx
|
|
sed -i "s/\"-Xmx/\"-Xms${MIN_RAM}\",\n\t\t\"-Xmx/g" "$json_file"
|
|
fi
|
|
|
|
echo "=== Memory configuration complete ==="
|
|
}
|
|
configure_memory
|
|
|
|
# Build server arguments
|
|
# Note: -modfolders is NOT used - mods are configured via INI only
|
|
# Reference: IndifferentBroccoli/projectzomboid-server-docker
|
|
SERVER_ARGS="-cachedir=${CONFIG_DIR} -servername ${SERVER_NAME}"
|
|
|
|
# Always pass the admin password when we have one.
|
|
#
|
|
# This used to be gated on the admin DB not existing yet, on the assumption that
|
|
# the file's presence meant the admin user was already set up. It does not: PZ
|
|
# creates the DB file in ServerWorldDatabase.create() *before* it creates the
|
|
# admin user, so any boot interrupted between those two steps leaves a database
|
|
# that exists but has no admin. From then on the guard withheld the flag, the
|
|
# server fell back to an interactive "Enter new administrator password:" prompt,
|
|
# read EOF because a detached container has no stdin, and died with
|
|
# NoSuchElementException -- on every restart, forever.
|
|
if [ -n "${ADMIN_PASSWORD}" ]; then
|
|
SERVER_ARGS="${SERVER_ARGS} -adminpassword ${ADMIN_PASSWORD}"
|
|
fi
|
|
|
|
# Note: Server password is set via INI file, not command line args
|
|
|
|
# Start server
|
|
cd "${INSTALL_DIR}"
|
|
echo "=== Starting Project Zomboid Server ==="
|
|
echo "Connect to: home.debyl.io:16261"
|
|
|
|
exec su -c "export LD_LIBRARY_PATH=${INSTALL_DIR}/jre64/lib:\${LD_LIBRARY_PATH} && ./start-server.sh ${SERVER_ARGS}" steam
|