Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions docker-compose.dedicated-server.ghcr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ services:
WINEDEBUG: -all
# linux require use file stdin
SERVER_CLI_INPUT_MODE: ${SERVER_CLI_INPUT_MODE:-stream}
# minimum required virtual screen
XVFB_DISPLAY: ${XVFB_DISPLAY:-:99}
XVFB_SCREEN: ${XVFB_SCREEN:-720x1280x16}
volumes:
# - wineprefix64:/var/opt/wineprefix64
- ./server-data:/srv/persist
Expand Down
3 changes: 0 additions & 3 deletions docker-compose.dedicated-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ services:
WINEDEBUG: -all
# linux require use file stdin
SERVER_CLI_INPUT_MODE: ${SERVER_CLI_INPUT_MODE:-stream}
# minimum required virtual screen
XVFB_DISPLAY: ${XVFB_DISPLAY:-:99}
XVFB_SCREEN: ${XVFB_SCREEN:-64x64x16}
volumes:
# - wineprefix64:/var/opt/wineprefix64
- ./server-data:/srv/persist
Expand Down
6 changes: 4 additions & 2 deletions docker/dedicated-server/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
FROM debian:bookworm-slim
FROM debian:trixie-slim

ARG DEBIAN_FRONTEND=noninteractive
# basically, it only works with a Release build.(libs are not included in Debug build)
ARG MC_RUNTIME_DIR=x64/Minecraft.Server/Release
ENV DISPLAY=" "

RUN dpkg --add-architecture i386 \
&& apt-get update \
Expand All @@ -11,7 +12,8 @@ RUN dpkg --add-architecture i386 \
wine \
wine64 \
wine32:i386 \
xvfb \
xwayland-run \
cage \
tini \
&& rm -rf /var/lib/apt/lists/*

Expand Down
86 changes: 1 addition & 85 deletions docker/dedicated-server/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,65 +30,6 @@ ensure_persist_file() {
ln -sfn "${persist_path}" "${runtime_path}"
}

wait_for_xvfb_ready() {
local display="$1"
local xvfb_pid="$2"
local wait_seconds="${XVFB_WAIT_SECONDS:-10}"
local wait_ticks=$((wait_seconds * 10))
local display_number="${display#:}"
display_number="${display_number%%.*}"

if [ -z "${display_number}" ] || ! [[ "${display_number}" =~ ^[0-9]+$ ]]; then
echo "[error] Invalid DISPLAY format for Xvfb wait: ${display}" >&2
return 1
fi

local socket_path="/tmp/.X11-unix/X${display_number}"
local elapsed=0

while [ "${elapsed}" -lt "${wait_ticks}" ]; do
if ! kill -0 "${xvfb_pid}" 2>/dev/null; then
echo "[error] Xvfb exited before the display became ready." >&2
if [ -f /tmp/xvfb.log ]; then
echo "[error] ---- /tmp/xvfb.log ----" >&2
tail -n 200 /tmp/xvfb.log >&2 || true
echo "[error] ----------------------" >&2
fi
return 1
fi

if [ -S "${socket_path}" ]; then
# Keep a short extra delay so Wine does not race display handshake.
sleep 0.2
if kill -0 "${xvfb_pid}" 2>/dev/null && [ -S "${socket_path}" ]; then
return 0
fi
fi

# One more liveness check after the ready probe branch.
if ! kill -0 "${xvfb_pid}" 2>/dev/null; then
echo "[error] Xvfb exited during display readiness probe." >&2
if [ -f /tmp/xvfb.log ]; then
echo "[error] ---- /tmp/xvfb.log ----" >&2
tail -n 200 /tmp/xvfb.log >&2 || true
echo "[error] ----------------------" >&2
fi
return 1
fi

sleep 0.1
elapsed=$((elapsed + 1))
done

echo "[error] Timed out waiting for Xvfb display ${display}." >&2
if [ -f /tmp/xvfb.log ]; then
echo "[error] ---- /tmp/xvfb.log ----" >&2
tail -n 200 /tmp/xvfb.log >&2 || true
echo "[error] ----------------------" >&2
fi
return 1
}

if [ ! -d "$SERVER_DIR" ]; then
echo "[error] Server directory not found: $SERVER_DIR" >&2
exit 1
Expand Down Expand Up @@ -133,35 +74,10 @@ if [ ! -d "${WINEPREFIX}" ] || [ -z "$(ls -A "${WINEPREFIX}" 2>/dev/null)" ]; th
mkdir -p "${WINEPREFIX}"
fi

# in the current implementation, a virtual screen is required because the client-side logic is being called for compatibility
if [ -z "${DISPLAY:-}" ]; then
export DISPLAY="${XVFB_DISPLAY:-:99}"
XVFB_SCREEN="${XVFB_SCREEN:-64x64x16}"
DISPLAY_NUMBER="${DISPLAY#:}"
DISPLAY_NUMBER="${DISPLAY_NUMBER%%.*}"
if [ -z "${DISPLAY_NUMBER}" ] || ! [[ "${DISPLAY_NUMBER}" =~ ^[0-9]+$ ]]; then
echo "[error] Invalid XVFB_DISPLAY format: ${DISPLAY}" >&2
exit 1
fi
XVFB_SOCKET="/tmp/.X11-unix/X${DISPLAY_NUMBER}"
XVFB_LOCK="/tmp/.X${DISPLAY_NUMBER}-lock"
# The check is performed assuming the same container will be restarted.
if [ -S "${XVFB_SOCKET}" ] || [ -e "${XVFB_LOCK}" ]; then
echo "[warn] Removing stale Xvfb state for ${DISPLAY} before startup." >&2
rm -f "${XVFB_SOCKET}" "${XVFB_LOCK}"
fi
Xvfb "${DISPLAY}" -nolisten tcp -screen 0 "${XVFB_SCREEN}" >/tmp/xvfb.log 2>&1 &
XVFB_PID=$!
wait_for_xvfb_ready "${DISPLAY}" "${XVFB_PID}"
echo "[info] Xvfb ready on ${DISPLAY} (pid=${XVFB_PID}, screen=${XVFB_SCREEN})"
else
echo "[info] Using existing DISPLAY=${DISPLAY}; skipping Xvfb startup"
fi

args=(
-port "${SERVER_PORT}"
-bind "${SERVER_BIND_IP}"
)

echo "[info] Starting ${SERVER_EXE} on ${SERVER_BIND_IP}:${SERVER_PORT}"
exec "${WINE_CMD}" "${SERVER_EXE}" "${args[@]}"
exec wlheadless-run -c cage -- "${WINE_CMD}" "${SERVER_EXE}" "${args[@]}"
Loading