# syntax=docker/dockerfile:1.7

# =============================================================================
# Versions
# =============================================================================

# Update these values whenever the NVIDIA GPU Operator driver changes.
ARG NVIDIA_DRIVER_BRANCH=580
ARG NVIDIA_DRIVER_VERSION=580.126.20
ARG NVIDIA_DRIVER_PACKAGE_VERSION=580.126.20-1ubuntu1

ARG SUNSHINE_REF=0784774
ARG BUILD_DEPS_VERSION=v2026.724.203728
ARG NV_CODEC_HEADERS_VERSION=n13.0.19.1

# ============================================================================
# Build du FFmpeg utilisé par Sunshine
# nv-codec-headers volontairement limité à NVENC API 13.0
# ============================================================================
FROM docker.io/library/ubuntu:24.04 AS ffmpeg-build

ARG BUILD_DEPS_VERSION
ARG NV_CODEC_HEADERS_VERSION

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        autoconf \
        automake \
        build-essential \
        ca-certificates \
        cmake \
        git \
        libass-dev \
        libfreetype6-dev \
        libgnutls28-dev \
        libmp3lame-dev \
        libnuma-dev \
        libopus-dev \
        libsdl2-dev \
        libtool \
        libvorbis-dev \
        libxcb1-dev \
        libxcb-shm0-dev \
        libxcb-xfixes0-dev \
        libx11-xcb-dev \
        libxcb-dri3-dev \
        make \
        meson \
        nasm \
        ninja-build \
        pkg-config \
        texinfo \
        wget \
        zlib1g-dev && \
    rm -rf /var/lib/apt/lists/*

RUN git clone \
        --branch "${BUILD_DEPS_VERSION}" \
        --depth 1 \
        --recurse-submodules \
        https://github.com/LizardByte/build-deps.git \
        /src/build-deps

# Le point important :
# on remplace les nv-codec-headers utilisés pour compiler FFmpeg
# par la dernière release API 13.0.
RUN rm -rf /src/build-deps/third-party/FFmpeg/nv-codec-headers && \
    git clone \
        --branch "${NV_CODEC_HEADERS_VERSION}" \
        --depth 1 \
        https://github.com/FFmpeg/nv-codec-headers.git \
        /src/build-deps/third-party/FFmpeg/nv-codec-headers

RUN cmake \
        -S /src/build-deps \
        -B /src/build-deps/build \
        -G "Unix Makefiles" \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX=/opt/build-deps \
        -DBUILD_ALL=OFF \
        -DBUILD_FFMPEG=ON \
        -DBUILD_FFMPEG_NV_CODEC_HEADERS=ON \
        -DBUILD_FFMPEG_CUDA_LLVM=OFF \
        -DBUILD_TESTS=OFF \
        -DBUILD_DOCS=OFF && \
    cmake --build /src/build-deps/build --parallel "$(nproc)" && \
    cmake --install /src/build-deps/build


# ============================================================================
# Build de Sunshine avec notre FFmpeg
# ============================================================================
FROM docker.io/library/ubuntu:24.04 AS sunshine-build

ARG SUNSHINE_REF

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        ca-certificates \
        git && \
    rm -rf /var/lib/apt/lists/*

RUN git clone \
        --filter=blob:none \
        https://github.com/LizardByte/Sunshine.git \
        /src/sunshine && \
    cd /src/sunshine && \
    git checkout "${SUNSHINE_REF}" && \
    git submodule update --init --recursive --depth 1

# Installation des dépendances de compilation de Sunshine.
# --skip-cuda désactive NVFBC/CUDA dans Sunshine, PAS NVENC via FFmpeg.
RUN cd /src/sunshine && \
    ./scripts/linux_build.sh \
        --sudo-off \
        --skip-cuda \
        --step=deps

# Remplacement du FFmpeg précompilé de LizardByte par le nôtre.
COPY --from=ffmpeg-build /opt/build-deps/ffmpeg /tmp/custom-ffmpeg

RUN rm -rf \
        /src/sunshine/third-party/build-deps/ffmpeg/Linux-x86_64 && \
    mkdir -p \
        /src/sunshine/third-party/build-deps/ffmpeg/Linux-x86_64 && \
    cp -a \
        /tmp/custom-ffmpeg/. \
        /src/sunshine/third-party/build-deps/ffmpeg/Linux-x86_64/

# Configuration + compilation + création du .deb
RUN cd /src/sunshine && \
    ./scripts/linux_build.sh \
        --sudo-off \
        --skip-cuda \
        --step=cmake && \
    ./scripts/linux_build.sh \
        --sudo-off \
        --skip-cuda \
        --step=build && \
    ./scripts/linux_build.sh \
        --sudo-off \
        --skip-cuda \
        --step=package && \
    cp /src/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine.deb



# =============================================================================
# Main image
# =============================================================================

FROM docker.io/library/ubuntu:24.04

ARG NVIDIA_DRIVER_BRANCH
ARG NVIDIA_DRIVER_VERSION
ARG NVIDIA_DRIVER_PACKAGE_VERSION

ARG USER_NAME=ubuntu
ARG USER_UID=1000
ARG USER_GID=1000

ENV DEBIAN_FRONTEND=noninteractive \
    HOME=/home/ubuntu \
    USER=ubuntu \
    DISPLAY=:20 \
    DISPLAY_SIZEW=1920 \
    DISPLAY_SIZEH=1080 \
    DISPLAY_REFRESH=120 \
    DISPLAY_DPI=96 \
    DISPLAY_CDEPTH=24 \
    VIDEO_PORT=HDMI-0 \
    TZ=Europe/Paris \
    LANG=fr_FR.UTF-8 \
    LANGUAGE=fr_FR:fr \
    LC_ALL=fr_FR.UTF-8 \
    XDG_RUNTIME_DIR=/tmp/runtime-ubuntu \
    PIPEWIRE_RUNTIME_DIR=/tmp/runtime-ubuntu \
    PULSE_RUNTIME_PATH=/tmp/runtime-ubuntu/pulse \
    PULSE_SERVER=unix:/tmp/runtime-ubuntu/pulse/native \
    NVIDIA_VISIBLE_DEVICES=all \
    NVIDIA_DRIVER_CAPABILITIES=all \
    EXPECTED_NVIDIA_DRIVER_VERSION=${NVIDIA_DRIVER_VERSION} \
    NVIDIA_I386_PACKAGE_VERSION=${NVIDIA_DRIVER_PACKAGE_VERSION}

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

USER root


# =============================================================================
# Base desktop / gaming environment
# =============================================================================

RUN dpkg --add-architecture i386 \
    && apt-get update \
    && apt-get install --no-install-recommends -y \
		btop fonts-noto-cjk fonts-ubuntu mousepad nano ristretto thunar \
        ubuntu-wallpapers \
        adwaita-icon-theme \
        elementary-xfce-icon-theme \
        greybird-gtk-theme \
        hicolor-icon-theme \
        humanity-icon-theme \
        keyboard-configuration \
        tango-icon-theme \
        xfce4-goodies \
        xfce4-notifyd \
        xfce4-pulseaudio-plugin \
        xfonts-base \
        xfonts-scalable \
        alsa-utils \
        ca-certificates \
        curl \
        dbus \
        dbus-user-session \
        dbus-x11 \
        file \
        fonts-dejavu \
        fonts-liberation \
        fonts-noto \
        fonts-noto-color-emoji \
        kmod \
        libasound2-plugins \
        libcap2-bin \
        libegl1 \
        libgbm1 \
        libgl1 \
        libglvnd0 \
        libglx0 \
        libpciaccess0 \
        libpulse0 \
        libvulkan1 \
        libx11-6 \
        libx11-xcb1 \
        libxdamage1 \
        libxext6 \
        libxfixes3 \
        libxinerama1 \
        libxrandr2 \
        libxss1 \
        libxtst6 \
        locales \
        mesa-utils \
        pciutils \
        pipewire \
        pipewire-pulse \
        procps \
        psmisc \
        pulseaudio-utils \
        sudo \
        supervisor \
        tzdata \
        udev \
        vulkan-tools \
        wireplumber \
        x11-utils \
        x11-xserver-utils \
        xauth \
        xcvt \
        xdg-user-dirs \
        xdg-utils \
        xfce4 \
        xfce4-terminal \
        xkb-data \
        xserver-xorg-core \
        xserver-xorg-input-libinput \
        xserver-xorg-legacy \
        xz-utils \
    && sed -i \
        -e 's/^# *fr_FR.UTF-8 UTF-8/fr_FR.UTF-8 UTF-8/' \
        -e 's/^# *en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' \
        /etc/locale.gen \
    && locale-gen \
    && apt-get clean \
    && rm -rf \
        /var/lib/apt/lists/* \
        /var/cache/apt/* \
        /var/cache/debconf/* \
        /tmp/* \
        /var/tmp/*


# =============================================================================
# Desktop user
# =============================================================================

RUN set -eux; \
    if ! getent group "${USER_GID}" >/dev/null; then \
        groupadd --gid "${USER_GID}" "${USER_NAME}"; \
    fi; \
    if ! id -u "${USER_NAME}" >/dev/null 2>&1; then \
        useradd \
            --uid "${USER_UID}" \
            --gid "${USER_GID}" \
            --create-home \
            --shell /bin/bash \
            "${USER_NAME}"; \
    else \
        usermod --shell /bin/bash "${USER_NAME}"; \
    fi; \
    for group in \
        audio \
        games \
        input \
        render \
        tty \
        video; \
    do \
        getent group "${group}" >/dev/null \
            && usermod -aG "${group}" "${USER_NAME}" \
            || true; \
    done; \
    echo "${USER_NAME} ALL=(ALL:ALL) NOPASSWD: ALL" \
        > "/etc/sudoers.d/${USER_NAME}"; \
    chmod 0440 "/etc/sudoers.d/${USER_NAME}"; \
    install \
        -d \
        -o "${USER_UID}" \
        -g "${USER_GID}" \
        -m 0700 \
        /tmp/runtime-ubuntu; \
    install \
        -d \
        -o "${USER_UID}" \
        -g "${USER_GID}" \
        /home/${USER_NAME}/.config/sunshine \
        /games


# =============================================================================
# NVIDIA repository + nvidia-xconfig
#
# Only the userspace Xorg configuration utility is installed here.
# The kernel driver remains fully managed by the NVIDIA GPU Operator.
# =============================================================================

RUN curl -fsSLO \
        https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb \
    && dpkg -i cuda-keyring_1.1-1_all.deb \
    && rm -f cuda-keyring_1.1-1_all.deb \
    && apt-get update \
    && apt-get install --no-install-recommends -y \
        "nvidia-xconfig=${NVIDIA_DRIVER_PACKAGE_VERSION}" \
    && nvidia-xconfig --version \
    && apt-get clean \
    && rm -rf \
        /var/lib/apt/lists/* \
        /var/cache/apt/*


# =============================================================================
# NVIDIA Xorg driver modules
#
# Extract only the Xorg-side NVIDIA modules matching the host driver.
# Do not install the whole amd64 NVIDIA userspace stack with APT.
# =============================================================================

RUN cd /tmp \
    && apt-get update \
    && apt-get download \
        "xserver-xorg-video-nvidia-${NVIDIA_DRIVER_BRANCH}=${NVIDIA_DRIVER_PACKAGE_VERSION}" \
    && mkdir -p /tmp/nvidia-xorg \
    && dpkg-deb -x \
        "xserver-xorg-video-nvidia-${NVIDIA_DRIVER_BRANCH}_${NVIDIA_DRIVER_PACKAGE_VERSION}_amd64.deb" \
        /tmp/nvidia-xorg \
    && install -D -m 0755 \
        /tmp/nvidia-xorg/usr/lib/xorg/modules/drivers/nvidia_drv.so \
        /usr/lib/xorg/modules/drivers/nvidia_drv.so \
    && cp -a \
        /tmp/nvidia-xorg/usr/lib/xorg/modules/extensions/libglxserver_nvidia.so* \
        /usr/lib/xorg/modules/extensions/ \
    && rm -rf \
        /tmp/nvidia-xorg \
        /tmp/xserver-xorg-video-nvidia-*.deb \
        /var/lib/apt/lists/*


# =============================================================================
# NVIDIA GLVND / Vulkan configuration
#
# Actual 64-bit NVIDIA libraries are injected at runtime by the GPU Operator /
# NVIDIA Container Toolkit.
# =============================================================================

RUN printf '%s\n' \
        '/usr/local/nvidia/lib' \
        '/usr/local/nvidia/lib64' \
        > /etc/ld.so.conf.d/nvidia.conf \
    && install -d -m 0755 \
        /etc/vulkan/icd.d \
        /usr/share/glvnd/egl_vendor.d \
    && cat > /etc/vulkan/icd.d/nvidia_icd.json <<'EOF'
{
    "file_format_version": "1.0.0",
    "ICD": {
        "library_path": "libGLX_nvidia.so.0",
        "api_version": "1.3.0"
    }
}
EOF

RUN cat > /usr/share/glvnd/egl_vendor.d/10_nvidia.json <<'EOF'
{
    "file_format_version": "1.0.0",
    "ICD": {
        "library_path": "libEGL_nvidia.so.0"
    }
}
EOF


# =============================================================================
# Sunshine
# =============================================================================

COPY --from=sunshine-build /sunshine.deb /tmp/sunshine.deb

RUN apt-get update \
    && apt-get install --no-install-recommends -y \
        /tmp/sunshine.deb \
    && setcap cap_sys_admin,cap_dac_override=ep \
       /usr/bin/sunshine-2025.924.154138 \
    && rm -f /tmp/sunshine.deb \
    && apt-get clean \
    && rm -rf \
        /var/lib/apt/lists/* \
        /var/cache/apt/*

# =============================================================================
# Steam + 32-bit Linux gaming runtime
# =============================================================================

RUN dpkg --add-architecture i386 \
    && apt-get update \
    && apt-get install --no-install-recommends -y \
        ca-certificates \
        curl \
    && curl -fsSL \
        https://repo.steampowered.com/steam/archive/stable/steam.gpg \
        -o /usr/share/keyrings/steam.gpg \
    && printf '%s\n' \
        'deb [arch=amd64,i386 signed-by=/usr/share/keyrings/steam.gpg] https://repo.steampowered.com/steam/ stable steam' \
        > /etc/apt/sources.list.d/steam-bootstrap.list \
    && apt-get update \
    && apt-get install --no-install-recommends -y \
        steam-launcher \
        steam-libs-amd64 \
        steam-libs-i386 \
        libegl1:amd64 \
        libegl1:i386 \
        libgbm1:amd64 \
        libgbm1:i386 \
        libgl1:amd64 \
        libgl1:i386 \
        libgl1-mesa-dri:amd64 \
        libgl1-mesa-dri:i386 \
        libglx-mesa0:amd64 \
        libglx-mesa0:i386 \
        libvulkan1:amd64 \
        libvulkan1:i386 \
        xdg-desktop-portal \
        xdg-desktop-portal-gtk \
    && rm -f /etc/apt/sources.list.d/steam-bootstrap.list \
    && apt-get clean \
    && rm -rf \
        /var/lib/apt/lists/* \
        /var/cache/apt/*


# =============================================================================
# Non-snap Firefox
# =============================================================================

RUN install -d -m 0755 /etc/apt/keyrings \
    && curl -fsSL https://packages.mozilla.org/apt/repo-signing-key.gpg \
       -o /etc/apt/keyrings/packages.mozilla.org.asc \
    && echo "deb [signed-by=/etc/apt/keyrings/packages.mozilla.org.asc] https://packages.mozilla.org/apt mozilla main" \
       > /etc/apt/sources.list.d/mozilla.list \
    && printf '%s\n' \
       'Package: *' \
       'Pin: origin packages.mozilla.org' \
       'Pin-Priority: 1000' \
       > /etc/apt/preferences.d/mozilla \
    && apt-get update \
    && apt-get install --no-install-recommends -y \
       firefox \
       firefox-l10n-fr \
    && apt-get clean


# =============================================================================
# NVIDIA 32-bit userspace
#
# The GPU Operator currently does not provide the compat32 libraries required
# by 32-bit OpenGL applications and Proton/DXVK.
#
# Install the exact userspace version matching the host driver, then keep a
# protected copy under /opt. The NVIDIA runtime can remove/mask the files in
# /usr/lib/i386-linux-gnu when the pod starts; sunshine-entrypoint.sh restores
# them afterwards.
# =============================================================================

RUN dpkg --add-architecture i386 \
    && apt-get update \
    && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        "libnvidia-common-${NVIDIA_DRIVER_BRANCH}=${NVIDIA_DRIVER_PACKAGE_VERSION}" \
        "libnvidia-gpucomp-${NVIDIA_DRIVER_BRANCH}:i386=${NVIDIA_DRIVER_PACKAGE_VERSION}" \
        "libnvidia-decode-${NVIDIA_DRIVER_BRANCH}:i386=${NVIDIA_DRIVER_PACKAGE_VERSION}" \
        "libnvidia-compute-${NVIDIA_DRIVER_BRANCH}:i386=${NVIDIA_DRIVER_PACKAGE_VERSION}" \
        "libnvidia-gl-${NVIDIA_DRIVER_BRANCH}:i386=${NVIDIA_DRIVER_PACKAGE_VERSION}" \
    && mkdir -p /opt/nvidia-i386 \
    && for file in $( \
        dpkg -L \
            "libnvidia-gl-${NVIDIA_DRIVER_BRANCH}:i386" \
            "libnvidia-compute-${NVIDIA_DRIVER_BRANCH}:i386" \
            "libnvidia-decode-${NVIDIA_DRIVER_BRANCH}:i386" \
            "libnvidia-gpucomp-${NVIDIA_DRIVER_BRANCH}:i386" \
        | grep '^/usr/lib/i386-linux-gnu/' \
        | sort -u \
    ); do \
        if [[ -e "${file}" || -L "${file}" ]]; then \
            cp -a --parents "${file}" /opt/nvidia-i386/; \
        fi; \
    done \
    && test -e \
        /opt/nvidia-i386/usr/lib/i386-linux-gnu/libGLX_nvidia.so.0 \
    && test -e \
        "/opt/nvidia-i386/usr/lib/i386-linux-gnu/libnvidia-glcore.so.${NVIDIA_DRIVER_VERSION}" \
    && ldconfig \
    && apt-get clean \
    && rm -rf \
        /var/lib/apt/lists/* \
        /var/cache/apt/*

# Keep APT package indexes available for Steam's dependency checker.
RUN apt-get update \
    && apt-get clean

# =============================================================================
# Runtime scripts
# =============================================================================

COPY desktop-entrypoint.sh /etc/desktop-entrypoint.sh
COPY sunshine-entrypoint.sh /etc/sunshine-entrypoint.sh
COPY supervisord.conf /etc/supervisord.conf

RUN sed -i 's/\r$//' \
        /etc/desktop-entrypoint.sh \
        /etc/sunshine-entrypoint.sh \
        /etc/supervisord.conf \
    && chmod 0755 \
        /etc/desktop-entrypoint.sh \
        /etc/sunshine-entrypoint.sh \
    && chmod 0644 \
        /etc/supervisord.conf


# =============================================================================
# Final filesystem permissions
# =============================================================================

RUN chown -R \
        "${USER_UID}:${USER_GID}" \
        "/home/${USER_NAME}" \
        /tmp/runtime-ubuntu


# =============================================================================
# Sanity checks
# =============================================================================

RUN command -v \
        steam \
    && command -v \
        nvidia-xconfig \
    && command -v \
        supervisord \
    && command -v \
        pipewire \
    && command -v \
        wireplumber \
    && command -v \
        Xorg \
    && command -v \
        xfce4-session \
    && test -x \
        /etc/sunshine-entrypoint.sh \
    && test -x \
        /etc/desktop-entrypoint.sh


# =============================================================================
# Runtime
# =============================================================================

USER 1000:1000

WORKDIR /home/ubuntu

STOPSIGNAL SIGTERM

ENTRYPOINT ["/etc/sunshine-entrypoint.sh"]