Codex-Refined Automated DayZ
CrayZ is a Docker-based DayZ Dedicated Server setup for Unix-based operating systems running Docker, including normal Linux Docker hosts, OpenMediaVault/OMV, and Unraid/UnRAID-style NAS deployments.
Supported platform note: after this introduction, the documentation generally refers to these supported targets simply as a Docker host. The only OMV-specific exception is the documented support for named OMV Compose stack files such as crayz.yml and crayz.env.
It is designed to make running a DayZ server less painful by keeping the server files, SteamCMD state, profiles, logs, and configuration in predictable persistent folders.
CrayZ is currently focused on a reliable vanilla DayZ server setup first, with layered mod support added only after the base server install and login flow are proven stable.
CrayZ provides:
- A Docker image for running a DayZ Dedicated Server.
- Docker Compose files for local builds and GHCR-based deployment.
- Persistent server files under
data/server/. - Persistent DayZ profiles under
data/profiles/. - Persistent logs under
data/logs/. - Persistent Steam login/session state under
data/steam/. - Local DayZ mod loading from already-present folders under
data/mods/workshop/. - SteamCMD Workshop download/update for individually listed mod IDs during install/update mode.
- First-run creation of default config files when missing.
- PUID/PGID support for Docker bind mounts.
- Credentialed SteamCMD login for installing/updating the DayZ server.
CrayZ currently targets a reliable vanilla DayZ Dedicated Server baseline with local mod loading and individual Workshop mod download/update.
Implemented:
- GHCR/Docker Compose deployment layout.
- Local Docker build layout.
- SteamCMD-based DayZ server install/update.
- Persistent Steam login/session state.
- First-run config seeding.
- PUID/PGID permission support.
- Local mod folder loading from
config/mods.txt. - Individual Steam Workshop mod download/update from
config/mods.txt.
Not implemented yet:
- Workshop collection support.
- Automatic mod dependency resolution.
- RCON dashboard.
- Web UI.
- Hosting-panel style management.
You need:
- A Docker host.
- Docker Compose.
- A Steam account that can install the DayZ Dedicated Server through SteamCMD.
- A local
.envfile containing your private Steam login values.
Anonymous SteamCMD login is not supported at this point in time by DayZ so it is not possible with CrayZ.
Clone or copy this repository onto your Docker host, then enter the repo folder:
cd crayzCreate your private environment file:
cp .env.example .envEdit .env:
nano .envAt minimum, set:
STEAM_USERNAME=
STEAM_PASSWORD=
STEAM_GUARD_CODE=
DAYZ_ALLOW_STEAM_CREDENTIAL_LOGIN=1Fill STEAM_USERNAME and STEAM_PASSWORD only in your private .env.
For the first install/update, keep DAYZ_AUTO_UPDATE=1, then pull and start the image:
docker compose pull
docker compose upFor the first run, starting in the foreground is recommended so you can watch the SteamCMD login and install process.
After the first successful login and install, stop the container with Ctrl+C, set DAYZ_AUTO_UPDATE=0 in .env, and start normal runtime:
docker compose up -dCrayZ uses credentialed SteamCMD login.
For the first login:
- Set
STEAM_USERNAMEin.env. - Set
STEAM_PASSWORDin.env. - Leave
STEAM_GUARD_CODEempty unless Steam gives you a code. - Set
DAYZ_ALLOW_STEAM_CREDENTIAL_LOGIN=1. - Start the container.
- Approve the login in the Steam mobile app if Steam sends a mobile approval request.
- If Steam gives you a Steam Guard code, place that code in
STEAM_GUARD_CODEand rerun the container. - After login succeeds, clear
STEAM_GUARD_CODEfrom.env.
Steam login/session state is stored persistently under:
data/steam/Steam/
data/steam/dot-steam/
These folders map to /home/dayz/Steam and /home/dayz/.steam inside the container. Keeping both paths persistent helps SteamCMD reuse session state, but Steam Guard persistence is not guaranteed. Normal runtime should use DAYZ_AUTO_UPDATE=0 so restarts do not invoke SteamCMD.
Do not commit or share your .env file.
CrayZ separates install/update mode from normal runtime mode.
First install or manual server/Workshop update:
- Set
DAYZ_AUTO_UPDATE=1. - Start the container in the foreground.
- Approve Steam Guard if Steam asks.
- Wait for SteamCMD to finish successfully.
- Stop the container.
- Set
DAYZ_AUTO_UPDATE=0.
Normal runtime:
- Start or recreate the container with
DAYZ_AUTO_UPDATE=0. - Confirm logs show
Skipping SteamCMD update because DAYZ_AUTO_UPDATE is not 1. - Confirm logs show
Starting vanilla DayZ server on UDP port 2302.
Future manual server/Workshop update:
- Temporarily set
DAYZ_AUTO_UPDATE=1. - Run one update.
- Set
DAYZ_AUTO_UPDATE=0again before normal restarts.
If Steam Guard prompts repeat after a restart, stop the container. Do not keep approving repeated prompts. Verify the Steam state mounts and permissions before trying again.
Normal Docker Compose usage on a Docker host expects:
docker-compose.yml
.env
OMV's native Compose stack handling may store stacks with names such as:
crayz.yml
crayz.env
That layout works when Compose is told which env file to use:
docker compose -f crayz.yml --env-file crayz.env config
docker compose -f crayz.yml --env-file crayz.env upFor OMV native Compose usage, copy or paste the root docker-compose.yml contents into crayz.yml, then copy .env.example to crayz.env and edit only crayz.env with your local values.
The Compose files pass CrayZ runtime variables explicitly through environment:. This makes values from .env, crayz.env, or the shell visible inside the container. The optional env_file: .env entry is kept for the default filename/layout only; named OMV Compose files still need --env-file crayz.env.
On first startup, CrayZ creates missing folders and default config files.
Expected folder layout after first run:
crayz/
docker-compose.yml
.env
config/
serverDZ.cfg
mods.txt
data/
server/
profiles/
logs/
mods/
workshop/
steam/
Steam/
dot-steam/
If config/serverDZ.cfg does not exist, CrayZ creates a safe default vanilla server config.
If config/mods.txt does not exist, CrayZ creates a commented empty local mod list.
Existing config files are not overwritten.
CrayZ supports PUID and PGID so files created inside bind-mounted folders belong to the expected host user.
On the Docker host, run:
id yourusernameExample:
uid=1000(username) gid=1000(username) groups=1000(username),100(users)
Use those values in .env:
PUID=1000
PGID=1000Use the UID and GID of the Docker host user that should own and manage the CrayZ files.
At startup, CrayZ prepares the internal dayz user/group with those IDs, checks the mounted folders, and then drops privileges before running SteamCMD or the DayZ server.
Main configuration files:
.env
config/serverDZ.cfg
config/mods.txt
In the Compose files, some values are written like this:
PUID: "${PUID:-1000}"
PGID: "${PGID:-1000}"This means:
Use the value from `.env`, `--env-file`, or the shell when it exists.
If the value is missing or empty, use the fallback value after `:-`.
Example .env values:
PUID=1000
PGID=4With that .env, Docker Compose resolves the container environment as:
PUID: "1000"
PGID: "4"The fallback values in Compose are only used when the variable is not set in .env, the --env-file file, or the host environment.
Private runtime settings.
This file contains values such as:
PUID=1000
PGID=1000
STEAM_USERNAME=
STEAM_PASSWORD=
STEAM_GUARD_CODE=
DAYZ_ALLOW_STEAM_CREDENTIAL_LOGIN=1
DAYZ_SERVER_PORT=2302
DAYZ_STEAM_QUERY_PORT=27016
DAYZ_SERVER_CONFIG=serverDZ.cfg
DAYZ_STEAM_APP_ID=223350
DAYZ_WORKSHOP_APP_ID=221100
DAYZ_VALIDATE_INSTALL=1
DAYZ_AUTO_UPDATE=1
DAYZ_EXTRA_ARGS=CrayZ uses 0 for disabled and 1 for enabled on toggle-style settings.
| Variable | Default | Description |
|---|---|---|
PUID |
1000 |
Host user ID used inside the container. Files created in bind-mounted folders should be owned by this host user ID. Use id yourusername on the Docker host to find the correct value. |
PGID |
1000 |
Host group ID used inside the container. Files created in bind-mounted folders should belong to this host group ID. Use id yourusername on the Docker host to find the correct value. |
STEAM_USERNAME |
empty | Steam account username used by SteamCMD. Required when DAYZ_ALLOW_STEAM_CREDENTIAL_LOGIN=1. |
STEAM_PASSWORD |
empty | Steam account password used by SteamCMD. Required when DAYZ_ALLOW_STEAM_CREDENTIAL_LOGIN=1. Never commit this value. |
STEAM_GUARD_CODE |
empty | Optional Steam Guard verification code. Leave empty unless Steam gives you a code. If Steam asks for mobile approval instead, approve the login in the Steam mobile app and leave this empty. |
DAYZ_ALLOW_STEAM_CREDENTIAL_LOGIN |
1 |
SteamCMD credential-login toggle. See notes below for toggle values and testing guidance. |
DAYZ_SERVER_NAME |
CrayZ Test Server |
Friendly server name used by CrayZ defaults. The visible DayZ server name is normally controlled by config/serverDZ.cfg. |
DAYZ_SERVER_PORT |
2302 |
UDP game port exposed by Docker and passed to the DayZ server. |
DAYZ_STEAM_QUERY_PORT |
27016 |
UDP Steam query/server browser port exposed by Docker. serverDZ.cfg must also contain steamQueryPort = 27016;. |
DAYZ_SERVER_CONFIG |
serverDZ.cfg |
Config filename inside config/ that DayZ should use. Most users should leave this as serverDZ.cfg. |
DAYZ_STEAM_APP_ID |
223350 |
Steam app ID for the DayZ Dedicated Server. Most users should not change this. |
DAYZ_WORKSHOP_APP_ID |
221100 |
Steam Workshop app ID used when downloading DayZ Workshop items. This is separate from DAYZ_STEAM_APP_ID. |
DAYZ_VALIDATE_INSTALL |
1 |
Controls SteamCMD file validation during install/update. 1 validates server files and can repair missing or corrupted files. 0 skips validation and may be faster. |
DAYZ_AUTO_UPDATE |
1 |
Controls startup update behavior. 1 is install/update mode and runs SteamCMD once at container start. 0 is normal runtime mode and skips SteamCMD, then starts the existing installed server files. |
DAYZ_EXTRA_ARGS |
empty | Optional extra command-line arguments appended to the DayZ server launch command. Advanced users only. |
Recommended install/update settings:
DAYZ_ALLOW_STEAM_CREDENTIAL_LOGIN=1
DAYZ_VALIDATE_INSTALL=1
DAYZ_AUTO_UPDATE=1
DAYZ_EXTRA_ARGS=Recommended normal runtime settings after install/update succeeds:
DAYZ_AUTO_UPDATE=0Use DAYZ_AUTO_UPDATE=1 only when installing or intentionally updating server files. SteamCMD login persistence with Steam Guard is not guaranteed, so normal restarts should use DAYZ_AUTO_UPDATE=0.
DAYZ_ALLOW_STEAM_CREDENTIAL_LOGIN values:
0means disabled; CrayZ blocks credentialed SteamCMD login.1means enabled; CrayZ may useSTEAM_USERNAME,STEAM_PASSWORD, and optionalSTEAM_GUARD_CODE.
The default is 1. Set it to 0 only when intentionally testing config generation or startup behavior without allowing Steam login.
Never commit .env.
The authoritative DayZ server configuration file.
Inside the container, CrayZ starts DayZ with:
-config=/dayz/config/serverDZ.cfg
For normal repo-relative deployments, edit:
config/serverDZ.cfg
For deployments using the documented absolute Docker host layout, edit:
/DockerData/crayz/config/serverDZ.cfg
This controls settings such as:
- server name
- password
- admin password
- max players
- Steam query/server browser port
- mission template
- server time behavior
- signature verification
For server browser visibility, the config should include this top-level setting:
steamQueryPort = 27016;Fresh CrayZ-generated configs include it. Existing configs are not overwritten, so older config/serverDZ.cfg files may need this line added manually.
DayZ mission and Central Economy files are highly user-editable, but the location matters. SteamCMD validation treats the installed DayZ server files as managed game/server content. If you edit the default mission directly inside the Steam-managed server install and later run an update or validation pass, SteamCMD may restore those files to the official vanilla version.
The most common files affected are mission and economy files such as:
types.xml
cfgspawnabletypes.xml
events.xml
globals.xml
cfgeventspawns.xml
cfgrandompresets.xml
cfgplayerspawnpoints.xml
cfggameplay.json
cfgweather.xml
messages.xml
init.c
Recommended pattern: keep your edited mission as a custom mission, with a separate folder name, and treat that custom copy as your source of truth. Do not keep long-term custom economy work only in the default vanilla mission folder.
Typical default mission folder inside the installed server files:
/dayz/server/mpmissions/dayzOffline.chernarusplus/
Recommended custom source folder for CrayZ deployments using the documented absolute Docker host layout:
/DockerData/crayz/config/mpmissions/dayzOffline_crayz.chernarusplus/
The mission folder name should keep the real map suffix after the dot. For Chernarus, use a folder name ending in:
.chernarusplus
For example:
dayzOffline_crayz.chernarusplus
dayzOffline_myserver.chernarusplus
dayzOffline_survivalplus.chernarusplus
Then point config/serverDZ.cfg at the custom mission template:
class Missions
{
class DayZ
{
template = "dayzOffline_crayz.chernarusplus";
};
};The value of template must match the custom mission folder name. The part after the dot tells the DayZ engine which terrain/mission world is being loaded, so it must remain a valid DayZ terrain suffix such as chernarusplus.
A practical first-time setup on the Docker host:
mkdir -p /DockerData/crayz/config/mpmissions
cp -a /DockerData/crayz/data/server/mpmissions/dayzOffline.chernarusplus /DockerData/crayz/config/mpmissions/dayzOffline_crayz.chernarusplusDayZ normally loads missions from the server mpmissions directory. If your custom mission source lives under config/mpmissions, copy or sync it into the runtime mission location after server updates and before normal runtime:
mkdir -p /DockerData/crayz/data/server/mpmissions
rsync -a --delete /DockerData/crayz/config/mpmissions/dayzOffline_crayz.chernarusplus/ /DockerData/crayz/data/server/mpmissions/dayzOffline_crayz.chernarusplus/After changing serverDZ.cfg or mission files, restart the container.
Safe operating rule:
- Use
DAYZ_AUTO_UPDATE=1for intentional SteamCMD install/update/validate runs. - Keep your custom mission source under
config/mpmissions/. - After an update/validate run, re-sync the custom mission into
data/server/mpmissions/if needed. - Use
DAYZ_AUTO_UPDATE=0for normal runtime. - Back up custom mission files before heavy economy, loot, weather, or spawn tuning.
This avoids losing custom types.xml, BBP/MMG economy entries, weather settings, server messages, login/logout timers, and other mission edits during SteamCMD validation.
The human-editable mod list.
CrayZ keeps mod content persistently under:
/dayz/mods/workshop/<folder_name>
For deployments using the documented absolute Docker host layout, place local mod folders under:
/DockerData/crayz/data/mods/workshop/
The Compose files mount that host folder to /dayz/mods/workshop/ inside the container.
At startup, CrayZ creates DayZ-native server-root symlinks for enabled mods:
/dayz/server/<folder_name> -> /dayz/mods/workshop/<folder_name>
DayZ is then launched with relative server-root mod names:
-mod=@ModName;@OtherMod
-servermod=@ServerOnlyMod
CrayZ does not launch DayZ with absolute /dayz/mods/workshop/... mod paths.
Supported formats:
folder_name|load_type
workshop_id|folder_name|load_type
Blank lines and lines starting with # are ignored.
Local-only lines use folder_name|load_type. The folder must already exist under /dayz/mods/workshop/.
Workshop lines use workshop_id|folder_name|load_type. When DAYZ_AUTO_UPDATE=1, CrayZ downloads or updates the item with SteamCMD and syncs it into /dayz/mods/workshop/<folder_name>. When DAYZ_AUTO_UPDATE=0, SteamCMD is skipped and CrayZ only loads the already-present local folder.
workshop_id must be numeric. DAYZ_WORKSHOP_APP_ID=221100 is used for DayZ Workshop item downloads. DAYZ_STEAM_APP_ID=223350 remains the DayZ Dedicated Server app ID.
load_type values:
clientadds the folder name to the DayZ-mod=launch parameter.serveradds the folder name to the DayZ-servermod=launch parameter.
For client mods, CrayZ recursively searches the enabled mod folder for .bikey files, case-insensitively, and copies discovered keys into /dayz/server/keys/. This covers common and non-standard paths such as:
key/
keys/
Keys/
nested/key/folders/
Missing keys are non-fatal. CrayZ logs whether keys were copied or whether no .bikey files were found.
Examples:
@CF|client
1559212036|@CF|client
@VPPAdminTools|server
@Some Server Mod|client
CrayZ preserves the order from mods.txt. If a listed folder is missing, startup fails before DayZ is launched with a clear error. If /dayz/server/<folder_name> already exists as a real file or directory, startup fails instead of overwriting it.
No-space folder aliases are recommended for easier troubleshooting and cleaner launch output, for example @BetterMovement instead of @Better Movement. Folder names with spaces may still work, but they make logs and manual checks easier to misread.
Tested conservative Workshop example:
1559212036|@CommunityFramework|client
2545327648|@DabsFramework|client
3046779255|@BetterMovement|client
1560819773|@UnlimitedStamina|client
Workshop download/update uses the same credentialed SteamCMD login path as server updates. Steam Guard/session persistence is still not guaranteed, so run Workshop install/update intentionally with DAYZ_AUTO_UPDATE=1, then return to DAYZ_AUTO_UPDATE=0 for normal restarts.
Workshop collections and automatic dependency resolution are not supported yet. List each Workshop item explicitly.
To install or update individual Workshop mods:
- Add Workshop lines to
config/mods.txt. - Set
DAYZ_AUTO_UPDATE=1in.env. - Start the container and approve Steam Guard if Steam asks.
- Wait for SteamCMD to finish and for CrayZ to sync the listed Workshop items.
- Stop the container.
- Set
DAYZ_AUTO_UPDATE=0. - Restart normally.
Example:
1559212036|@CF|client
During install/update, SteamCMD downloads item 1559212036 for Workshop app 221100, then CrayZ syncs it into:
/dayz/mods/workshop/@CF
On startup, CrayZ enables it for DayZ with:
/dayz/server/@CF -> /dayz/mods/workshop/@CF
-mod=@CF
Normal runtime with DAYZ_AUTO_UPDATE=0 does not run SteamCMD. It only loads folders that already exist under /dayz/mods/workshop/, through server-root symlinks under /dayz/server/.
Start in foreground:
docker compose upStart in background:
docker compose up -dStop:
docker compose downView logs:
docker logs -f crayz-dayzUpdate image:
docker compose pull
docker compose up -dFor local development, use the local Compose file:
docker compose -f docker-compose.local.yml build
docker compose -f docker-compose.local.yml upThe normal deployment Compose file should use the prebuilt GHCR image.
CrayZ stores persistent runtime data outside the container.
data/server/
Installed DayZ server files.
data/profiles/
DayZ profile and runtime state.
data/logs/
Server logs.
data/mods/workshop/
Local and synced Workshop DayZ mod folders mounted to /dayz/mods/workshop.
data/steam/
SteamCMD login/session state.
data/steam/Steam/
Mounted to /home/dayz/Steam.
data/steam/dot-steam/
Mounted to /home/dayz/.steam.
config/
User-editable configuration files.
These folders should be backed up if you care about preserving the server state.
Do not commit or share:
.env- Steam usernames/passwords
- Steam Guard codes
- downloaded server files
- logs containing private data
- Steam runtime/session state
Safe to commit:
.env.example- Compose files
- scripts
- documentation
- default example config templates
Check that the image exists and that the GHCR package is public or that your Docker host is logged in to GHCR.
docker compose pullCheck that both Steam state mounts are present and writable:
- ./data/steam/Steam:/home/dayz/Steam
- ./data/steam/dot-steam:/home/dayz/.steamFor absolute-path Docker host deployments, use the same container targets:
- /DockerData/crayz/data/steam/Steam:/home/dayz/Steam
- /DockerData/crayz/data/steam/dot-steam:/home/dayz/.steamIf Steam Guard prompts repeat after a successful approval, stop the container before further login attempts and verify these mounts. Repeated failed or repeated new-device logins can trigger Steam account protection.
For normal restarts, set:
DAYZ_AUTO_UPDATE=0SteamCMD login persistence with Steam Guard is not guaranteed yet. Safe runtime mode avoids depending on SteamCMD login for every restart.
Also verify that the container is using consistent PUID and PGID values between runs.
Check your .env:
PUID=1000
PGID=1000Then compare with:
id yourusernameMake sure the config/ folder is mounted writable.
The container cannot create default config files if the config mount is read-only.
Direct public connect to the game port proves only the DayZ game path:
<public-ip-or-domain>:2302
Server browser visibility uses the Steam query path:
<public-ip-or-domain>:27016
For launcher visibility, all three pieces must line up:
- Docker publishes
27016/udp. - The router forwards
27016/udpto the Docker host. config/serverDZ.cfgcontains this top-level setting:
steamQueryPort = 27016;The native DayZ launcher and Steam server browser use the query path to discover the server. DZSA/DZLauncher should also be checked or submitted with <public-ip-or-domain>:27016, not the direct-connect game port. DZSA uses its own index/list behavior, so it may take time and a launcher restart before the server appears.
Confirmed CrayZ troubleshooting result: public direct connect worked on 2302/udp, Docker/NAT exposed 27016/udp, and native DayZ launcher visibility started working after adding steamQueryPort = 27016; to the active /DockerData/crayz/config/serverDZ.cfg.
If edited files such as types.xml, globals.xml, cfgweather.xml, or messages.xml keep reverting, they are probably being edited only in the SteamCMD-managed default mission folder. SteamCMD validation can restore official server files during install/update mode.
Use a custom mission folder and point config/serverDZ.cfg to it with the template setting. Keep the editable source under config/mpmissions/, then copy or sync that custom mission into data/server/mpmissions/ after intentional update/validate runs. See the Configuration section above for the recommended custom mission layout.
Fresh CrayZ configs include instanceId = 1;. If DayZ logs instanceId parameter is mandatory, your existing config/serverDZ.cfg was created before this default was added or was edited manually. Add this line near the other top-level server settings:
instanceId = 1;SteamCMD may not have completed the install/update.
Check the container logs:
docker logs -f crayz-dayzCrayZ is not a commercial hosting panel or web dashboard.
The goal is to provide a reliable, understandable, self-hosted Docker setup for DayZ Dedicated Server hosting.
Workshop collection support is planned, but the base server install, local mod loading, individual Workshop mod updates, Steam login safety, permissions, and restart behavior are the foundation.
