Upload files to "/"

This commit is contained in:
2026-07-03 17:01:35 +00:00
commit 75222000a0
3 changed files with 201 additions and 0 deletions

57
Dockerfile Normal file
View File

@@ -0,0 +1,57 @@
# =========================================================================
# IW4X / MW2 dedicated-server base image
# Extends the Pterodactyl wine yolk and adds the FULL 32-bit Wine tree
# that MW2 (a 2009 32-bit Windows game) needs but the stock yolk lacks.
#
# Build: docker build -t <your-registry>/iw4x-wine:latest .
# Push: docker push <your-registry>/iw4x-wine:latest
# =========================================================================
FROM ghcr.io/pterodactyl/yolks:wine_latest
USER root
# ---- 1. Install the 32-bit Wine libraries the stock image is missing -----
# The stock yolk enables i386 but never installs wine32:i386 / libwine:i386,
# which is why a win32 prefix can't load 32-bit kernel32/user32/etc.
# We add the WineHQ repo to get matching 32-bit builds, then install winbind
# (needed for NTLM), cabextract (winetricks needs it) and the 32-bit tree.
RUN dpkg --add-architecture i386 \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
wget \
gnupg2 \
cabextract \
winbind \
xvfb \
xauth \
wine32:i386 \
libwine:i386 \
fonts-wine \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# ---- 2. Bake a clean 32-bit prefix + runtimes into the image -------------
# Doing this at BUILD time (as root) avoids the unprivileged-runtime apt wall
# and means every container starts from a known-good win32 prefix.
ENV WINEARCH=win32
ENV WINEPREFIX=/opt/wine-prefix
ENV WINEDEBUG=-all
# winetricks is already present in the yolk; if not, grab it.
RUN if ! command -v winetricks >/dev/null 2>&1; then \
wget -O /usr/local/bin/winetricks \
https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks \
&& chmod +x /usr/local/bin/winetricks ; \
fi
# Initialise the prefix headless, then install the runtimes IW4X/MW2 want.
# vcrun2019 + d3dcompiler_47 are the ones the IW4X Linux docs call for.
RUN xvfb-run -a wineboot --init \
&& xvfb-run -a winetricks -q vcrun2019 d3dcompiler_47 \
&& wineserver -w \
&& chmod -R 777 /opt/wine-prefix
USER container
ENV USER=container HOME=/home/container
WORKDIR /home/container

102
iw4x-custom-egg.json Normal file
View File

@@ -0,0 +1,102 @@
{
"_comment": "IW4X egg rebuilt for a custom 32-bit wine image. No Steam login. Game files supplied by you; IW4X files fetched from GitHub at install.",
"meta": {
"version": "PTDL_v2",
"update_url": null
},
"exported_at": "2026-07-03T00:00:00+00:00",
"name": "IW4x (Custom 32-bit Wine)",
"author": "you@yourlab.local",
"description": "IW4x dedicated server for Call of Duty: Modern Warfare 2 (2009), running on a custom 32-bit Wine image. Game files are provided by the operator; IW4X client files are fetched from GitHub via the official launcher.",
"features": null,
"docker_images": {
"IW4X Wine (custom 32-bit)": "REGISTRY.your-lab.local/iw4x-wine:latest"
},
"file_denylist": [],
"startup": "bash ./start-iw4x.sh",
"config": {
"files": "{\r\n \"userraw/server.cfg\": {\r\n \"parser\": \"file\",\r\n \"find\": {\r\n \"sv_hostname\": \"sv_hostname \\\"{{server.build.env.SERVER_NAME}}\\\"\",\r\n \"set g_password\": \"set g_password \\\"{{server.build.env.SERVER_PASSWORD}}\\\"\"\r\n }\r\n }\r\n}",
"startup": "{\r\n \"done\": \"Sending heartbeat to master\"\r\n}",
"logs": "{}",
"stop": "^C"
},
"scripts": {
"installation": {
"script": "#!/bin/bash\r\n# IW4X install script - NO STEAM LOGIN.\r\n# Game (MW2) files are supplied by the operator via upload / volume.\r\n# This script only lays down the IW4X launcher, client dll, rawfiles,\r\n# server configs, and the startup wrapper.\r\n\r\nset -e\r\napt-get update && apt-get install -y --no-install-recommends curl wget unzip tar xz-utils ca-certificates\r\n\r\ncd /mnt/server\r\n\r\n## --- IW4X launcher (Linux) ---\r\necho \"Fetching IW4X launcher...\"\r\nwget -q https://github.com/iw4x/launcher/releases/latest/download/launcher-x86_64-linux-glibc.tar.xz -O launcher.tar.xz || \\\r\n wget -q https://github.com/iw4x/launcher/releases/download/v1.1.8-b.18/launcher-1.1.8-b.18-x86_64-linux-glibc.tar.xz -O launcher.tar.xz\r\ntar xf launcher.tar.xz\r\nrm -f launcher.tar.xz\r\nchmod +x iw4x-launcher || true\r\n\r\n## --- IW4X client dll (the mod itself) ---\r\necho \"Fetching iw4x.dll...\"\r\ncurl -L https://github.com/iw4x/iw4x-client/releases/latest/download/iw4x.dll -o iw4x.dll\r\n\r\n## --- IW4X raw files (assets + iw4x.exe) ---\r\necho \"Fetching raw files...\"\r\ncurl -L https://github.com/iw4x/iw4x-rawfiles/releases/latest/download/release.zip -o release.zip\r\nunzip -o release.zip -d /mnt/server\r\nrm -f release.zip\r\n\r\n## --- Server configs + launch scripts ---\r\necho \"Fetching server configs...\"\r\nwget -q https://github.com/iw4x/iw4-server-configs/archive/refs/heads/main.zip -O configs.zip\r\nunzip -o configs.zip\r\ncp -rf iw4-server-configs-main/* /mnt/server/ 2>/dev/null || true\r\nrm -rf iw4-server-configs-main configs.zip\r\nrm -f LICENSE README.md 2>/dev/null || true\r\n\r\necho \"-----------------------------------------\"\r\necho \"IW4X files installed.\"\r\necho \"IMPORTANT: upload your legally-owned MW2 game files into /home/container\"\r\necho \"(iw4mp.exe and the game assets) if they are not already present.\"\r\necho \"Also upload start-iw4x.sh to /home/container and it will be used at boot.\"\r\necho \"-----------------------------------------\"",
"container": "ghcr.io/pterodactyl/installers:debian",
"entrypoint": "bash"
}
},
"variables": [
{
"name": "Mod Dir",
"description": "Name of the directory where the mod lives (fs_game). Leave blank for none.",
"env_variable": "MOD_DIR",
"default_value": "",
"user_viewable": true,
"user_editable": true,
"rules": "nullable|string",
"field_type": "text"
},
{
"name": "Server Port",
"description": "UDP port the server listens on (default 28960).",
"env_variable": "SERVER_PORT",
"default_value": "28960",
"user_viewable": true,
"user_editable": true,
"rules": "required|integer",
"field_type": "text"
},
{
"name": "LAN Mode",
"description": "0 = public (send heartbeats to master list). 1 = LAN/unlisted.",
"env_variable": "LAN_MODE",
"default_value": "0",
"user_viewable": true,
"user_editable": true,
"rules": "required|boolean",
"field_type": "text"
},
{
"name": "Server Config File",
"description": "Which cfg in userraw/ to exec. server.cfg (dedicated) or partyserver.cfg (lobby).",
"env_variable": "SERVER_CFG",
"default_value": "server.cfg",
"user_viewable": true,
"user_editable": true,
"rules": "required|string",
"field_type": "text"
},
{
"name": "Log File",
"description": "Enable server logging (1 on, 0 off).",
"env_variable": "LOG_FILE",
"default_value": "1",
"user_viewable": true,
"user_editable": true,
"rules": "required|boolean",
"field_type": "text"
},
{
"name": "Server Name",
"description": "Sets sv_hostname. Color codes: ^1 Red ^2 Green ^3 Yellow ^4 Blue ^5 Cyan ^6 Pink ^7 White.",
"env_variable": "SERVER_NAME",
"default_value": "My IW4X Server",
"user_viewable": true,
"user_editable": true,
"rules": "required|string|max:100",
"field_type": "text"
},
{
"name": "Server Password",
"description": "Leave blank for public, or set a password for a private server.",
"env_variable": "SERVER_PASSWORD",
"default_value": "",
"user_viewable": true,
"user_editable": true,
"rules": "nullable|string|max:100",
"field_type": "text"
}
]
}

42
start-iw4x.sh Normal file
View File

@@ -0,0 +1,42 @@
#!/bin/bash
# ==========================================================================
# IW4X startup wrapper (place at /home/container/start-iw4x.sh, chmod +x)
# Called by the egg's Startup Command.
# ==========================================================================
cd /home/container || exit 1
export WINEARCH=win32
export WINEPREFIX=/home/container/.wine
export WINEDEBUG="${WINEDEBUG:--all}"
# --- Seed the known-good 32-bit prefix baked into the image (first boot) ---
# The image ships a fully-initialised win32 prefix at /opt/wine-prefix with
# vcrun2019 + d3dcompiler_47 already installed. If the volume doesn't have a
# valid win32 prefix yet, copy it in. This avoids the stock entrypoint
# rebuilding a broken win64 prefix.
if [ ! -f "${WINEPREFIX}/system.reg" ] || ! grep -q '#arch=win32' "${WINEPREFIX}/system.reg" 2>/dev/null; then
echo "[iw4x] Seeding fresh win32 wine prefix from image..."
rm -rf "${WINEPREFIX}"
cp -a /opt/wine-prefix "${WINEPREFIX}"
echo "[iw4x] Prefix ready: $(head -1 ${WINEPREFIX}/system.reg)"
else
echo "[iw4x] Existing win32 prefix detected, reusing it."
fi
# --- Update IW4X client files via the official launcher (no Steam login) ---
if [ -f ./iw4x-launcher ]; then
echo "[iw4x] Running launcher update..."
./iw4x-launcher --update
fi
# --- Launch the dedicated server ------------------------------------------
# Mirrors the official DedicatedServer.sh invocation.
echo "[iw4x] Launching server..."
exec wine iw4x.exe -dedicated -stdout \
+set fs_game "${MOD_DIR}" \
+set sv_lanonly "${LAN_MODE:-0}" \
+set net_port "${SERVER_PORT}" \
+exec "${SERVER_CFG:-server.cfg}" \
+set logfile "${LOG_FILE:-1}" \
+set party_enable "0" \
+map_rotate