From 088d5d3e5186e4f179c03b5262f8c9e30a5f16f3 Mon Sep 17 00:00:00 2001 From: Daniel Ceregatti Date: Fri, 19 Apr 2024 08:03:18 -0700 Subject: [PATCH] Implement server restarting via messages.xml. Trim down the container to only what it really needs. Upgrade containers to bookworm. Upgrade web's node to 20. Add bercon to the web container. Remove rcon from the server container. Remove motd text from config. Add roadmap and update docs. --- README.md | 4 +++- ROADMAP.md | 26 ++++++++++++++++++----- docker-compose.yml | 4 ++-- files/messages.xml | 14 ++++++++++++ files/serverDZ.cfg | 2 +- server/Dockerfile | 24 +++++++-------------- server/bin/dz | 53 ++++++++++++++++++++++++---------------------- web/Dockerfile | 23 +++++++++++--------- 8 files changed, 90 insertions(+), 60 deletions(-) create mode 100644 files/messages.xml diff --git a/README.md b/README.md index bebb7fa..02e87a2 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,12 @@ This project started when the Linux DayZ server was released for DayZ experiment * Some mods are known to crash the server on startup: * [DayZ Expansion AI](https://steamcommunity.com/sharedfiles/filedetails/?id=2792982069) - * [Red Falcon Flight System Heliz](https://steamcommunity.com/workshop/filedetails/?id=2692979668) + * [Red Falcon Flight System Heliz](https://steamcommunity.com/workshop/filedetails/?id=2692979668) - Bug report [here](https://feedback.bistudio.com/T176564) * Some mods work, but have bugs: * [DayZ Expansion Groups](https://steamcommunity.com/sharedfiles/filedetails/?id=2792983364) * The save file becomes corrupted and when the server restarts so the changes do not persist. +* There are other bugs: + * (Server doesn't stop with SIGTERM)[https://feedback.bistudio.com/T170721] This project is a work in progress: See the [roadmap](ROADMAP.md). diff --git a/ROADMAP.md b/ROADMAP.md index e232235..f3d69d3 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -6,13 +6,29 @@ * Login to Steam * Install base files * Search for mods + * Currently using the Steam Web API, which requires a developer key. * Add / Remove / Update mods * Create a server - * Configure server settings - * + * Server manager + * Activate / Deactivate mods + * Change mod settings + * Change server settings + * Update server files + * Start / Stop / Restart server * Start / Stop / Restart server - * Server RCON - * Server manager mod with web interface + * Server RCON UI + * Send commands * Server management - * Docker compose \ No newline at end of file + * Spin up a server + * Activate / Deactivate mods + * Change server settings via a UI + * RCON + * XML / JSON file manager + * Add / remove / update values. + * Validate XML / JSON + + +Unsorted: + +Server status shows storage age, stats \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index e439586..1fdae5d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -65,8 +65,8 @@ services: # - 2303:2303/udp # # Steam port # - 27016:27016/udp - # Always restart, unless stopped - restart: unless-stopped + # The server script execs itself when the server exits, unless told not to by `dz stop` + restart: no # Allows attaching a debugger from the host # cap_add: # - SYS_PTRACE diff --git a/files/messages.xml b/files/messages.xml new file mode 100644 index 0000000..1fb0cbb --- /dev/null +++ b/files/messages.xml @@ -0,0 +1,14 @@ + + + + 240 + 1 + The server will restart in #tmin minutes... + + + 1 + 30 + 1 + Welcome to #name! + + diff --git a/files/serverDZ.cfg b/files/serverDZ.cfg index bf39dcf..2bc3921 100644 --- a/files/serverDZ.cfg +++ b/files/serverDZ.cfg @@ -30,7 +30,7 @@ loginQueueMaxPlayers=500; // The maximum number of players that can wait i instanceId = 1; // DayZ server instance id, to identify the number of instances per box and their storage folders with persistence files storageAutoFix = 1; // Checks if the persistence files are corrupted and replaces corrupted ones with empty ones (value 0-1) -motd[] = {"This line never shows up...", "DayZ on Linux for Linux"}; // Message of the day displayed in the in-game chat +motd[] = {"", ""}; // Message of the day displayed in the in-game chat respawnTime = 0; // Sets the respawn delay (in seconds) before the player is able to get a new character on the server, when the previous one is dead motdInterval = 300; // Time interval (in seconds) between each message diff --git a/server/Dockerfile b/server/Dockerfile index 8512593..631ae44 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -1,18 +1,16 @@ -FROM debian:bullseye +FROM debian:bookworm -# Set debconf to run non-interactively and agree to the SteamCMD EULA +# Replace shell with bash so we can source files +RUN rm /bin/sh && ln -s /bin/bash /bin/sh + +# Set debconf to run non-interactively RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections -# Add contrib and backports -RUN sed -i /etc/apt/sources.list -e 's/main/main contrib non-free/' - -RUN echo 'deb http://deb.debian.org/debian bullseye-backports main non-free' >> /etc/apt/sources.list +# Add backports and contrib +RUN sed -i /etc/apt/sources.list.d/debian.sources -e 's/Components: main/Components: main contrib non-free/g' # Install _only_ the necessary packages RUN apt-get update && apt-get -y upgrade && apt-get -y install --no-install-recommends \ - curl \ - ca-certificates \ - git \ gwenhywfar-tools \ jq \ libsdl2-2.0-0 \ @@ -21,13 +19,10 @@ RUN apt-get update && apt-get -y upgrade && apt-get -y install --no-install-reco locales \ nano \ patch \ - python3 \ procps \ wget \ xmlstarlet -RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.9 1 - # Set the locale RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen ENV LANG en_US.UTF-8 @@ -37,9 +32,6 @@ ENV LC_ALL en_US.UTF-8 # Add our scripts directory to PATH ENV PATH /files/bin:/server/bin:${PATH} -# Add py3rcon -RUN cd /usr/local && git clone https://github.com/indepth666/py3rcon.git - # Setup a non-privileged user ARG USER_ID @@ -54,6 +46,6 @@ USER user # The dayzserver script expects a home directory to itself. WORKDIR /home/user -# Run the server. +# Run the server. The use of both ENTRYPOINT and CMD is to allow for development mode. ENTRYPOINT ["entrypoint.sh"] CMD ["start.sh"] diff --git a/server/bin/dz b/server/bin/dz index 7f8ddd2..ba5d836 100755 --- a/server/bin/dz +++ b/server/bin/dz @@ -81,7 +81,7 @@ loadconfig(){ fi if [ "${passwd}" == "" ] then - printf "[ ${red}FAIL${default} ] Could not generate a passwort for RCON!\nOpen the Battleye config with 'dayzserver rcon'." + printf "[ ${red}FAIL${default} ] Could not generate a passwort for RCON!\n" exit 1 else cat > "${BE_SERVER_FILE}" < ~/py3rcon.config.json } # Make sure to clean up and report on exit, as these files remain in the container's volume @@ -130,8 +125,9 @@ report() { # Back these files up into a new directory with the current time stamp in the name DIR="${SERVER_PROFILE}/logs/$(date +%Y-%m-%d-%H-%M-%S)" mkdir -p ${DIR} - cd ${SERVER_PROFILE} - mv -v *.log *.RPT *.mdmp ${DIR} 2> /dev/null + pushd ${SERVER_PROFILE} > /dev/null + mv -v *.log *.RPT *.mdmp ${DIR} 2> /dev/null || true + popd > /dev/null } mergexml(){ @@ -151,6 +147,17 @@ mergexml(){ -o -name "init.c" \ \) -exec cp -v {} ${SERVER_FILES}{} \; + # Same for any files in the db subdirectory we may modify + find /mpmissions/${MAP}/db \( \ + -name "messages.xml" \ + \) -exec cp -v {} ${SERVER_FILES}{} \; + + # For now let's just replace the file instead of merging, as the upstream file has nothing in it. + if [ -f ${FILES}/messages.xml ] + then + cp -v ${FILES}/messages.xml ${MPMISSIONS}/${MAP}/db/messages.xml + fi + echo # Remove previously copied keys and restore the default key @@ -376,6 +383,8 @@ start(){ done exit 0 fi + # Clean up from previous runs + rm -f ${SERVER_FILES}/dont_restart # Ensure mpmissions has at least one map. If not, copy it from the local read-only volume that stores pristine mpmissons directories if [ ! -d "${MPMISSIONS}/${MAP}" ] && [ -d "/mpmissions/${MAP}" ] then @@ -384,10 +393,6 @@ start(){ echo cp -av /mpmissions/${MAP} ${MPMISSIONS} fi - # Do the report on exit. Set here so that it only happens once we're starting the server, and not for other actions. - trap ' - report - ' EXIT get_mods mergexml if [[ ${DONT_START} != "" ]] @@ -408,25 +413,28 @@ start(){ echo ${parameters} > /tmp/parameters ./DayZServer "${mod_command_line}" ${parameters} EXIT_CODE=$? - if [ -f ${SERVER_FILES}/restart ] - then - rm -f ${SERVER_FILES}/restart - EXIT_CODE=42 - fi printf "\n[ ${yellow}DayZ${default} ] Server exited. Exit code: ${EXIT_CODE}\n" - exit ${EXIT_CODE} + report + if [ -f ${SERVER_FILES}/dont_restart ] + then + printf "\n[ ${red}DayZ${default} ] Server script exiting, container shutting down...\n" + else + printf "\n[ ${green}DayZ${default} ] Restarting server\n" + exec dz start + fi + exit 0 } # Restarts the server by forcing an exit code other than 0, causing docker to restart the container. restart(){ - touch "${SERVER_FILES}/restart" echo "Restarting DayZ server..." kill -TERM $(pidof DayZServer) } -# Stops the server cleanly and exits 0, which will stop the container. +# Stops the server but does not restart it. stop(){ echo "Stopping DayZ server..." + touch "${SERVER_FILES}/dont_restart" kill -TERM $(pidof DayZServer) } @@ -503,11 +511,6 @@ activate(){ status } -# Our internal RCON -rcon(){ - exec /usr/local/py3rcon/py3rcon.py --gui ~/py3rcon.config.json -} - # List mods activelist(){ X=1 diff --git a/web/Dockerfile b/web/Dockerfile index 84f1219..49fa285 100644 --- a/web/Dockerfile +++ b/web/Dockerfile @@ -1,4 +1,7 @@ -FROM debian:bullseye +FROM debian:bookworm + +# Replace shell with bash so we can source files +RUN rm /bin/sh && ln -s /bin/bash /bin/sh # Set debconf to run non-interactively and agree to the SteamCMD EULA RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections \ @@ -6,16 +9,11 @@ RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selectio && echo steam steam/license note '' | debconf-set-selections \ && dpkg --add-architecture i386 -# Add contrib and backports -RUN sed -i /etc/apt/sources.list -e 's/main/main contrib non-free/' - -RUN echo 'deb http://deb.debian.org/debian bullseye-backports main non-free' >> /etc/apt/sources.list +# Add backports and contrib +RUN sed -i /etc/apt/sources.list.d/debian.sources -e 's/Components: main/Components: main contrib non-free/g' # Install _only_ the necessary packages RUN apt-get update && apt-get -y upgrade && apt-get -y install --no-install-recommends \ - curl \ - ca-certificates \ - git \ gwenhywfar-tools \ jq \ libxml2-utils \ @@ -40,11 +38,11 @@ ENV PATH /usr/games:/files/bin:/web/bin:${PATH} # Install nodejs RUN mkdir /usr/local/nvm ENV NVM_DIR /usr/local/nvm -ENV NODE_VERSION 18.18.2 +ENV NODE_VERSION 20.12.2 RUN echo $NODE_VERSION # Install nvm with node and npm -RUN curl https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash \ +RUN wget -O - https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash \ && . $NVM_DIR/nvm.sh \ && nvm install $NODE_VERSION \ && nvm alias default $NODE_VERSION \ @@ -64,6 +62,11 @@ RUN groupadd -g ${USER_ID} user && \ # Shut steamcmd up RUN cd /usr/lib/i386-linux-gnu && ln -s /web/bin/steamservice.so +# Add bercon https://github.com/WoozyMasta/bercon +RUN wget https://github.com/WoozyMasta/bercon/releases/download/1.0.0/bercon \ + && chmod +x bercon \ + && mv bercon /usr/bin + # Use our non-privileged user USER user