aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/create_release.yml56
-rw-r--r--.github/workflows/validate.yml45
-rw-r--r--CHANGELOG.md1
-rw-r--r--docker/Dockerfile55
-rw-r--r--docker/empty/.gitkeep0
-rw-r--r--scripts/docker.lua88
-rw-r--r--xmake.lua17
7 files changed, 262 insertions, 0 deletions
diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml
index 3345573c0..6d6a15bfc 100644
--- a/.github/workflows/create_release.yml
+++ b/.github/workflows/create_release.yml
@@ -127,6 +127,62 @@ jobs:
name: zenserver-macos
path: build/zenserver-macos.zip
+ docker-build:
+ name: Build Docker Images
+ runs-on: [linux, x64, zen]
+ timeout-minutes: 15
+ needs: [bundle-linux, bundle-windows]
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Read VERSION.txt
+ id: read_version
+ uses: ue-foundation/[email protected]
+ with:
+ path: "./VERSION.txt"
+
+ - name: Download Linux bundle
+ uses: actions/download-artifact@v1
+ with:
+ name: zenserver-linux
+ path: artifacts/linux
+
+ - name: Download Windows bundle
+ uses: actions/download-artifact@v1
+ with:
+ name: zenserver-win64
+ path: artifacts/win64
+
+ - name: Extract binaries
+ run: |
+ mkdir -p build/linux/x86_64/release
+ unzip artifacts/linux/zenserver-linux.zip -d artifacts/linux-extracted
+ cp artifacts/linux-extracted/zenserver build/linux/x86_64/release/
+ mkdir -p build/win-binary-staging
+ unzip artifacts/win64/zenserver-win64.zip -d artifacts/win-extracted
+ cp artifacts/win-extracted/zenserver.exe build/win-binary-staging/
+
+ - name: Build Docker image (with Wine + Windows binary)
+ run: |
+ docker build \
+ -t zenserver-compute:${{ steps.read_version.outputs.content }} \
+ --build-arg WIN_BINARY_DIR=build/win-binary-staging \
+ -f docker/Dockerfile .
+
+ - name: Build Docker image (Linux only, no Wine)
+ run: |
+ docker build \
+ -t zenserver-compute-linux:${{ steps.read_version.outputs.content }} \
+ --build-arg INSTALL_WINE=false \
+ -f docker/Dockerfile .
+
+ # TODO: Push images to container registry
+ # - name: Push images
+ # run: |
+ # docker push zenserver-compute:${{ steps.read_version.outputs.content }}
+ # docker push zenserver-compute-linux:${{ steps.read_version.outputs.content }}
+
create-release:
runs-on: [linux, x64, zen]
timeout-minutes: 5
diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml
index d96645ac9..dfdb9677d 100644
--- a/.github/workflows/validate.yml
+++ b/.github/workflows/validate.yml
@@ -247,3 +247,48 @@ jobs:
with:
name: zenserver-macos
path: build/zenserver-macos.zip
+
+ docker-build:
+ name: Build Docker Images
+ if: github.ref_name == 'main'
+ runs-on: [linux, x64, zen]
+ timeout-minutes: 15
+ needs: [linux-build, windows-build]
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Download Linux bundle
+ uses: actions/download-artifact@v1
+ with:
+ name: zenserver-linux
+ path: artifacts/linux
+
+ - name: Download Windows bundle
+ uses: actions/download-artifact@v1
+ with:
+ name: zenserver-win64
+ path: artifacts/win64
+
+ - name: Extract binaries
+ run: |
+ mkdir -p build/linux/x86_64/release
+ unzip artifacts/linux/zenserver-linux.zip -d artifacts/linux-extracted
+ cp artifacts/linux-extracted/zenserver build/linux/x86_64/release/
+ mkdir -p build/win-binary-staging
+ unzip artifacts/win64/zenserver-win64.zip -d artifacts/win-extracted
+ cp artifacts/win-extracted/zenserver.exe build/win-binary-staging/
+
+ - name: Build Docker image (with Wine + Windows binary)
+ run: |
+ docker build \
+ -t zenserver-compute:latest \
+ --build-arg WIN_BINARY_DIR=build/win-binary-staging \
+ -f docker/Dockerfile .
+
+ - name: Build Docker image (Linux only, no Wine)
+ run: |
+ docker build \
+ -t zenserver-compute-linux:latest \
+ --build-arg INSTALL_WINE=false \
+ -f docker/Dockerfile .
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cd0f85c98..930b9938c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@
- Feature: Added `zen down --all` flag to shut down all running zenserver instances
- Feature: Added `xmake kill` task to terminate all running zenserver instances
- Feature: Support `ZEN_MALLOC` environment variable for default allocator selection; default allocator switched to rpmalloc
+- Feature: Added Dockerfile and extended GHA workflows to produce zenserver Docker images, primarily intended for compute nodes
- Improvement: Added support for CoW block-cloning (used by build download) on Linux (tested with: btrfs/ XFS)
- Improvement: Added full-file CoW copying on macOS (APFS)
- Improvement: Updated asio to 1.38.0
diff --git a/docker/Dockerfile b/docker/Dockerfile
new file mode 100644
index 000000000..060042d85
--- /dev/null
+++ b/docker/Dockerfile
@@ -0,0 +1,55 @@
+# Copyright Epic Games, Inc. All Rights Reserved.
+#
+# Runtime image for zenserver compute workers.
+#
+# Build variants:
+# With Wine (for running Windows worker executables via WineProcessRunner):
+# docker build -t zenserver-compute -f docker/Dockerfile .
+#
+# Without Wine (Linux-only workers, smaller image):
+# docker build -t zenserver-compute --build-arg INSTALL_WINE=false -f docker/Dockerfile .
+#
+# The build context must contain the pre-built Linux zenserver binary at:
+# build/linux/x86_64/release/zenserver
+
+FROM ubuntu:24.04
+
+# Avoid interactive prompts during package installation
+ENV DEBIAN_FRONTEND=noninteractive
+
+# Set to "false" to skip Wine installation and produce a smaller image
+ARG INSTALL_WINE=true
+
+# Install WineHQ (only when INSTALL_WINE=true)
+# Enables i386 architecture required for Wine32 support
+RUN if [ "$INSTALL_WINE" = "true" ]; then \
+ dpkg --add-architecture i386 \
+ && apt-get update \
+ && apt-get install -y --no-install-recommends \
+ ca-certificates \
+ gnupg \
+ wget \
+ && wget -qO- https://dl.winehq.org/wine-builds/winehq.key \
+ | gpg --dearmor -o /usr/share/keyrings/winehq-archive.key \
+ && echo "deb [signed-by=/usr/share/keyrings/winehq-archive.key] https://dl.winehq.org/wine-builds/ubuntu/ noble main" \
+ > /etc/apt/sources.list.d/winehq.list \
+ && apt-get update \
+ && apt-get install -y --no-install-recommends winehq-stable \
+ && apt-get remove -y gnupg wget \
+ && apt-get autoremove -y \
+ && rm -rf /var/lib/apt/lists/* ; \
+ fi
+
+# Copy the pre-built zenserver binary
+COPY build/linux/x86_64/release/zenserver /opt/zenserver/zenserver
+RUN chmod +x /opt/zenserver/zenserver
+
+# Optional: Windows zenserver binary for Wine-based compute workers.
+# Set WIN_BINARY_DIR to a directory containing zenserver.exe to include it.
+# Defaults to docker/empty (an empty placeholder) so the COPY is a no-op.
+ARG WIN_BINARY_DIR=docker/empty
+COPY ${WIN_BINARY_DIR}/ /opt/zenserver/
+
+EXPOSE 8558
+
+ENTRYPOINT ["/opt/zenserver/zenserver"]
diff --git a/docker/empty/.gitkeep b/docker/empty/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/docker/empty/.gitkeep
diff --git a/scripts/docker.lua b/scripts/docker.lua
new file mode 100644
index 000000000..f66f8db86
--- /dev/null
+++ b/scripts/docker.lua
@@ -0,0 +1,88 @@
+-- Copyright Epic Games, Inc. All Rights Reserved.
+
+import("core.base.option")
+
+--------------------------------------------------------------------------------
+local function _get_version()
+ local version_file = path.join(os.projectdir(), "VERSION.txt")
+ local version = io.readfile(version_file)
+ if version then
+ version = version:trim()
+ end
+ if not version or version == "" then
+ raise("Failed to read version from VERSION.txt")
+ end
+ return version
+end
+
+--------------------------------------------------------------------------------
+function main()
+ local registry = option.get("registry")
+ local tag = option.get("tag")
+ local push = option.get("push")
+ local no_wine = option.get("no-wine")
+ local win_binary = option.get("win-binary")
+
+ if not tag then
+ tag = _get_version()
+ end
+
+ local image_name = no_wine and "zenserver-compute-linux" or "zenserver-compute"
+ if registry then
+ image_name = registry .. "/" .. image_name
+ end
+
+ local full_tag = image_name .. ":" .. tag
+
+ -- Verify the zenserver binary exists
+ local binary_path = path.join(os.projectdir(), "build/linux/x86_64/release/zenserver")
+ if not os.isfile(binary_path) then
+ raise("zenserver binary not found at %s\nBuild it first with: xmake config -y -m release -a x64 && xmake build -y zenserver", binary_path)
+ end
+
+ -- Stage Windows binary if provided
+ local win_staging_dir = nil
+ if win_binary then
+ if not os.isfile(win_binary) then
+ raise("Windows binary not found at %s", win_binary)
+ end
+ win_staging_dir = path.join(os.projectdir(), "build/win-binary-staging")
+ os.mkdir(win_staging_dir)
+ os.cp(win_binary, path.join(win_staging_dir, "zenserver.exe"))
+ print("-- Including Windows binary: %s", win_binary)
+ end
+
+ -- Build the Docker image
+ local dockerfile = path.join(os.projectdir(), "docker/Dockerfile")
+ print("-- Building Docker image: %s", full_tag)
+ local args = {"build", "-t", full_tag, "-f", dockerfile}
+ if no_wine then
+ table.insert(args, "--build-arg")
+ table.insert(args, "INSTALL_WINE=false")
+ end
+ if win_staging_dir then
+ table.insert(args, "--build-arg")
+ table.insert(args, "WIN_BINARY_DIR=build/win-binary-staging")
+ end
+ table.insert(args, os.projectdir())
+ local ret = os.execv("docker", args)
+ if ret > 0 then
+ raise("Docker build failed")
+ end
+
+ -- Clean up staging directory
+ if win_staging_dir then
+ os.rmdir(win_staging_dir)
+ end
+
+ print("-- Built image: %s", full_tag)
+
+ if push then
+ print("-- Pushing image: %s", full_tag)
+ ret = os.execv("docker", {"push", full_tag})
+ if ret > 0 then
+ raise("Docker push failed")
+ end
+ print("-- Pushed image: %s", full_tag)
+ end
+end
diff --git a/xmake.lua b/xmake.lua
index 561f9f399..acab78600 100644
--- a/xmake.lua
+++ b/xmake.lua
@@ -382,6 +382,23 @@ task("bundle")
bundle()
end)
+task("docker")
+ set_menu {
+ usage = "xmake docker [--push] [--no-wine] [--win-binary PATH] [--tag TAG] [--registry REGISTRY]",
+ description = "Build Docker image for zenserver compute workers",
+ options = {
+ {nil, "push", "k", nil, "Push the image after building"},
+ {nil, "no-wine", "k", nil, "Build without Wine (smaller image, Linux-only workers)"},
+ {nil, "win-binary", "v", nil, "Path to Windows zenserver.exe to include in image"},
+ {nil, "tag", "v", nil, "Override image tag (default: version from VERSION.txt)"},
+ {nil, "registry", "v", nil, "Registry prefix (e.g. ghcr.io/epicgames)"},
+ }
+ }
+ on_run(function ()
+ import("scripts.docker")
+ docker()
+ end)
+
task("kill")
set_menu {
usage = "xmake kill",