#!/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