Dockerfile 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. # syntax=docker/dockerfile:1.7
  2. # =============================================================================
  3. # Versions
  4. # =============================================================================
  5. ARG SUNSHINE_VERSION=v2025.924.154138
  6. # Update these values whenever the NVIDIA GPU Operator driver changes.
  7. ARG NVIDIA_DRIVER_BRANCH=580
  8. ARG NVIDIA_DRIVER_VERSION=580.126.20
  9. ARG NVIDIA_DRIVER_PACKAGE_VERSION=580.126.20-1ubuntu1
  10. # =============================================================================
  11. # Sunshine package source
  12. # =============================================================================
  13. FROM ghcr.io/lizardbyte/sunshine:${SUNSHINE_VERSION}-ubuntu-24.04 AS sunshine
  14. # =============================================================================
  15. # Main image
  16. # =============================================================================
  17. FROM docker.io/library/ubuntu:24.04
  18. ARG NVIDIA_DRIVER_BRANCH
  19. ARG NVIDIA_DRIVER_VERSION
  20. ARG NVIDIA_DRIVER_PACKAGE_VERSION
  21. ARG USER_NAME=ubuntu
  22. ARG USER_UID=1000
  23. ARG USER_GID=1000
  24. ENV DEBIAN_FRONTEND=noninteractive \
  25. HOME=/home/ubuntu \
  26. USER=ubuntu \
  27. DISPLAY=:20 \
  28. DISPLAY_SIZEW=1920 \
  29. DISPLAY_SIZEH=1080 \
  30. DISPLAY_REFRESH=120 \
  31. DISPLAY_DPI=96 \
  32. DISPLAY_CDEPTH=24 \
  33. VIDEO_PORT=HDMI-0 \
  34. TZ=Europe/Paris \
  35. LANG=fr_FR.UTF-8 \
  36. LANGUAGE=fr_FR:fr \
  37. LC_ALL=fr_FR.UTF-8 \
  38. XDG_RUNTIME_DIR=/tmp/runtime-ubuntu \
  39. PIPEWIRE_RUNTIME_DIR=/tmp/runtime-ubuntu \
  40. PULSE_RUNTIME_PATH=/tmp/runtime-ubuntu/pulse \
  41. PULSE_SERVER=unix:/tmp/runtime-ubuntu/pulse/native \
  42. NVIDIA_VISIBLE_DEVICES=all \
  43. NVIDIA_DRIVER_CAPABILITIES=all \
  44. EXPECTED_NVIDIA_DRIVER_VERSION=${NVIDIA_DRIVER_VERSION} \
  45. NVIDIA_I386_PACKAGE_VERSION=${NVIDIA_DRIVER_PACKAGE_VERSION}
  46. SHELL ["/bin/bash", "-o", "pipefail", "-c"]
  47. USER root
  48. # =============================================================================
  49. # Base desktop / gaming environment
  50. # =============================================================================
  51. RUN dpkg --add-architecture i386 \
  52. && apt-get update \
  53. && apt-get install --no-install-recommends -y \
  54. btop fonts-noto-cjk fonts-ubuntu mousepad nano ristretto thunar \
  55. ubuntu-wallpapers \
  56. adwaita-icon-theme \
  57. elementary-xfce-icon-theme \
  58. greybird-gtk-theme \
  59. hicolor-icon-theme \
  60. humanity-icon-theme \
  61. keyboard-configuration \
  62. tango-icon-theme \
  63. xfce4-goodies \
  64. xfce4-notifyd \
  65. xfce4-pulseaudio-plugin \
  66. xfonts-base \
  67. xfonts-scalable \
  68. alsa-utils \
  69. ca-certificates \
  70. curl \
  71. dbus \
  72. dbus-user-session \
  73. dbus-x11 \
  74. file \
  75. fonts-dejavu \
  76. fonts-liberation \
  77. fonts-noto \
  78. fonts-noto-color-emoji \
  79. kmod \
  80. libasound2-plugins \
  81. libcap2-bin \
  82. libegl1 \
  83. libgbm1 \
  84. libgl1 \
  85. libglvnd0 \
  86. libglx0 \
  87. libpciaccess0 \
  88. libpulse0 \
  89. libvulkan1 \
  90. libx11-6 \
  91. libx11-xcb1 \
  92. libxdamage1 \
  93. libxext6 \
  94. libxfixes3 \
  95. libxinerama1 \
  96. libxrandr2 \
  97. libxss1 \
  98. libxtst6 \
  99. locales \
  100. mesa-utils \
  101. pciutils \
  102. pipewire \
  103. pipewire-pulse \
  104. procps \
  105. psmisc \
  106. pulseaudio-utils \
  107. sudo \
  108. supervisor \
  109. tzdata \
  110. udev \
  111. vulkan-tools \
  112. wireplumber \
  113. x11-utils \
  114. x11-xserver-utils \
  115. xauth \
  116. xcvt \
  117. xdg-user-dirs \
  118. xdg-utils \
  119. xfce4 \
  120. xfce4-terminal \
  121. xkb-data \
  122. xserver-xorg-core \
  123. xserver-xorg-input-libinput \
  124. xserver-xorg-legacy \
  125. xz-utils \
  126. && sed -i \
  127. -e 's/^# *fr_FR.UTF-8 UTF-8/fr_FR.UTF-8 UTF-8/' \
  128. -e 's/^# *en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' \
  129. /etc/locale.gen \
  130. && locale-gen \
  131. && apt-get clean \
  132. && rm -rf \
  133. /var/lib/apt/lists/* \
  134. /var/cache/apt/* \
  135. /var/cache/debconf/* \
  136. /tmp/* \
  137. /var/tmp/*
  138. # =============================================================================
  139. # Desktop user
  140. # =============================================================================
  141. RUN set -eux; \
  142. if ! getent group "${USER_GID}" >/dev/null; then \
  143. groupadd --gid "${USER_GID}" "${USER_NAME}"; \
  144. fi; \
  145. if ! id -u "${USER_NAME}" >/dev/null 2>&1; then \
  146. useradd \
  147. --uid "${USER_UID}" \
  148. --gid "${USER_GID}" \
  149. --create-home \
  150. --shell /bin/bash \
  151. "${USER_NAME}"; \
  152. else \
  153. usermod --shell /bin/bash "${USER_NAME}"; \
  154. fi; \
  155. for group in \
  156. audio \
  157. games \
  158. input \
  159. render \
  160. sudo \
  161. tty \
  162. video; \
  163. do \
  164. getent group "${group}" >/dev/null \
  165. && usermod -aG "${group}" "${USER_NAME}" \
  166. || true; \
  167. done; \
  168. echo "${USER_NAME} ALL=(ALL:ALL) NOPASSWD: ALL" \
  169. > "/etc/sudoers.d/${USER_NAME}"; \
  170. chmod 0440 "/etc/sudoers.d/${USER_NAME}"; \
  171. install \
  172. -d \
  173. -o "${USER_UID}" \
  174. -g "${USER_GID}" \
  175. -m 0700 \
  176. /tmp/runtime-ubuntu; \
  177. install \
  178. -d \
  179. -o "${USER_UID}" \
  180. -g "${USER_GID}" \
  181. /home/${USER_NAME}/.config/sunshine \
  182. /games
  183. # =============================================================================
  184. # NVIDIA repository + nvidia-xconfig
  185. #
  186. # Only the userspace Xorg configuration utility is installed here.
  187. # The kernel driver remains fully managed by the NVIDIA GPU Operator.
  188. # =============================================================================
  189. RUN curl -fsSLO \
  190. https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb \
  191. && dpkg -i cuda-keyring_1.1-1_all.deb \
  192. && rm -f cuda-keyring_1.1-1_all.deb \
  193. && apt-get update \
  194. && apt-get install --no-install-recommends -y \
  195. "nvidia-xconfig=${NVIDIA_DRIVER_PACKAGE_VERSION}" \
  196. && nvidia-xconfig --version \
  197. && apt-get clean \
  198. && rm -rf \
  199. /var/lib/apt/lists/* \
  200. /var/cache/apt/*
  201. # =============================================================================
  202. # NVIDIA Xorg driver modules
  203. #
  204. # Extract only the Xorg-side NVIDIA modules matching the host driver.
  205. # Do not install the whole amd64 NVIDIA userspace stack with APT.
  206. # =============================================================================
  207. RUN cd /tmp \
  208. && apt-get update \
  209. && apt-get download \
  210. "xserver-xorg-video-nvidia-${NVIDIA_DRIVER_BRANCH}=${NVIDIA_DRIVER_PACKAGE_VERSION}" \
  211. && mkdir -p /tmp/nvidia-xorg \
  212. && dpkg-deb -x \
  213. "xserver-xorg-video-nvidia-${NVIDIA_DRIVER_BRANCH}_${NVIDIA_DRIVER_PACKAGE_VERSION}_amd64.deb" \
  214. /tmp/nvidia-xorg \
  215. && install -D -m 0755 \
  216. /tmp/nvidia-xorg/usr/lib/xorg/modules/drivers/nvidia_drv.so \
  217. /usr/lib/xorg/modules/drivers/nvidia_drv.so \
  218. && cp -a \
  219. /tmp/nvidia-xorg/usr/lib/xorg/modules/extensions/libglxserver_nvidia.so* \
  220. /usr/lib/xorg/modules/extensions/ \
  221. && rm -rf \
  222. /tmp/nvidia-xorg \
  223. /tmp/xserver-xorg-video-nvidia-*.deb \
  224. /var/lib/apt/lists/*
  225. # =============================================================================
  226. # NVIDIA GLVND / Vulkan configuration
  227. #
  228. # Actual 64-bit NVIDIA libraries are injected at runtime by the GPU Operator /
  229. # NVIDIA Container Toolkit.
  230. # =============================================================================
  231. RUN printf '%s\n' \
  232. '/usr/local/nvidia/lib' \
  233. '/usr/local/nvidia/lib64' \
  234. > /etc/ld.so.conf.d/nvidia.conf \
  235. && install -d -m 0755 \
  236. /etc/vulkan/icd.d \
  237. /usr/share/glvnd/egl_vendor.d \
  238. && cat > /etc/vulkan/icd.d/nvidia_icd.json <<'EOF'
  239. {
  240. "file_format_version": "1.0.0",
  241. "ICD": {
  242. "library_path": "libGLX_nvidia.so.0",
  243. "api_version": "1.3.0"
  244. }
  245. }
  246. EOF
  247. RUN cat > /usr/share/glvnd/egl_vendor.d/10_nvidia.json <<'EOF'
  248. {
  249. "file_format_version": "1.0.0",
  250. "ICD": {
  251. "library_path": "libEGL_nvidia.so.0"
  252. }
  253. }
  254. EOF
  255. # =============================================================================
  256. # Sunshine
  257. # =============================================================================
  258. COPY --from=sunshine /sunshine.deb /tmp/sunshine.deb
  259. RUN apt-get update \
  260. && apt-get install --no-install-recommends -y \
  261. /tmp/sunshine.deb \
  262. && setcap cap_sys_admin,cap_dac_override=ep \
  263. /usr/bin/sunshine-2025.924.154138 \
  264. && rm -f /tmp/sunshine.deb \
  265. && apt-get clean \
  266. && rm -rf \
  267. /var/lib/apt/lists/* \
  268. /var/cache/apt/*
  269. # =============================================================================
  270. # Steam + 32-bit Linux gaming runtime
  271. # =============================================================================
  272. RUN dpkg --add-architecture i386 \
  273. && apt-get update \
  274. && apt-get install --no-install-recommends -y \
  275. ca-certificates \
  276. curl \
  277. && curl -fsSL \
  278. https://repo.steampowered.com/steam/archive/stable/steam.gpg \
  279. -o /usr/share/keyrings/steam.gpg \
  280. && printf '%s\n' \
  281. 'deb [arch=amd64,i386 signed-by=/usr/share/keyrings/steam.gpg] https://repo.steampowered.com/steam/ stable steam' \
  282. > /etc/apt/sources.list.d/steam-bootstrap.list \
  283. && apt-get update \
  284. && apt-get install --no-install-recommends -y \
  285. steam-launcher \
  286. steam-libs-amd64 \
  287. steam-libs-i386 \
  288. libegl1:amd64 \
  289. libegl1:i386 \
  290. libgbm1:amd64 \
  291. libgbm1:i386 \
  292. libgl1:amd64 \
  293. libgl1:i386 \
  294. libgl1-mesa-dri:amd64 \
  295. libgl1-mesa-dri:i386 \
  296. libglx-mesa0:amd64 \
  297. libglx-mesa0:i386 \
  298. libvulkan1:amd64 \
  299. libvulkan1:i386 \
  300. xdg-desktop-portal \
  301. xdg-desktop-portal-gtk \
  302. && rm -f /etc/apt/sources.list.d/steam-bootstrap.list \
  303. && apt-get clean \
  304. && rm -rf \
  305. /var/lib/apt/lists/* \
  306. /var/cache/apt/*
  307. # =============================================================================
  308. # Non-snap Firefox
  309. # =============================================================================
  310. RUN install -d -m 0755 /etc/apt/keyrings \
  311. && curl -fsSL https://packages.mozilla.org/apt/repo-signing-key.gpg \
  312. -o /etc/apt/keyrings/packages.mozilla.org.asc \
  313. && echo "deb [signed-by=/etc/apt/keyrings/packages.mozilla.org.asc] https://packages.mozilla.org/apt mozilla main" \
  314. > /etc/apt/sources.list.d/mozilla.list \
  315. && printf '%s\n' \
  316. 'Package: *' \
  317. 'Pin: origin packages.mozilla.org' \
  318. 'Pin-Priority: 1000' \
  319. > /etc/apt/preferences.d/mozilla \
  320. && apt-get update \
  321. && apt-get install --no-install-recommends -y \
  322. firefox \
  323. firefox-l10n-fr \
  324. && apt-get clean
  325. # =============================================================================
  326. # NVIDIA 32-bit userspace
  327. #
  328. # The GPU Operator currently does not provide the compat32 libraries required
  329. # by 32-bit OpenGL applications and Proton/DXVK.
  330. #
  331. # Install the exact userspace version matching the host driver, then keep a
  332. # protected copy under /opt. The NVIDIA runtime can remove/mask the files in
  333. # /usr/lib/i386-linux-gnu when the pod starts; sunshine-entrypoint.sh restores
  334. # them afterwards.
  335. # =============================================================================
  336. RUN dpkg --add-architecture i386 \
  337. && apt-get update \
  338. && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
  339. "libnvidia-common-${NVIDIA_DRIVER_BRANCH}=${NVIDIA_DRIVER_PACKAGE_VERSION}" \
  340. "libnvidia-gpucomp-${NVIDIA_DRIVER_BRANCH}:i386=${NVIDIA_DRIVER_PACKAGE_VERSION}" \
  341. "libnvidia-decode-${NVIDIA_DRIVER_BRANCH}:i386=${NVIDIA_DRIVER_PACKAGE_VERSION}" \
  342. "libnvidia-compute-${NVIDIA_DRIVER_BRANCH}:i386=${NVIDIA_DRIVER_PACKAGE_VERSION}" \
  343. "libnvidia-gl-${NVIDIA_DRIVER_BRANCH}:i386=${NVIDIA_DRIVER_PACKAGE_VERSION}" \
  344. && mkdir -p /opt/nvidia-i386 \
  345. && for file in $( \
  346. dpkg -L \
  347. "libnvidia-gl-${NVIDIA_DRIVER_BRANCH}:i386" \
  348. "libnvidia-compute-${NVIDIA_DRIVER_BRANCH}:i386" \
  349. "libnvidia-decode-${NVIDIA_DRIVER_BRANCH}:i386" \
  350. "libnvidia-gpucomp-${NVIDIA_DRIVER_BRANCH}:i386" \
  351. | grep '^/usr/lib/i386-linux-gnu/' \
  352. | sort -u \
  353. ); do \
  354. if [[ -e "${file}" || -L "${file}" ]]; then \
  355. cp -a --parents "${file}" /opt/nvidia-i386/; \
  356. fi; \
  357. done \
  358. && test -e \
  359. /opt/nvidia-i386/usr/lib/i386-linux-gnu/libGLX_nvidia.so.0 \
  360. && test -e \
  361. "/opt/nvidia-i386/usr/lib/i386-linux-gnu/libnvidia-glcore.so.${NVIDIA_DRIVER_VERSION}" \
  362. && ldconfig \
  363. && apt-get clean \
  364. && rm -rf \
  365. /var/lib/apt/lists/* \
  366. /var/cache/apt/*
  367. # Keep APT package indexes available for Steam's dependency checker.
  368. RUN apt-get update \
  369. && apt-get clean
  370. # =============================================================================
  371. # Runtime scripts
  372. # =============================================================================
  373. COPY desktop-entrypoint.sh /etc/desktop-entrypoint.sh
  374. COPY sunshine-entrypoint.sh /etc/sunshine-entrypoint.sh
  375. COPY supervisord.conf /etc/supervisord.conf
  376. RUN sed -i 's/\r$//' \
  377. /etc/desktop-entrypoint.sh \
  378. /etc/sunshine-entrypoint.sh \
  379. /etc/supervisord.conf \
  380. && chmod 0755 \
  381. /etc/desktop-entrypoint.sh \
  382. /etc/sunshine-entrypoint.sh \
  383. && chmod 0644 \
  384. /etc/supervisord.conf
  385. # =============================================================================
  386. # Final filesystem permissions
  387. # =============================================================================
  388. RUN chown -R \
  389. "${USER_UID}:${USER_GID}" \
  390. "/home/${USER_NAME}" \
  391. /tmp/runtime-ubuntu
  392. # =============================================================================
  393. # Sanity checks
  394. # =============================================================================
  395. RUN command -v \
  396. steam \
  397. && command -v \
  398. nvidia-xconfig \
  399. && command -v \
  400. supervisord \
  401. && command -v \
  402. pipewire \
  403. && command -v \
  404. wireplumber \
  405. && command -v \
  406. Xorg \
  407. && command -v \
  408. xfce4-session \
  409. && test -x \
  410. /etc/sunshine-entrypoint.sh \
  411. && test -x \
  412. /etc/desktop-entrypoint.sh
  413. # =============================================================================
  414. # Runtime
  415. # =============================================================================
  416. USER 1000:1000
  417. WORKDIR /home/ubuntu
  418. STOPSIGNAL SIGTERM
  419. ENTRYPOINT ["/etc/sunshine-entrypoint.sh"]