Files
2025-05-18 13:04:45 +08:00

247 lines
16 KiB
Docker

# This file was generated by ue4-docker version 0.0.114 with the following options:
#
# - buildgraph_args: "-set:BuildIdOverride=UE_5.4 -set:WithLinuxArm64=false -set:WithClient=true -set:WithServer=true"
# - combine: true
# - credential_mode: "secrets"
# - disable_all_patches: true
# - disable_labels: true
# - enable_dso_patch: false
# - enable_ushell: true
# - excluded_components: {"ddc": false, "debug": false, "templates": false}
# - gitdependencies_args: ""
#
# This Dockerfile combines the steps for the following images:
#
# - ue4-build-prerequisites
# - ue4-source
# - ue4-minimal
ARG BASEIMAGE
FROM ${BASEIMAGE} as prerequisites
# Disable interactive prompts during package installation
ENV DEBIAN_FRONTEND=noninteractive
# Enable CUDA support for NVIDIA GPUs (even when not using a CUDA base image), since evidently some versions of UE unconditionally assume
# `libcuda.so.1` exists when using the NVIDIA proprietary drivers, and will fail to initialise the Vulkan RHI if it is missing
ENV NVIDIA_DRIVER_CAPABILITIES ${NVIDIA_DRIVER_CAPABILITIES},compute
# Add the "display" driver capability for NVIDIA GPUs
# (This allows us to run the Editor from an interactive container by bind-mounting the host system's X11 socket)
ENV NVIDIA_DRIVER_CAPABILITIES ${NVIDIA_DRIVER_CAPABILITIES},display
# Enable NVENC support for use by Unreal Engine plugins that depend on it (e.g. Pixel Streaming)
# (Note that adding `video` seems to implicitly enable `compute` as well, but we include separate directives here to clearly indicate the purpose of both)
ENV NVIDIA_DRIVER_CAPABILITIES ${NVIDIA_DRIVER_CAPABILITIES},video
# Install our build prerequisites
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
ca-certificates \
curl \
git \
git-lfs \
gpg-agent \
python3 \
python3-dev \
python3-pip \
shared-mime-info \
software-properties-common \
sudo \
tzdata \
unzip \
xdg-user-dirs \
xdg-utils \
zip && \
rm -rf /var/lib/apt/lists/* && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Install the X11 runtime libraries required by CEF so we can cook Unreal Engine projects that use the WebBrowserWidget plugin
# (Starting in Unreal Engine 5.0, we need these installed before creating an Installed Build to prevent cooking failures related to loading the Quixel Bridge plugin)
RUN apt-get update && apt-get install -y --no-install-recommends \
libasound2 \
libatk1.0-0 \
libatk-bridge2.0-0 \
libcairo2 \
libfontconfig1 \
libfreetype6 \
libgbm1 \
libglu1 \
libnss3 \
libnspr4 \
libpango-1.0-0 \
libpangocairo-1.0-0 \
libsm6 \
libxcomposite1 \
libxcursor1 \
libxdamage1 \
libxi6 \
libxkbcommon-x11-0 \
libxrandr2 \
libxrender1 \
libxss1 \
libxtst6 \
libxv1 \
x11-xkb-utils \
xauth \
xfonts-base \
xkb-data && \
rm -rf /var/lib/apt/lists/* && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Disable the default "lecture" message the first time a user runs a command using sudo
RUN echo 'Defaults lecture="never"' >> /etc/sudoers && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Unreal refuses to run as the root user, so create a non-root user with no password and allow them to run commands using sudo
RUN useradd --create-home --home /home/ue4 --shell /bin/bash --uid 1000 ue4 && \
passwd -d ue4 && \
usermod -a -G audio,video,sudo ue4 && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
USER ue4
# Install Python 3.12, which is required by ushell
USER root
RUN add-apt-repository -y ppa:deadsnakes/ppa && \
apt-get update && \
apt-get install -y --no-install-recommends python3.12 python3.12-venv && \
rm -rf /var/lib/apt/lists/* && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
USER ue4
# Install a copy of pip for Python 3.12
RUN curl -fsSL 'https://bootstrap.pypa.io/get-pip.py' | python3.12 && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Enable Git Large File Storage (LFS) support
RUN git lfs install && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
FROM prerequisites as source
# The git repository that we will clone
ARG GIT_REPO=""
# The git branch/tag/commit that we will checkout
ARG GIT_BRANCH=""
# Install our git credential helper that retrieves credentials from build secrets
COPY --chown=ue4:ue4 git-credential-helper-secrets.sh /tmp/git-credential-helper-secrets.sh
ENV GIT_ASKPASS=/tmp/git-credential-helper-secrets.sh
RUN chmod +x /tmp/git-credential-helper-secrets.sh && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Clone the UE4 git repository using the build secret credentials
# (Note that we include the changelist override value here to ensure any cached source code is invalidated if
# the override is modified between runs, which is useful when testing preview versions of the Unreal Engine)
ARG CHANGELIST
RUN --mount=type=secret,id=username,uid=1000,required \
--mount=type=secret,id=password,uid=1000,required \
CHANGELIST="$CHANGELIST" \
mkdir /home/ue4/UnrealEngine && \
cd /home/ue4/UnrealEngine && \
git init && \
git remote add origin "$GIT_REPO" && \
git fetch --progress --depth 1 origin "$GIT_BRANCH" && \
git checkout FETCH_HEAD && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Run post-clone setup steps, ensuring our package lists are up to date since Setup.sh doesn't call `apt-get update`
# Ensure Setup.sh uses the same cache path when building either UE4 or UE5
ENV UE_GITDEPS=/home/ue4/gitdeps
ENV UE4_GITDEPS=/home/ue4/gitdeps
RUN mkdir "$UE_GITDEPS" && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# When running with BuildKit, we use a cache mount to cache the dependency data across multiple build invocations
WORKDIR /home/ue4/UnrealEngine
RUN --mount=type=cache,target=/home/ue4/gitdeps,uid=1000,gid=1000 sudo apt-get update && \
./Setup.sh && \
sudo rm -rf /var/lib/apt/lists/* && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
FROM source as builder
# Set the changelist number in Build.version to ensure our Build ID is generated correctly
ARG CHANGELIST
COPY set-changelist.py /tmp/set-changelist.py
RUN python3 /tmp/set-changelist.py /home/ue4/UnrealEngine/Engine/Build/Build.version $CHANGELIST && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Remove the .git directory to disable UBT `git status` calls and speed up the build process
RUN rm -rf /home/ue4/UnrealEngine/.git && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Ensure UBT is built before we create the Installed Build, since Build.sh explicitly sets the
# target .NET Framework version, whereas InstalledEngineBuild.xml just uses the system default,
# which can result in errors when running the built UBT due to the wrong version being targeted
RUN ./Engine/Build/BatchFiles/Linux/Build.sh ShaderCompileWorker Linux Development -SkipBuild -buildubt && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Create an Installed Build of the Engine
WORKDIR /home/ue4/UnrealEngine
RUN ./Engine/Build/BatchFiles/RunUAT.sh BuildGraph \
-target="Make Installed Build Linux" \
-script=Engine/Build/InstalledEngineBuild.xml \
-set:HostPlatformOnly=true \
-set:WithDDC=true \
-set:BuildIdOverride=UE_5.4 -set:WithLinuxArm64=false -set:WithClient=true -set:WithServer=true && \
rm -R -f /home/ue4/UnrealEngine/LocalBuilds/InstalledDDC && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Ensure UnrealVersionSelector is built, since the prebuilt binaries may not be up-to-date
RUN ./Engine/Build/BatchFiles/Linux/Build.sh UnrealVersionSelector Linux Shipping && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Copy InstalledBuild.txt from the Installed Build and run UnrealVersionSelector to populate Install.ini with any custom Build ID specified in the BuildGraph flags
# (Note that the `-unattended` flag used below requires Unreal Engine 4.22 or newer, so this will break under older versions)
# (Note also that custom Build IDs are supported by Unreal Engine 5.3.1 and newer, and older versions will just use a GUID as the Build ID)
RUN cp /home/ue4/UnrealEngine/LocalBuilds/Engine/Linux/Engine/Build/InstalledBuild.txt /home/ue4/UnrealEngine/Engine/Build/InstalledBuild.txt && \
./Engine/Binaries/Linux/UnrealVersionSelector-Linux-Shipping -register -unattended && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Ensure ushell is copied to the Installed Build
RUN rm -rf ./LocalBuilds/Engine/Linux/Engine/Extras/ushell && \
cp -r ./Engine/Extras/ushell ./LocalBuilds/Engine/Linux/Engine/Extras/ushell && \
bash -c 'set -e; shopt -s globstar; cd /home/ue4/UnrealEngine/LocalBuilds/Engine/Linux/Engine/Extras/ushell && chmod +x ./**/*.sh' && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Split out both optional components (DDC, debug symbols, template projects) and large subdirectories so they can be copied
# into the final container image as separate filesystem layers, avoiding creating a single monolithic layer with everything
COPY split-components.py /tmp/split-components.py
RUN python3 /tmp/split-components.py /home/ue4/UnrealEngine/LocalBuilds/Engine/Linux /home/ue4/UnrealEngine/Components && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Copy the Installed Build into a clean image, discarding the source build
FROM prerequisites as minimal
# Copy the Installed Build files from the builder image
COPY --from=builder --chown=ue4:ue4 /home/ue4/UnrealEngine/LocalBuilds/Engine/Linux /home/ue4/UnrealEngine
COPY --from=builder --chown=ue4:ue4 /home/ue4/UnrealEngine/Components/Binaries /home/ue4/UnrealEngine
COPY --from=builder --chown=ue4:ue4 /home/ue4/UnrealEngine/Components/Content /home/ue4/UnrealEngine
COPY --from=builder --chown=ue4:ue4 /home/ue4/UnrealEngine/Components/Extras /home/ue4/UnrealEngine
COPY --from=builder --chown=ue4:ue4 /home/ue4/UnrealEngine/Components/Intermediate /home/ue4/UnrealEngine
COPY --from=builder --chown=ue4:ue4 /home/ue4/UnrealEngine/Components/Plugins /home/ue4/UnrealEngine
COPY --from=builder --chown=ue4:ue4 /home/ue4/UnrealEngine/Components/Source /home/ue4/UnrealEngine
COPY --from=builder --chown=ue4:ue4 /home/ue4/UnrealEngine/Components/DDC /home/ue4/UnrealEngine
COPY --from=builder --chown=ue4:ue4 /home/ue4/UnrealEngine/Components/DebugSymbols /home/ue4/UnrealEngine
COPY --from=builder --chown=ue4:ue4 /home/ue4/UnrealEngine/Components/TemplatesAndSamples /home/ue4/UnrealEngine
# Copy Install.ini from the builder image, so it can be used by tools that read the list of engine installations (e.g. ushell)
COPY --from=builder --chown=ue4:ue4 /home/ue4/.config/Epic/UnrealEngine/Install.ini /home/ue4/.config/Epic/UnrealEngine/Install.ini
WORKDIR /home/ue4/UnrealEngine
# Add ushell to the system PATH and alias `ushell` to `ushell.sh`
ENV PATH="$PATH:/home/ue4/UnrealEngine/Engine/Extras/ushell"
RUN echo 'alias ushell="ushell.sh"' >> /home/ue4/.bashrc && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Perform first-run setup for ushell
RUN bash -c 'set -e; source /home/ue4/UnrealEngine/Engine/Extras/ushell/ushell.sh && exit 0' && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Perform first-run setup for Mono, UnrealBuildTool and AutomationTool, which makes it possible to build Unreal projects and plugins as users other than `ue4`
# (Note that this will only work with 4.26.0 and newer, older Engine versions will always require write access to `/home/ue4/UnrealEngine`)
# See the comments on this issue for details, including the need to ensure $HOME is set correctly: <https://github.com/adamrehn/ue4-docker/issues/141>
COPY print-editor-target.py /tmp/print-editor-target.py
RUN EDITOR_TARGET=$(python3 /tmp/print-editor-target.py /home/ue4/UnrealEngine) && \
./Engine/Build/BatchFiles/Linux/Build.sh "$EDITOR_TARGET" Linux Development -SkipBuild && \
mkdir -p ./Engine/Programs/AutomationTool/Saved && \
chmod a+rw ./Engine/Programs/AutomationTool/Saved && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
# Enable Vulkan support for NVIDIA GPUs
USER root
RUN apt-get update && apt-get install -y --no-install-recommends libvulkan1 && \
rm -rf /var/lib/apt/lists/* && \
VULKAN_API_VERSION=`dpkg -s libvulkan1 | grep -oP 'Version: [0-9|\.]+' | grep -oP '[0-9|\.]+'` && \
mkdir -p /etc/vulkan/icd.d/ && \
echo \
"{\
\"file_format_version\" : \"1.0.0\",\
\"ICD\": {\
\"library_path\": \"libGLX_nvidia.so.0\",\
\"api_version\" : \"${VULKAN_API_VERSION}\"\
}\
}" > /etc/vulkan/icd.d/nvidia_icd.json && echo '' && echo 'RUN directive complete. Docker will now commit the filesystem layer to disk.' && echo 'Note that for large filesystem layers this can take quite some time.' && echo 'Performing filesystem layer commit...' && echo ''
USER ue4