From 6fbb9bf2ada11bdac2e3c66cb68d1b46802be687 Mon Sep 17 00:00:00 2001 From: Daniel Ceregatti Date: Wed, 29 May 2024 02:45:11 -0700 Subject: [PATCH 01/11] Add support for two servers. This is a breaking change from before, as it creates new volumes with 1 and 2 in their names, allowing for 3, 4, ..., n. --- .gitignore | 2 +- README.md | 47 +++++++++++++++++++++++---------- docker-compose.yml | 63 +++++++++++++++++++++++++++++++++------------ files/bin/dz-common | 6 ++--- 4 files changed, 84 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index 0d7d73e..52906c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ .idea *.iml -.env +.env* node_modules/ diff --git a/README.md b/README.md index 02e87a2..29fa7c3 100644 --- a/README.md +++ b/README.md @@ -30,12 +30,33 @@ git clone https://ceregatti.org/git/daniel/dayzdockerserver.git cd dayzdockerserver ``` -Create a `.env` file that contains your user id. Usually the `${UID}` shell variable has this: +Create a `.env` file for the web container that contains your user id. Usually the `${UID}` shell variable has this: ```shell echo "export USER_ID=${UID}" | tee .env ``` +Repeat the above for server1, which uses .env1 (and so on): +```shell +echo "export USER_ID=${UID}" | tee .env1 +``` + +But each server must also set its own unique ports: +```shell +echo "export SERVER_PORT=2302" | tee -a .env1 +echo "export RCON_PORT=2303" | tee -a .env1 +echo "export STEAM_PORT=27016" | tee -a .env1 +``` + +Repeat the above for each server you want to run, making sure the ports are unique across all servers: +```shell +echo "export USER_ID=${UID}" | tee .env2 +echo "export SERVER_PORT=2312" | tee -a .env2 +echo "export RCON_PORT=2313" | tee -a .env2 +echo "export STEAM_PORT=27116" | tee -a .env2 + + +```shell Build the Docker images: ```shell @@ -76,7 +97,7 @@ hostname = "Something other than Server Name"; // Server name Install the server config file: ```shell -docker compose run --rm server dz c +docker compose run --rm server1 dz c ``` The maintenance of the config file is a work in progress. The goal is to create a facility for merging changes into the config file and maintain a paper trail of changes. @@ -86,18 +107,18 @@ Launch the stack into the background: docker compose up -d ``` -There will be nothing in mpmissions when the server container starts for the first time. A pristine copy of `dayzOffline.chernarusplus` will be copied from the `mpmission` volume to the server container. This will be the default map. To install other maps, see [Maps](#maps). +There will be nothing in mpmissions when a server container starts for the first time. A pristine copy of `dayzOffline.chernarusplus` will be copied from the `mpmission` volume to the server container. This will be the default map. To install other maps, see [Maps](#maps). To see the server log: ```shell -docker compose logs -f server +docker compose logs -f server1 ``` ## Stopping the server To stop the DayZ server: ```shell -docker compose exec server dz stop +docker compose exec server1 dz stop ``` If it exits cleanly, the container will also stop. Otherwise a crash is presumed and the server will restart. Ideally, the server would always exit cleanly, but... it's DayZ. @@ -126,13 +147,13 @@ A terminal-based RCON client is included: https://github.com/indepth666/py3rcon. The dz script manages what's necessary to configure and run it: ```shell -docker compose exec server dz rcon +docker compose exec server1 dz rcon ``` To reset the RCON password in the Battle Eye configuration file, simply delete it, and a random one will be generated on the next server startup: ```shell -docker compose run --rm server rm serverfiles/battleye/baserver_x64_active* +docker compose run --rm server1 rm serverfiles/battleye/baserver_x64_active* ``` Don't expect much from this RCON at this time. @@ -159,13 +180,13 @@ Don't forget to [bring it back up](#run). To stop the server: ```shell -docker compose exec server dz stop +docker compose exec server1 dz stop ``` The above sends the SIGINT signal to the server process. The server sometimes fails to stop with this signal. It may be necessary to force stop it with the SIGKILL: ```shell -docker compose exec server dz force +docker compose exec server1 dz force ``` When the server exits cleanly, i.e. exit code 0, the container also stops. Otherwise, a crash is presumed, and the server will be automatically restarted. @@ -180,8 +201,8 @@ docker compose down Interactive interface for managing mods. ``` -docker compose exec server dz activate id | add id1 | deactivate id | list | modupdate | remove id -docker compose exec server dz a id | add id1 | d id | l | m | r id +docker compose exec server1 dz activate id | add id1 | deactivate id | list | modupdate | remove id +docker compose exec server1 dz a id | add id1 | d id | l | m | r id ``` Look for mods in the [DayZ Workshop](https://steamcommunity.com/app/221100/workshop/). Browse to one. In its URL will be @@ -232,9 +253,7 @@ This allows access to the server container using exec. You can then start and st ```shell # Go into the server container -docker compose exec shell bash -# Because this is now in the environment and keeping the server from starting, it'd still keep the server from starting unless we unset it -unset DEVELOPMENT +docker compose exec server1 bash # See what the server status is dz s # Start it diff --git a/docker-compose.yml b/docker-compose.yml index 1fdae5d..9e05112 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,18 +1,24 @@ volumes: - # For steamcmd files and resource files used by the scripts + # Only in the web container. + # For steamcmd files and resource files used by the scripts. homedir_main: - # For Steam, for now - homedir_server: + # Shared by all containers. + # Mods. + mods: # Where the server files will be installed serverfiles: - # Server profile files - profiles: # Upstream mission files servermpmissions: + # Server-specific volumes + # For Steam, for now + homedir_server1: + homedir_server2: # Server mission files - mpmissions: - # Mods - mods: + mpmissions1: + mpmissions2: + # Server profile files + profiles1: + profiles2: services: @@ -37,21 +43,23 @@ services: env_file: - .env - server: + server1: build: context: server args: - USER_ID user: ${USER_ID} volumes: - - homedir_server:/home/user + # Common volumes + - ./files:/files + - mods:/mods + - ./server:/server - serverfiles:/serverfiles - servermpmissions:/mpmissions:ro - - mods:/mods - - mpmissions:/serverfiles/mpmissions - - profiles:/profiles - - ./files:/files - - ./server:/server + # Server-specific volumes + - homedir_server1:/home/user + - mpmissions1:/serverfiles/mpmissions + - profiles1:/profiles # To have the server show up in the LAN tab of the DayZ launcher, # it must run under host mode. network_mode: host @@ -77,4 +85,27 @@ services: # soft: -1 # hard: -1 env_file: - - .env + - .env1 + + # Copy and paste this for every other server you want to run, replacing 2 with 3, and so on. + server2: # <-- here + build: + context: server + args: + - USER_ID + user: ${USER_ID} + volumes: + # Common volumes + - ./files:/files + - mods:/mods + - ./server:/server + - serverfiles:/serverfiles + - servermpmissions:/mpmissions:ro + # Server-specific volumes + - homedir_server2:/home/user # <-- here + - mpmissions2:/serverfiles/mpmissions # <-- here + - profiles2:/profiles # <-- here + network_mode: host + restart: no + env_file: + - .env2 # <-- here diff --git a/files/bin/dz-common b/files/bin/dz-common index 2fa8606..1711603 100755 --- a/files/bin/dz-common +++ b/files/bin/dz-common @@ -5,9 +5,9 @@ set -eEa # If you want/need the server and rcon ports to be different, set them here. # The steam query port is set in serverDZ.cfg. -# Server port -port=2302 -rcon_port=2303 +# Server port. Set these in the .env file for the container. +port=${SERVER_PORT} +rcon_port=${RCON_PORT} # Don't change anything else. From 60fc1d58ee6d790914112c6a687e3789035e0fd7 Mon Sep 17 00:00:00 2001 From: Daniel Ceregatti Date: Wed, 29 May 2024 20:08:08 -0700 Subject: [PATCH 02/11] Add support for setting the steam query port via the environment. It's optional, but now we're going to always use it, so we normalized that setting in the serverDZ.cfg that we ship (which we should probably update, as 1.25 adds new entries). --- files/serverDZ.cfg | 2 +- server/bin/dz | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/files/serverDZ.cfg b/files/serverDZ.cfg index 2bc3921..2d8685c 100644 --- a/files/serverDZ.cfg +++ b/files/serverDZ.cfg @@ -49,7 +49,7 @@ adminLogPlayerList = 0; // 1 - log periodic player list with position every 5 enableDebugMonitor = 0; // shows info about the character using a debug window in a corner of the screen (value 0-1) -//steamQueryPort = 2305; // defines Steam query port, should fix the issue with server not being visible in client server browser +steamQueryPort = 27016; // defines Steam query port, should fix the issue with server not being visible in client server browser allowFilePatching = 1; // if set to 1 it will enable connection of clients with "-filePatching" launch parameter enabled diff --git a/server/bin/dz b/server/bin/dz index e949e40..99c0edf 100755 --- a/server/bin/dz +++ b/server/bin/dz @@ -11,6 +11,7 @@ mkdir -p ${SERVER_PROFILE}/battleye SERVER_CFG_FILE="serverDZ.cfg" SERVER_CFG_DST="${SERVER_PROFILE}/${SERVER_CFG_FILE}" SERVER_CFG_SRC="${FILES}/${SERVER_CFG_FILE}" +SERVER_CFG_SAVE="${SERVER_PROFILE}/${SERVER_CFG_FILE}.save" # Command line parameters except mod, as that is handled separately. parameters="-config=${SERVER_CFG_DST} -port=${port} -freezecheck -BEpath=${SERVER_PROFILE}/battleye -profiles=${SERVER_PROFILE} -nologs" @@ -62,10 +63,10 @@ loadconfig(){ exit 1 fi # Handle the initial server configuration file - if [ ! -f ${SERVER_CFG_DST} ] + if [ ! -f ${SERVER_CFG_SAVE} ] then echo "Creating initial server configuration file" - cp "${SERVER_CFG_SRC}" "${SERVER_CFG_DST}" + cp "${SERVER_CFG_SRC}" "${SERVER_CFG_SAVE}" fi # battleye config and rconpassword setup # The server creates a new file from this file, which it then uses. @@ -411,6 +412,9 @@ start(){ # actual status with those echo ${mod_command_line} > /tmp/mod_command_line echo ${parameters} > /tmp/parameters + # Add the steam port from the environment + cp -a "${SERVER_CFG_SAVE}" "${SERVER_CFG_DST}" + sed -e "s,^steamQueryPort.*,steamQueryPort = ${STEAM_PORT};," -i "${SERVER_CFG_DST}" ./DayZServer "${mod_command_line}" ${parameters} EXIT_CODE=$? printf "\n[ ${yellow}DayZ${default} ] Server exited. Exit code: ${EXIT_CODE}\n" @@ -446,20 +450,20 @@ force(){ # Handle any changes in the server config file by allowing them to be merged after viewing a diff. config(){ - if ! diff -q "${SERVER_CFG_DST}" "${SERVER_CFG_SRC}" + if ! diff -q "${SERVER_CFG_SAVE}" "${SERVER_CFG_SRC}" then echo "=========================================================================" - diff -Nau --color "${SERVER_CFG_DST}" "${SERVER_CFG_SRC}" | more + diff -Nau --color "${SERVER_CFG_SAVE}" "${SERVER_CFG_SRC}" | more echo "=========================================================================" if prompt_yn "The new server configuration file differs from what's installed. Use it?" then echo "Updating the server configuration file" - cp "${SERVER_CFG_SRC}" "${SERVER_CFG_DST}" + cp "${SERVER_CFG_SRC}" "${SERVER_CFG_SAVE}" else echo "NOT updating the server configuration file" fi else - echo "No differences found between ${SERVER_CFG_SRC} and ${SERVER_CFG_DST}" + echo "No differences found between ${SERVER_CFG_SRC} and ${SERVER_CFG_SAVE}" fi } @@ -540,9 +544,9 @@ activelist(){ get_map_name(){ MAP="none" # Map name - if [[ -f ${SERVER_CFG_DST} ]] + if [[ -f ${SERVER_CFG_SAVE} ]] then - MAP=$(grep -E "template=" ${SERVER_CFG_DST} | grep -vE "^//" | cut -d= -f2 | cut -d\; -f1 | tr -d '"') + MAP=$(grep -E "template=" ${SERVER_CFG_SAVE} | grep -vE "^//" | cut -d= -f2 | cut -d\; -f1 | tr -d '"') fi echo ${MAP} } From 50837d97da773fef0e7a8cea85a1038c24b5af71 Mon Sep 17 00:00:00 2001 From: Daniel Ceregatti Date: Thu, 30 May 2024 12:59:04 -0700 Subject: [PATCH 03/11] This should not have made its way here. Removing. --- files/mods/2981609048/cfggameplay.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/files/mods/2981609048/cfggameplay.json b/files/mods/2981609048/cfggameplay.json index 149a295..d56baed 100644 --- a/files/mods/2981609048/cfggameplay.json +++ b/files/mods/2981609048/cfggameplay.json @@ -2,8 +2,5 @@ "WorldsData":{ "environmentMinTemps": [-7.0, -5.0, -3.0, -2.0, 0.0, 2.0, 5.0, 10.0, 7.0, 5.0, 1.0, -2.0], "environmentMaxTemps": [-3.0, -1.0, 2.0, 5.0, 7.0, 10.0, 12.0, 16.0, 13.0, 10.0, 7.0, 2.0] - }, - "PlayerData": { - "disablePersonalLight": true } } From 563b17b01854d66e9f5d5cee8eb0ad6ec15eabc7 Mon Sep 17 00:00:00 2001 From: Daniel Ceregatti Date: Thu, 30 May 2024 14:51:28 -0700 Subject: [PATCH 04/11] Update docs. --- files/custom/README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/files/custom/README.md b/files/custom/README.md index 8c5b3c8..df56471 100644 --- a/files/custom/README.md +++ b/files/custom/README.md @@ -106,6 +106,17 @@ cp -a /files/custom/starting-gear /profiles/custom/ Restart the server. +### No personal light + +The personal light is usually configured using the `disablePersonalLight` setting in [serverDZ.cfg](../serverDZ.cfg), but if a cfggameplay.json file is present, which is the default being employed for this project, that setting must be overridden there. To configure the personal light: + +```shell +mkdir -p /profiles/custom +cp -a /files/custom/no-personal-light /profiles/custom +``` + +Restart the server. + ### References [BI DayZ Wiki - Spawning Gear Configuration](https://community.bistudio.com/wiki/DayZ:Spawning_Gear_Configuration) From 958c9711fef4064549281be4b8e287ab8144ecdf Mon Sep 17 00:00:00 2001 From: Daniel Ceregatti Date: Wed, 19 Jun 2024 17:12:24 -0700 Subject: [PATCH 05/11] See if we get fewer commit warnings. --- files/bin/dz-common | 54 ++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/files/bin/dz-common b/files/bin/dz-common index 1711603..1ee2083 100755 --- a/files/bin/dz-common +++ b/files/bin/dz-common @@ -6,48 +6,48 @@ set -eEa # The steam query port is set in serverDZ.cfg. # Server port. Set these in the .env file for the container. -port=${SERVER_PORT} -rcon_port=${RCON_PORT} +export port=${SERVER_PORT} +export rcon_port=${RCON_PORT} # Don't change anything else. # Colors -default="\e[0m" -red="\e[31m" -green="\e[32m" -yellow="\e[93m" -lightblue="\e[94m" -blue="\e[34m" -magenta="\e[35m" -cyan="\e[36m" +export default="\e[0m" +export red="\e[31m" +export green="\e[32m" +export yellow="\e[93m" +export lightblue="\e[94m" +export blue="\e[34m" +export magenta="\e[35m" +export cyan="\e[36m" # DayZ release server Steam app ID. # Now that the Linux server is released, the binaries will come from this ID. -release_server_appid=223350 +export release_server_appid=223350 # Leaving the experimental server appid here to allow for the use of the experimental server. -#release_server_appid=1042420 +#export release_server_appid=1042420 # DayZ release client SteamID. This is for mods, as only the release client has them. -release_client_appid=221100 +export release_client_appid=221100 # Server container profile directory -SERVER_PROFILE="/profiles" +export SERVER_PROFILE="/profiles" # Common container base directories -FILES="/files" -SERVER_FILES="/serverfiles" +export FILES="/files" +export SERVER_FILES="/serverfiles" # Used to check if dayZ is installed -SERVER_INSTALL_FILE="${SERVER_FILES}/DayZServer" +export SERVER_INSTALL_FILE="${SERVER_FILES}/DayZServer" # Steam files -STEAM_LOGIN="${HOME}/steamlogin" -STEAMCMD=steamcmd +export STEAM_LOGIN="${HOME}/steamlogin" +export STEAMCMD=steamcmd # Other stuff -YES="${green}yes${default}" -NO="${red}no${default}" +export YES="${green}yes${default}" +export NO="${red}no${default}" # Convenience function prompt_yn(){ @@ -95,7 +95,7 @@ get_mod_name(){ echo "Mod ID ${1} doesn't exist" >&2 exit 1 fi - NAME=$(grep name ${WORKSHOP_DIR}/${1}/meta.cpp | cut -d '"' -f2 | tr -cd [:alnum:]) + NAME=$(grep name "${WORKSHOP_DIR}/${1}/meta.cpp" | cut -d '"' -f2 | tr -cd "[:alnum:]") if [[ ${NAME} = "" ]] then echo "Could not get metadata. See above. Exiting..." @@ -113,19 +113,17 @@ get_mod_id(){ fi # If we have a second argument, we want to iterate over active server mods DIR=${SERVER_FILES} - ARG="-d" if [[ ${2} = "0" ]] then - ARG="-tdr" DIR=${SERVER_PROFILE} fi # echo "DIR: ${DIR}, ARG: ${ARG}" >&2 X=1 # Loop over mods - for link in $(ls ${ARG} ${DIR}/@* 2> /dev/null) + for link in "${DIR}"/@* do ID=$(readlink ${link} | awk -F/ '{print $NF}') - if [[ ${X} = ${1} ]] + if [[ "${X}" = "${1}" ]] then echo -n ${ID} return @@ -140,14 +138,14 @@ get_mods(){ do ID=$(readlink ${link} | awk -F/ '{print $NF}') MODNAME=$(get_mod_name ${ID}) - workshoplist+=" +workshop_download_item "${release_client_appid}" "${ID} + workshoplist+=" +workshop_download_item ${release_client_appid} ${ID}" done get_mod_command_line } get_mod_command_line(){ mod_command_line="" - for link in $(ls -tdr ${SERVER_PROFILE}/@* 2> /dev/null) + for link in "${SERVER_PROFILE}"/@* do ID=$(readlink ${link} | awk -F/ '{print $NF}') MODNAME=$(get_mod_name ${ID}) From 1a9c05a1901437637abcb60146bb0ab8883053cc Mon Sep 17 00:00:00 2001 From: Daniel Ceregatti Date: Thu, 20 Jun 2024 09:45:44 -0700 Subject: [PATCH 06/11] Oops, didn't mean to commit these two changes. Reverting. --- files/bin/dz-common | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/files/bin/dz-common b/files/bin/dz-common index 1ee2083..ba08f99 100755 --- a/files/bin/dz-common +++ b/files/bin/dz-common @@ -113,14 +113,16 @@ get_mod_id(){ fi # If we have a second argument, we want to iterate over active server mods DIR=${SERVER_FILES} + ARG="-d" if [[ ${2} = "0" ]] then + ARG="-tdr" DIR=${SERVER_PROFILE} fi # echo "DIR: ${DIR}, ARG: ${ARG}" >&2 X=1 # Loop over mods - for link in "${DIR}"/@* + for link in $(ls ${ARG} ${DIR}/@* 2> /dev/null) do ID=$(readlink ${link} | awk -F/ '{print $NF}') if [[ "${X}" = "${1}" ]] @@ -145,7 +147,7 @@ get_mods(){ get_mod_command_line(){ mod_command_line="" - for link in "${SERVER_PROFILE}"/@* + for link in $(ls -tdr ${SERVER_PROFILE}/@* 2> /dev/null) do ID=$(readlink ${link} | awk -F/ '{print $NF}') MODNAME=$(get_mod_name ${ID}) From 7b70a07babc7f69453b82250f8276f175f99cfcc Mon Sep 17 00:00:00 2001 From: Daniel Ceregatti Date: Sat, 22 Jun 2024 10:26:15 -0700 Subject: [PATCH 07/11] Working config. --- files/mods/2289456201/map.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/mods/2289456201/map.env b/files/mods/2289456201/map.env index 5544bb0..0b0aebb 100644 --- a/files/mods/2289456201/map.env +++ b/files/mods/2289456201/map.env @@ -4,5 +4,5 @@ set -eE MAP="Namalsk" DIR="Namalsk-Server/Mission Files" -REPO="https://github.com/SumrakDZN/${DIR}/hardcore.namalsk" +REPO="https://github.com/SumrakDZN/Namalsk-Server.git" MPDIR="hardcore.namalsk" From daaee5decb36217e11b7996bdc1f29926725ee88 Mon Sep 17 00:00:00 2001 From: Daniel Ceregatti Date: Sat, 22 Jun 2024 13:20:08 -0700 Subject: [PATCH 08/11] Handle the server ID in PS1 in each server container. --- server/bin/start.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/bin/start.sh b/server/bin/start.sh index b3a60fd..e7d097c 100755 --- a/server/bin/start.sh +++ b/server/bin/start.sh @@ -3,7 +3,7 @@ # Set PS1 so we know we're in the container, should we exec into it. cat > .bashrc < Date: Sat, 22 Jun 2024 13:20:56 -0700 Subject: [PATCH 09/11] Update docs. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 29fa7c3..b43210f 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,9 @@ Repeat the above for server1, which uses .env1 (and so on): echo "export USER_ID=${UID}" | tee .env1 ``` -But each server must also set its own unique ports: +But each server must also set its own unique ports and id: ```shell +echo "export SERVER_ID=1" | tee -a .env1 echo "export SERVER_PORT=2302" | tee -a .env1 echo "export RCON_PORT=2303" | tee -a .env1 echo "export STEAM_PORT=27016" | tee -a .env1 @@ -51,6 +52,7 @@ echo "export STEAM_PORT=27016" | tee -a .env1 Repeat the above for each server you want to run, making sure the ports are unique across all servers: ```shell echo "export USER_ID=${UID}" | tee .env2 +echo "export SERVER_ID=2" | tee -a .env2 echo "export SERVER_PORT=2312" | tee -a .env2 echo "export RCON_PORT=2313" | tee -a .env2 echo "export STEAM_PORT=27116" | tee -a .env2 From 24f9ff2508b8f532eb8309bb4ade7b659190ea38 Mon Sep 17 00:00:00 2001 From: Daniel Ceregatti Date: Tue, 9 Jul 2024 09:10:41 -0700 Subject: [PATCH 10/11] Merge from main by hand. --- docker-compose.yml | 25 +++++++++++++++++++++++++ files/bin/dz-common | 10 ++++++++++ files/mods/enoch/map.env | 4 ++-- server/bin/dz | 29 +++++++++++++++-------------- web/bin/dz | 5 +++++ 5 files changed, 57 insertions(+), 16 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 9e05112..455c556 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,12 +13,15 @@ volumes: # For Steam, for now homedir_server1: homedir_server2: + homedir_server3: # Server mission files mpmissions1: mpmissions2: + mpmissions3: # Server profile files profiles1: profiles2: + profiles3: services: @@ -109,3 +112,25 @@ services: restart: no env_file: - .env2 # <-- here + + server3: # <-- here + build: + context: server + args: + - USER_ID + user: ${USER_ID} + volumes: + # Common volumes + - ./files:/files + - mods:/mods + - ./server:/server + - serverfiles:/serverfiles + - servermpmissions:/mpmissions:ro + # Server-specific volumes + - homedir_server3:/home/user # <-- here + - mpmissions3:/serverfiles/mpmissions # <-- here + - profiles3:/profiles # <-- here + network_mode: host + restart: no + env_file: + - .env3 # <-- here diff --git a/files/bin/dz-common b/files/bin/dz-common index 1fd973b..2929578 100755 --- a/files/bin/dz-common +++ b/files/bin/dz-common @@ -6,6 +6,16 @@ set -eEa # The steam query port is set in serverDZ.cfg. # Server port. Set these in the .env file for the container. +if [[ ${SERVER_PORT} = "" ]] +then + export SERVER_PORT=2302 +fi + +if [[ ${RCON_PORT} = "" ]] +then + export RCON_PORT=2303 +fi + export port=${SERVER_PORT} export rcon_port=${RCON_PORT} diff --git a/files/mods/enoch/map.env b/files/mods/enoch/map.env index 7c2a888..1fc8223 100644 --- a/files/mods/enoch/map.env +++ b/files/mods/enoch/map.env @@ -1,6 +1,6 @@ #!/usr/bin/env bash -MAP="Enoch" +MAP="Default Maps" DIR="DayZ-Central-Economy" REPO="https://github.com/BohemiaInteractive/${DIR}.git" -MPDIR="dayzOffline.enoch" +MPDIR="dayzOffline.*" diff --git a/server/bin/dz b/server/bin/dz index 98f8349..d17e0ea 100755 --- a/server/bin/dz +++ b/server/bin/dz @@ -5,7 +5,7 @@ source dz-common # Server container base directories MPMISSIONS="${SERVER_FILES}/mpmissions" -mkdir -p ${SERVER_PROFILE}/battleye +mkdir -p "${SERVER_PROFILE}"/battleye # Server configuration file SERVER_CFG_FILE="serverDZ.cfg" @@ -138,15 +138,18 @@ mergexml(){ # Copy the pristine files from upstream echo -e "${green}Copying upstream files into local mpmissions for map ${MAP}${default}": - find /mpmissions/${MAP} \( \ - -name "cfgeconomycore.xml" \ - -o -name "cfgenvironment.xml" \ - -o -name "cfgeventgroups.xml" \ - -o -name "cfgeventspawns.xml" \ - -o -name "cfggameplay.json" \ - -o -name "cfgweather.xml" \ - -o -name "init.c" \ - \) -exec cp -v {} ${SERVER_FILES}{} \; + # Not all maps have all files, so we need to check for their existence before copying them + for i in "cfgeconomycore.xml" "cfgenvironment.xml" "cfgeventgroups.xml" "cfgeventspawns.xml" "cfggameplay.json" "cfgweather.xml" "init.c" + do + if [ -f /mpmissions/${MAP}/${i} ] + then + cp -v /mpmissions/${MAP}/${i} ${MPMISSIONS}/${MAP}/${i} + else + # Copy it from the Chernarus map + echo "The map ${MAP} does not have a ${i} file, copying from Chernarus..." + cp -v /mpmissions/dayzOffline.chernarusplus/${i} ${MPMISSIONS}/${MAP}/${i} + fi + done # Same for any files in the db subdirectory we may modify find /mpmissions/${MAP}/db \( \ @@ -378,10 +381,8 @@ start(){ echo "Caught SIGTERM/SIGINT..." exit 0 ' SIGTERM SIGINT - while [ true ] - do - sleep 1 - done + tail -f /dev/null & + wait $! exit 0 fi # Clean up from previous runs diff --git a/web/bin/dz b/web/bin/dz index 047ac3d..de66a8b 100755 --- a/web/bin/dz +++ b/web/bin/dz @@ -122,6 +122,7 @@ add(){ symlink 1 ${1} "${MODNAME}" echo -e "Mod id ${1} - ${green}${MODNAME}${default} - added" xml ${ID} + map ${ID} } # Remove a mod @@ -190,6 +191,10 @@ install(){ printf "[ ${yellow}DayZ${default} ] Downloading DayZ Server-Files!\n" dologin ${STEAMCMD} +force_install_dir ${SERVER_FILES} +login "${steamlogin}" +app_update "${release_server_appid}" validate +quit + # This installs the mpmissions for charnarusplus and enoch (AKA Livonia) from github. The game once allowed the full server + # to be downloaded, but now you get the server without any mpmissions. This is a workaround. + echo "Installing mpmissions for ChernarusPlus and Livonia from github..." + map default else printf "[ ${lightblue}DayZ${default} ] The server is already installed.\n" fi From 8a87edf798b475ec6f71e6e7404eab77f7b8adb3 Mon Sep 17 00:00:00 2001 From: Daniel Ceregatti Date: Fri, 26 Jul 2024 21:44:21 -0700 Subject: [PATCH 11/11] Refactor docker compose build so a single server image is built for however many servers. Add horse mod, despite it being known to crash the Linux server. One day... Fix bashrc getting appended to instead of written to. Oops! --- docker-compose.yml | 104 ++++---- files/mods/3295021220/cfgenvironment.xml | 9 + files/mods/3295021220/cfgeventspawns.xml | 4 + files/mods/3295021220/events.xml | 24 ++ files/mods/3295021220/horses_chernarus.xml | 270 +++++++++++++++++++++ files/mods/3295021220/start.sh | 6 + files/mods/3295021220/xml.env | 3 + files/mods/@DayZHorse | 1 + web/Dockerfile | 151 ++++++++---- web/bin/start.sh | 2 +- 10 files changed, 482 insertions(+), 92 deletions(-) create mode 100755 files/mods/3295021220/cfgenvironment.xml create mode 100755 files/mods/3295021220/cfgeventspawns.xml create mode 100755 files/mods/3295021220/events.xml create mode 100755 files/mods/3295021220/horses_chernarus.xml create mode 100644 files/mods/3295021220/start.sh create mode 100644 files/mods/3295021220/xml.env create mode 120000 files/mods/@DayZHorse diff --git a/docker-compose.yml b/docker-compose.yml index 455c556..5602f90 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,6 +26,8 @@ volumes: services: web: + profiles: + - main build: context: web args: @@ -46,11 +48,23 @@ services: env_file: - .env - server1: + server-image: + &server-image + profiles: + - build build: context: server args: - USER_ID + image: server-image + pull_policy: never + env_file: + - .env + + server1: + <<: *server-image + profiles: + - main user: ${USER_ID} volumes: # Common volumes @@ -90,47 +104,47 @@ services: env_file: - .env1 - # Copy and paste this for every other server you want to run, replacing 2 with 3, and so on. - server2: # <-- here - build: - context: server - args: - - USER_ID - user: ${USER_ID} - volumes: - # Common volumes - - ./files:/files - - mods:/mods - - ./server:/server - - serverfiles:/serverfiles - - servermpmissions:/mpmissions:ro - # Server-specific volumes - - homedir_server2:/home/user # <-- here - - mpmissions2:/serverfiles/mpmissions # <-- here - - profiles2:/profiles # <-- here - network_mode: host - restart: no - env_file: - - .env2 # <-- here - - server3: # <-- here - build: - context: server - args: - - USER_ID - user: ${USER_ID} - volumes: - # Common volumes - - ./files:/files - - mods:/mods - - ./server:/server - - serverfiles:/serverfiles - - servermpmissions:/mpmissions:ro - # Server-specific volumes - - homedir_server3:/home/user # <-- here - - mpmissions3:/serverfiles/mpmissions # <-- here - - profiles3:/profiles # <-- here - network_mode: host - restart: no - env_file: - - .env3 # <-- here +# # Copy and paste this for every other server you want to run, replacing 2 with 3, and so on. +# server2: # <-- here +# build: +# context: server +# args: +# - USER_ID +# user: ${USER_ID} +# volumes: +# # Common volumes +# - ./files:/files +# - mods:/mods +# - ./server:/server +# - serverfiles:/serverfiles +# - servermpmissions:/mpmissions:ro +# # Server-specific volumes +# - homedir_server2:/home/user # <-- here +# - mpmissions2:/serverfiles/mpmissions # <-- here +# - profiles2:/profiles # <-- here +# network_mode: host +# restart: no +# env_file: +# - .env2 # <-- here +# +# server3: # <-- here +# build: +# context: server +# args: +# - USER_ID +# user: ${USER_ID} +# volumes: +# # Common volumes +# - ./files:/files +# - mods:/mods +# - ./server:/server +# - serverfiles:/serverfiles +# - servermpmissions:/mpmissions:ro +# # Server-specific volumes +# - homedir_server3:/home/user # <-- here +# - mpmissions3:/serverfiles/mpmissions # <-- here +# - profiles3:/profiles # <-- here +# network_mode: host +# restart: no +# env_file: +# - .env3 # <-- here diff --git a/files/mods/3295021220/cfgenvironment.xml b/files/mods/3295021220/cfgenvironment.xml new file mode 100755 index 0000000..aa1eeb4 --- /dev/null +++ b/files/mods/3295021220/cfgenvironment.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/files/mods/3295021220/cfgeventspawns.xml b/files/mods/3295021220/cfgeventspawns.xml new file mode 100755 index 0000000..e8f22d7 --- /dev/null +++ b/files/mods/3295021220/cfgeventspawns.xml @@ -0,0 +1,4 @@ + + + + diff --git a/files/mods/3295021220/events.xml b/files/mods/3295021220/events.xml new file mode 100755 index 0000000..0937dce --- /dev/null +++ b/files/mods/3295021220/events.xml @@ -0,0 +1,24 @@ + + + + 8 + 1 + 4 + 180 + 0 + 200 + 0 + 0 + + fixed + child + 1 + + + + + + + + + diff --git a/files/mods/3295021220/horses_chernarus.xml b/files/mods/3295021220/horses_chernarus.xml new file mode 100755 index 0000000..c04fea5 --- /dev/null +++ b/files/mods/3295021220/horses_chernarus.xml @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/mods/3295021220/start.sh b/files/mods/3295021220/start.sh new file mode 100644 index 0000000..8123c60 --- /dev/null +++ b/files/mods/3295021220/start.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +# This is run in the directory with the target files + +# Copy the territory file over +cp ${FILES}/mods/${ID}/horses_chernarus.xml env/wild_horse_territories.xml diff --git a/files/mods/3295021220/xml.env b/files/mods/3295021220/xml.env new file mode 100644 index 0000000..3487169 --- /dev/null +++ b/files/mods/3295021220/xml.env @@ -0,0 +1,3 @@ +CFGENVIRONMENT=local +CFGEVENTSPAWNS=local +EVENTS=local diff --git a/files/mods/@DayZHorse b/files/mods/@DayZHorse new file mode 120000 index 0000000..f5c8cc0 --- /dev/null +++ b/files/mods/@DayZHorse @@ -0,0 +1 @@ +3295021220 \ No newline at end of file diff --git a/web/Dockerfile b/web/Dockerfile index f9574e8..636b15d 100644 --- a/web/Dockerfile +++ b/web/Dockerfile @@ -1,48 +1,39 @@ -FROM debian:bookworm-slim +FROM debian:bookworm-slim AS download -# 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 \ - && echo steam steam/question select "I AGREE" | debconf-set-selections \ - && echo steam steam/license note '' | debconf-set-selections \ - && dpkg --add-architecture i386 - -# 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 +# Install _only_ the necessary packages to download the .net SDK and Steamworks .net SDK RUN apt-get update && apt-get -y upgrade && apt-get -y install --no-install-recommends \ - binutils \ - curl \ - git \ - gwenhywfar-tools \ - jq \ - libxml2-utils \ - locales \ - nano \ - procps \ + ca-certificates \ wget \ - rename \ - steamcmd \ - xmlstarlet + unzip -# Set the locale -RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen -ENV LANG en_US.UTF-8 -ENV LANGUAGE en_US:en -ENV LC_ALL en_US.UTF-8 +# Download dotnet SDK to build the steam API client +RUN cd /tmp && \ + wget -q https://dotnetcli.azureedge.net/dotnet/Sdk/8.0.303/dotnet-sdk-8.0.303-linux-x64.tar.gz -# Steamcmd needs its path added, as it ends up in /usr/games. -# Our server script is bind mounted in /files in docker-compose. -ENV PATH /usr/games:/files/bin:/web/bin:${PATH} +# Download the Steamworks .net package +RUN cd /tmp && \ + wget -q https://github.com/rlabrecque/Steamworks.NET/releases/download/20.2.0/Steamworks.NET-Standalone_20.2.0.zip + +# Extract the dotnet SDK +RUN cd /usr/local && \ + mkdir -p dotnet && \ + cd dotnet && \ + tar xfz /tmp/dotnet-sdk-8.0.303-linux-x64.tar.gz + +# Extract the Steamworks .net SDK +RUN mkdir -p /usr/local/steamworks.net && \ + cd /usr/local/steamworks.net && \ + unzip /tmp/Steamworks.NET-Standalone_20.2.0.zip + +# Add bercon https://github.com/WoozyMasta/bercon +RUN wget -q https://github.com/WoozyMasta/bercon/releases/download/1.0.0/bercon \ + && chmod +x bercon \ + && mv bercon /usr/bin # Install nodejs RUN mkdir /usr/local/nvm ENV NVM_DIR /usr/local/nvm -ENV NODE_VERSION 20.12.2 -RUN echo $NODE_VERSION +ENV NODE_VERSION 20.15.1 # Install nvm with node and npm RUN wget -O - https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash \ @@ -51,8 +42,84 @@ RUN wget -O - https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | && nvm alias default $NODE_VERSION \ && nvm use default -ENV NODE_PATH $NVM_DIR/versions/node/v$NODE_VERSION/lib/node_modules -ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH +FROM debian:bookworm-slim AS build + +COPY --from=download /usr/local/dotnet /usr/local/dotnet + +RUN apt-get update && apt-get -y upgrade && apt-get -y install --no-install-recommends \ + libicu72 \ + libssl3 + +# Disable MS telemetry +ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 + +# Build the steam API client +COPY client /usr/local/client + +#RUN cd /usr/local/client && \ +# /usr/local/dotnet/dotnet build -c Release + +FROM debian:bookworm-slim + +COPY --from=download /usr/local/dotnet /usr/local/dotnet + +COPY --from=download /usr/local/steamworks.net /usr/local/steamworks.net + +COPY --from=download /usr/bin/bercon /usr/bin/bercon + +COPY --from=download /usr/local/nvm /usr/local/nvm + +COPY --from=build /usr/local/client/ /usr/local/client + +ENV DOTNET_ROOT /usr/local/dotnet + +# Add backports, contrib, and non-free +RUN sed -i /etc/apt/sources.list.d/debian.sources -e 's/Components: main/Components: main contrib non-free/g' + +# Set debconf to run non-interactively and agree to the SteamCMD EULA +RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections \ + && echo steam steam/question select "I AGREE" | debconf-set-selections \ + && echo steam steam/license note '' | debconf-set-selections \ + && dpkg --add-architecture i386 + +# Install _only_ the necessary packages +RUN apt-get update && apt-get -y upgrade && apt-get -y install --no-install-recommends \ + binutils \ + curl \ + git \ + gwenhywfar-tools \ + jq \ + libicu72 \ + libssl3 \ + libxml2-utils \ + locales \ + nano \ + procps \ + wget \ + rename \ + steamcmd \ + xmlstarlet \ + unzip + +# Set the locale +RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen +ENV LANG=en_US.UTF-8 +ENV LANGUAGE=en_US:en +ENV LC_ALL=en_US.UTF-8 + +# This was installed in the download stage +ENV NVM_DIR /usr/local/nvm +ENV NODE_VERSION=20.15.1 + +ENV NODE_PATH=$NVM_DIR/versions/node/v$NODE_VERSION/lib/node_modules +ENV PATH=$NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH + +# Steamcmd needs its path added, as it ends up in /usr/games. +# Our server script is bind mounted in /files in docker-compose. +ENV PATH=/usr/games:/files/bin:/web/bin:${PATH} + +# Shut steamcmd up +RUN cd /usr/lib/i386-linux-gnu && ln -s /web/bin/steamservice.so # Setup a non-privileged user ARG USER_ID @@ -62,14 +129,6 @@ RUN groupadd -g ${USER_ID} user && \ mkdir -p /home/user /serverfiles/mpmissions /serverfiles/steamapps/workshop/content /web && \ chown -R user:user /home/user /serverfiles /web -# 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 diff --git a/web/bin/start.sh b/web/bin/start.sh index 2e2e230..a5d6ade 100755 --- a/web/bin/start.sh +++ b/web/bin/start.sh @@ -4,7 +4,7 @@ if ! echo .bashrc | grep -q "dz-web" then echo "Adding PS1 to .bashrc..." - cat >> .bashrc < .bashrc <