Create a dedicated means by which we can run interactive prompts to effect tasks such as (all WIP):

Logging into to Steam, accounting for Steam Guard. These credentials persist throughout the lifetime of the docker volume storing the data.
  Adding/removing/managing workshop items. The goal is to also manage the "=mod=" parameter.
  Listing the auto-generated RCON password.
  Backing up.
Further refine the original dayzserver script. In docker, a lot of the other stuff wasn't necessary so a lot is just being removed.
Install steamcmd into the container in Dockerfile and adjust paths.
Vastly updated docs!
This commit is contained in:
Daniel Ceregatti 2022-03-26 13:02:54 -07:00
parent e7ba76acf7
commit d87c5fad0e
6 changed files with 138 additions and 96 deletions

View file

@ -33,6 +33,13 @@ ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
# Add steamcmd to the image
RUN mkdir -p /steamcmd && \
curl -sqL "https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz" | tar zxf - -C steamcmd
# Make our docker scripts easier to run
ENV PATH /files:/steamcmd:${PATH}
# Setup a non-privileged user
RUN groupadd user && \
useradd -l -m -g user user
@ -47,4 +54,4 @@ USER user
WORKDIR /home/user
# Run the server.
CMD ["/files/dayzserver", "start"]
CMD ["dayzserver", "start"]

View file

@ -1,25 +1,33 @@
# DayZDockerServer
A Linux DayZ server in a Docker container. Uses a modified version of https://github.com/thelastnoc/dayz-sa_linuxserver
for all the Steam management. More info here https://steamcommunity.com/sharedfiles/filedetails/?id=1517338673.
### Caveat Emptor
Uses a docker volume for the unprivileged user's home directory, which stores the DayZ server files plus SteamCMD, a
utility used to manage Steam content from the command line. This volume can get quite large. Out of the box, as of this
writing, DayZ Experimental is at 1.17 and the volume comes to about 1.8G of disk space once all the files are downloaded.
A Linux DayZ server in a Docker container.
The main script's functionality is derived from [this project](https://github.com/thelastnoc/dayz-sa_linuxserver).
That functionality is described [here](https://steamcommunity.com/sharedfiles/filedetails/?id=1517338673). The goal is
to reproduce all that functionality and add even more while keeping it all in Docker.
### Setup, Build. and Configure
## Caveat Emptor
Edit `files/serverDZ.cfg` and set the server name (You don't really have to, but you should):
As of DayZ release 1.15, a [Linux DayZ server](https://steamdb.info/app/1042420/) was made available in Dayz
Experimental. This has not been officially released, so this will only run a DayZ Experimental server at the
moment. Only the [DayZ Experimental client](https://dayz.fandom.com/wiki/Experimental) will be able to connect to it.
This process will create a docker volume for the unprivileged user's home directory, which stores the DayZ server files.
This volume can get quite large. It will require at least 2G of disk space for the default install. Much more with mods.
## Setup, Build. and Configure
Edit `files/serverDZ.cfg` and set the values of any variables there.
See the [documentation](https://forums.dayz.com/topic/239635-dayz-server-files-documentation/):
```
hostname = "Something other than Server Name"; // Server name
```
Optionally edit `files/beserver_x64.cfg` and set the rcon password:
Optionally edit `files/beserver_x64.cfg` and set the RCON password:
```
RConPassword h4CKm3
```
If the above step is not performed, a random rcon password will be generated and output on the first run. It can also be
obtained later and reset.
If the above step is not performed, a random RCON password will be generated and output on the first run. It can also be
obtained and reset. (See [Management](#manage))
Add your Steam credentials. This step is necessary if you want to add mods. The vanilla server is installable by setting
the steamlogin to `anonymous`. Edit `files/steamlogin` and set the steam username.
@ -35,23 +43,32 @@ docker-compose build
```
Now login:
```
docker-compose run --rm config
docker-compose run --rm run manage login
```
### Run
## Run
Launch the container into the background:
```
docker-compose up -d dayzserver
docker-compose up -d run
```
Tail the log:
```
docker-compose logs -f dayzserver
docker-compose logs -f run
```
## Manage
### Workshop
To add a workshop item, edit `files/workshop.cfg` and add the item's id after the comment. Each id should be on its own
line, after the comment, which should not be removed. Install them:
```
docker-compose run --rm manage
```
### Workshop (TODO)
* Update/Add/Remove workshop files
* Makage -mod= command line
### Maintenance (TODO)
## TODO
* Update the server
* Restart the server
* Rcon to the server?
* RCON to the server?
* List current rocn password
* Detect changes to config files and propagate them
* Detect changes to config files and propagate them, with prompting.

View file

@ -5,14 +5,7 @@ volumes:
services:
config:
build: .
command: /files/login.sh
volumes:
- homedir:/home/user
- ./files:/files
dayzserver:
run:
build: .
ports:
- "2302:2302/udp"

View file

@ -3,81 +3,81 @@
appid=1042420
dayz_id=221100
if [ "${ansi}" != "off" ]; then
# echo colors
default="\e[0m"
red="\e[31m"
green="\e[32m"
yellow="\e[33m"
lightyellow="\e[93m"
blue="\e[34m"
lightblue="\e[94m"
magenta="\e[35m"
cyan="\e[36m"
# carriage return & erase to end of line
creeol="\r\033[K"
fi
default="\e[0m"
red="\e[31m"
green="\e[32m"
yellow="\e[33m"
lightyellow="\e[93m"
blue="\e[34m"
lightblue="\e[94m"
magenta="\e[35m"
cyan="\e[36m"
STEAMCMD=/steamcmd/steamcmd.sh
fn_loadconfig_dayz(){
source /files/default.cfg
# Handle adding the server cfg file
if [ ! -f ${HOME}/serverfiles/serverDZ.cfg ]
then
echo "Creating initial serverDZ.cfg"
cp /files/serverDZ.cfg "${HOME}/serverfiles/serverDZ.cfg"
elif diff -q /files/default.cfg "${HOME}/serverfiles/serverDZ.cfg" > /dev/null
then
echo "Updating serverDZ.cfg"
cp /files/serverDZ.cfg "${HOME}/serverfiles/serverDZ.cfg"
fi
}
fn_create_beconfig(){
# Set a random RCON password, unless one's set in the environment
if [ -d "${HOME}/serverfiles/battleye" ] && [ ! -f "${HOME}/serverfiles/battleye/beserver_x64.cfg" ]
then
echo -n "Creating Battle Eye RCON file "
cp /files/beserver_x64.cfg "${HOME}/serverfiles/battleye/beserver_x64.cfg"
if grep RCON_PASSWORD /files/beserver_x64.cfg
then
RCON_PASSWORD=$(< /dev/urandom tr -dc 'A-Za-z0-9' | head -c10)
echo -e "using random RCON password ${yellow}${RCON_PASSWORD}"
sed -i "${HOME}/serverfiles/battleye/beserver_x64.cfg" -e "s/RCON_PASSWORD/${RCON_PASSWORD}/"
else
echo "using the RCON_PASSWORD already set in files/beserver_x64.cfg."
fi
fn_do_rcon
elif diff -q /files/beserver_x64.cfg "${HOME}/serverfiles/battleye/beserver_x64.cfg" > /dev/null
then
echo -n "Updating Battle Eye RCON file "
fn_do_rcon
fi
}
fn_do_rcon(){
cp /files/beserver_x64.cfg "${HOME}/serverfiles/battleye/beserver_x64.cfg"
# Set a random RCON password, unless one's set in the environment
if grep -v RCON_PASSWORD /files/beserver_x64.cfg
then
RCON_PASSWORD=$(< /dev/urandom tr -dc 'A-Za-z0-9' | head -c10)
echo -e "using random RCON password ${yellow}${RCON_PASSWORD}"
sed -i "${HOME}/serverfiles/battleye/beserver_x64.cfg" -e "s/RCON_PASSWORD/${RCON_PASSWORD}/"
else
echo "using the RCON_PASSWORD already set in files/beserver_x64.cfg."
fi
}
fn_start_dayz(){
fn_loadconfig_dayz
fn_workshop_mods
printf "[ ${green}DayZ${default} ] Starting server...\n"
cd ${HOME}/serverfiles
./DayZServer $dayzparameter "$workshop" || (
echo
echo -e "${yellow}========================================== error.log =========================================="
find /home/user -name error.log -exec cat {} \; -exec rm -f {} \;
echo
echo -e "${yellow}========================================== script*.log ========================================"
find /home/user -name "script*.log" -exec cat {} \; -exec rm -f {} \;
echo
echo -e "${yellow}========================================== *.RPT =============================================="
find /home/user -name "*.RPT" -exec cat {} \; -exec rm -f {} \;
echo
echo -e "${yellow}========================================== End crash log ======================================"
)
printf "[ ${green}DayZ${default} ] Starting server...\n"
cd ${HOME}/serverfiles
./DayZServer $dayzparameter "$workshop" || (
echo
echo -e "${yellow}========================================== error.log =========================================="
find /home/user -name error.log -exec cat {} \; -exec rm -f {} \;
echo
echo -e "${yellow}========================================== script*.log ========================================"
find /home/user -name "script*.log" -exec cat {} \; -exec rm -f {} \;
echo
echo -e "${yellow}========================================== *.RPT =============================================="
find /home/user -name "*.RPT" -exec cat {} \; -exec rm -f {} \;
echo
echo -e "${yellow}========================================== End crash log ======================================"
)
}
fn_steamlogin_dayz(){
source /files/steamlogin
}
fn_install_steamcmd(){
if [ ! -f "${HOME}/steamcmd/steamcmd.sh" ]; then
mkdir ${HOME}/steamcmd &> /dev/null
curl -sqL "https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz" | tar zxf - -C steamcmd
printf "[ ${yellow}STEAM${default} ] Steamcmd installed\n"
else
printf "[ ${lightblue}STEAM${default} ] Steamcmd already installed\n"
fi
}
fn_install_dayz(){
if [ ! -f "${HOME}/serverfiles/DayZServer" ]; then
mkdir ${HOME}/serverfiles &> /dev/null
@ -92,7 +92,7 @@ fn_install_dayz(){
fn_runupdate_dayz(){
fn_loadconfig_dayz
${HOME}/steamcmd/steamcmd.sh +force_install_dir ${HOME}/serverfiles +login "${steamlogin}" +app_update "${appid}" +quit
${STEAMCMD} +force_install_dir ${HOME}/serverfiles +login "${steamlogin}" +app_update "${appid}" +quit
}
fn_update_dayz(){
@ -108,7 +108,7 @@ fn_update_dayz(){
sleep 1
fi
# check for new build
availablebuild=$(${HOME}/steamcmd/steamcmd.sh +login "${steamlogin}" +app_info_update 1 +app_info_print "${appid}" +app_info_print "${appid}" +quit | sed -n '/branch/,$p' | grep -m 1 buildid | tr -cd '[:digit:]')
availablebuild=$(${STEAMCMD} +login "${steamlogin}" +app_info_update 1 +app_info_print "${appid}" +app_info_print "${appid}" +quit | sed -n '/branch/,$p' | grep -m 1 buildid | tr -cd '[:digit:]')
if [ -z "${availablebuild}" ]; then
printf "\r[ ${red}FAIL${default} ] Checking for update: SteamCMD\n"
printf "\r[ ${red}FAIL${default} ] Checking for update: SteamCMD: Not returning version info\n"
@ -138,7 +138,7 @@ fn_update_dayz(){
fn_runvalidate_dayz(){
fn_loadconfig_dayz
${HOME}/steamcmd/steamcmd.sh +force_install_dir ${HOME}/serverfiles +login "${steamlogin}" +app_update "${appid}" validate +quit
${STEAMCMD} +force_install_dir ${HOME}/serverfiles +login "${steamlogin}" +app_update "${appid}" validate +quit
}
fn_workshop_mods(){
@ -163,7 +163,7 @@ fn_workshop_mods(){
fi
done
# download mods
${HOME}/steamcmd/steamcmd.sh +force_install_dir ${HOME}/serverfiles +login "${steamlogin}" ${workshoplist} +quit
${STEAMCMD} +force_install_dir ${HOME}/serverfiles +login "${steamlogin}" ${workshoplist} +quit
# link mods
for i in "${workshopID[@]}"
do

View file

@ -1,14 +0,0 @@
#!/usr/bin/env bash
if [ -f ${HOME}/.steamlogin ]
then
echo "The file .steamlogin already exists. Remove it first then run this again. (See README.md)"
exit 1
else
source /files/dayzserver
fn_install_steamcmd
echo "Setting up Steam credentials"
cp /files/steamlogin "${HOME}/.steamlogin"
source "${HOME}/.steamlogin"
${HOME}/steamcmd/steamcmd.sh +force_install_dir ${HOME}/serverfiles +login "${steamlogin}" +quit
fi

39
files/manage Executable file
View file

@ -0,0 +1,39 @@
#!/usr/bin/env bash
if [[ "${1}" = "login" ]]
then
if [ -f ${HOME}/.steamlogin ]
then
echo -n "The steam login is already set. Reset it? (Y|n): "
read -s -n 1 a
a=$(echo ${a} | tr A-Z a-z)
if [[ "${a}" = "y" ]]
then
rm -f ${HOME}/.steamlogin
else
echo "Not reset. Nothing to do. Exiting..."
exit 0
fi
fi
if [ ! -f ${HOME}/.steamlogin ]
then
echo "Setting up Steam credentials"
cp /files/steamlogin "${HOME}/.steamlogin"
source "${HOME}/.steamlogin"
steamcmd.sh +force_install_dir ${HOME}/serverfiles +login "${steamlogin}" +quit
fi
elif [[ "${1}" = "workshop" ]]
then
echo "Updating workshopp..."
elif [[ "${1}" = "backup" ]]
then
echo "Creating backup..."
elif [[ "${1}" = "rconpassword" ]]
then
echo "The RCON password is: ..."
else
echo "Unknown option '${1}'"
echo "Usage: manage backup | login | workshop | rconpassword"
exit 0
fi