Jump to content

brenno263

Member
  • Posts

    1
  • Joined

  • Last visited

brenno263's Achievements

  1. I've found a few ways around this, but I made an account to share my favorite, since it took me a fair bit of time to learn how to put this stuff together. I'm running a zomboid server in a docker container that I built myself, another learning exercise, https://github.com/brenno263/zomboid_server_container It's not perfect, and certainly isn't documented enough for public use, so let me know if that's something that anyone wants and I can write a nice guide and some better options. Anyways, the main point of this is to share how I handled SIGTERM. Well, here's my docker entry script: #!/bin/bash ARGS="-Xmx8G -Xms4G -- -servername da-hood -cachedir=$DATA_DIR" if [ -n "$ADMIN_PASSWORD" ]; then ARGS="$ARGS -adminpassword $ADMIN_PASSWORD" fi echo "Using args: $ARGS" # Set up our fifo pipe to push commands into the running server. ZOMBOID_STDIN_PIPE="zomboid_stdin_pipe" mkfifo "$ZOMBOID_STDIN_PIPE" # Fix to a bug in start-server.sh that prevents zomboid from correctly preloading a library: # ERROR: ld.so: object 'libjsig.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored. export LD_LIBRARY_PATH="${APP_DIR}/jre64/lib:${LD_LIBRARY_PATH}" # Start the server, taking stdin from our pipe so that we can talk to it later. # We use the read/write redirect "<>" since it doesn't block while the pipe is empty. # (the server should not be stopped to wait for a piped command. "<" would have this effect.) # Notice that we don't redirect server outputs, so they still land in the terminal. bash $APP_DIR/start-server.sh $ARGS 0<> "$ZOMBOID_STDIN_PIPE" & SERVER_PID=$! echo "THE PID OF THE SERVER IS $SERVER_PID!" # Set QUIT to 1 when we get a SIGTERM or SIGINT, breaking the following sleep loop. QUIT=0 trap "QUIT=1" TERM INT # Loop until we've decided to quit or the server is somehow not running. while [ "$QUIT" -eq "0" ] && kill -0 "$SERVER_PID" >& /dev/null ; do sleep 10; echo "sleeping" # If there's any input hanging out on stdin, go ahead and push it through the pipe. # This helps us maintain interactivity when running this script. if read -t 0 ; then echo "found stdin, writing to pipe." while read -r -t 0.5 line; do echo "writing $line" echo "$line" > "$ZOMBOID_STDIN_PIPE" done fi done # Once we've broken the sleep loop, send the quit command to the server and wait for it to stop. echo "quitting" echo "quit" > "$ZOMBOID_STDIN_PIPE" echo "waiting" wait # waits for child processes to complete rm "$ZOMBOID_STDIN_PIPE" echo "done" With clever use of a named pipe, I'm able to catch any signals, send a command to the server, and wait for it to close. Of course, this solution is for a Docker container, where you have one entry script that gets SIGTERM'd when the container wants to close. It could be adapted without too much trouble for a SystemD setup, though I am abusing Docker's ephemeral filesystem by spitting out a named pipe without a unique name and expecting that not to matter. If you are using SystemD however, there's an even better way to achieve this. As seen in this Nixos module for a minecraft server: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/games/minecraft-server.nix, around line 184 they configure a SystemD-managed socket wired into the stdin of the process. Then in the exit script on line 26, they are able to echo the quit command into that socket, stopping the server gracefully. This approach could absolutely be used for zomboid as well. Edit to add: I forgot that the PZWiki reccomends exactly this approach with SystemD lmao. Would have been way simpler to just link to their guide. https://pzwiki.net/wiki/Dedicated_server#System.d Anyways, I know this is a lot for anyone who isn't deeply invested in linux-land. Feel free to ask me any questions
×
×
  • Create New...