entrypoint.sh 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #!/bin/bash -e
  2. # This Source Code Form is subject to the terms of the Mozilla Public
  3. # License, v. 2.0. If a copy of the MPL was not distributed with this
  4. # file, You can obtain one at https://mozilla.org/MPL/2.0/.
  5. trap "echo TRAPed signal" HUP INT QUIT TERM
  6. # Create and modify permissions of XDG_RUNTIME_DIR
  7. sudo -u user mkdir -pm700 /tmp/runtime-user
  8. sudo chown user:user /tmp/runtime-user
  9. sudo -u user chmod 700 /tmp/runtime-user
  10. # Make user directory owned by the user in case it is not
  11. sudo chown user:user /home/user
  12. # Change operating system password to environment variable
  13. echo "user:$PASSWD" | sudo chpasswd
  14. # Remove directories to make sure the desktop environment starts
  15. sudo rm -rf /tmp/.X* ~/.cache
  16. # Change time zone from environment variable
  17. sudo ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime && echo "$TZ" | sudo tee /etc/timezone > /dev/null
  18. # Add game directories for Lutris to path
  19. export PATH="${PATH}:/usr/local/games:/usr/games"
  20. # Add LibreOffice to library path
  21. export LD_LIBRARY_PATH="/usr/lib/libreoffice/program:${LD_LIBRARY_PATH}"
  22. # This symbolic link enables running Xorg inside a container with `-sharevts`
  23. sudo ln -snf /dev/ptmx /dev/tty7
  24. # Configure environment for selkies-gstreamer utilities
  25. source /opt/gstreamer/gst-env
  26. # Install NVIDIA userspace driver components including X graphic libraries
  27. if ! command -v nvidia-xconfig &> /dev/null; then
  28. # Driver version is provided by the kernel through the container toolkit
  29. export DRIVER_VERSION=$(head -n1 </proc/driver/nvidia/version | awk '{print $8}')
  30. cd /tmp
  31. # If version is different, new installer will overwrite the existing components
  32. if [ ! -f "/tmp/NVIDIA-Linux-x86_64-$DRIVER_VERSION.run" ]; then
  33. # Check multiple sources in order to probe both consumer and datacenter driver versions
  34. curl -fsL -O "https://us.download.nvidia.com/XFree86/Linux-x86_64/$DRIVER_VERSION/NVIDIA-Linux-x86_64-$DRIVER_VERSION.run" || curl -fsL -O "https://us.download.nvidia.com/tesla/$DRIVER_VERSION/NVIDIA-Linux-x86_64-$DRIVER_VERSION.run" || { echo "Failed NVIDIA GPU driver download. Exiting."; exit 1; }
  35. fi
  36. # Extract installer before installing
  37. sudo sh "NVIDIA-Linux-x86_64-$DRIVER_VERSION.run" -x
  38. cd "NVIDIA-Linux-x86_64-$DRIVER_VERSION"
  39. # Run installation without the kernel modules and host components
  40. sudo ./nvidia-installer --silent \
  41. --no-kernel-module \
  42. --install-compat32-libs \
  43. --no-nouveau-check \
  44. --no-nvidia-modprobe \
  45. --no-rpms \
  46. --no-backup \
  47. --no-check-for-alternate-installs
  48. sudo rm -rf /tmp/NVIDIA* && cd ~
  49. fi
  50. # Allow starting Xorg from a pseudoterminal instead of strictly on a tty console
  51. if [ ! -f /etc/X11/Xwrapper.config ]; then
  52. echo -e "allowed_users=anybody\nneeds_root_rights=yes" | sudo tee /etc/X11/Xwrapper.config > /dev/null
  53. fi
  54. if grep -Fxq "allowed_users=console" /etc/X11/Xwrapper.config; then
  55. sudo sed -i "s/allowed_users=console/allowed_users=anybody/;$ a needs_root_rights=yes" /etc/X11/Xwrapper.config
  56. fi
  57. # Remove existing Xorg configuration
  58. if [ -f "/etc/X11/xorg.conf" ]; then
  59. sudo rm -f "/etc/X11/xorg.conf"
  60. fi
  61. # Get first GPU device if all devices are available or `NVIDIA_VISIBLE_DEVICES` is not set
  62. if [ "$NVIDIA_VISIBLE_DEVICES" == "all" ]; then
  63. export GPU_SELECT=$(sudo nvidia-smi --query-gpu=uuid --format=csv | sed -n 2p)
  64. elif [ -z "$NVIDIA_VISIBLE_DEVICES" ]; then
  65. export GPU_SELECT=$(sudo nvidia-smi --query-gpu=uuid --format=csv | sed -n 2p)
  66. # Get first GPU device out of the visible devices in other situations
  67. else
  68. export GPU_SELECT=$(sudo nvidia-smi --id=$(echo "$NVIDIA_VISIBLE_DEVICES" | cut -d ',' -f1) --query-gpu=uuid --format=csv | sed -n 2p)
  69. if [ -z "$GPU_SELECT" ]; then
  70. export GPU_SELECT=$(sudo nvidia-smi --query-gpu=uuid --format=csv | sed -n 2p)
  71. fi
  72. fi
  73. if [ -z "$GPU_SELECT" ]; then
  74. echo "No NVIDIA GPUs detected or nvidia-container-toolkit not configured. Exiting."
  75. exit 1
  76. fi
  77. # Setting `VIDEO_PORT` to none disables RANDR/XRANDR, do not set this if using datacenter GPUs
  78. if [ "${VIDEO_PORT,,}" = "none" ]; then
  79. export CONNECTED_MONITOR="--use-display-device=None"
  80. # The X server is otherwise deliberately set to a specific video port despite not being plugged to enable RANDR/XRANDR, monitor will display the screen if plugged to the specific port
  81. else
  82. export CONNECTED_MONITOR="--connected-monitor=${VIDEO_PORT}"
  83. fi
  84. # Bus ID from nvidia-smi is in hexadecimal format, should be converted to decimal format which Xorg understands, required because nvidia-xconfig doesn't work as intended in a container
  85. HEX_ID=$(sudo nvidia-smi --query-gpu=pci.bus_id --id="$GPU_SELECT" --format=csv | sed -n 2p)
  86. IFS=":." ARR_ID=($HEX_ID)
  87. unset IFS
  88. BUS_ID=PCI:$((16#${ARR_ID[1]})):$((16#${ARR_ID[2]})):$((16#${ARR_ID[3]}))
  89. # A custom modeline should be generated because there is no monitor to fetch this information normally
  90. export MODELINE=$(cvt -r "${SIZEW}" "${SIZEH}" "${REFRESH}" | sed -n 2p)
  91. # Generate /etc/X11/xorg.conf with nvidia-xconfig
  92. sudo nvidia-xconfig --virtual="${SIZEW}x${SIZEH}" --depth="$CDEPTH" --mode=$(echo "$MODELINE" | awk '{print $2}' | tr -d '"') --allow-empty-initial-configuration --no-probe-all-gpus --busid="$BUS_ID" --no-multigpu --no-sli --no-base-mosaic --only-one-x-screen ${CONNECTED_MONITOR}
  93. # Guarantee that the X server starts without a monitor by adding more options to the configuration
  94. sudo sed -i '/Driver\s\+"nvidia"/a\ Option "ModeValidation" "NoMaxPClkCheck, NoEdidMaxPClkCheck, NoMaxSizeCheck, NoHorizSyncCheck, NoVertRefreshCheck, NoVirtualSizeCheck, NoExtendedGpuCapabilitiesCheck, NoTotalSizeCheck, NoDualLinkDVICheck, NoDisplayPortBandwidthCheck, AllowNon3DVisionModes, AllowNonHDMI3DModes, AllowNonEdidModes, NoEdidHDMI2Check, AllowDpInterlaced"\n Option "HardDPMS" "False"' /etc/X11/xorg.conf
  95. # Add custom generated modeline to the configuration
  96. sudo sed -i '/Section\s\+"Monitor"/a\ '"$MODELINE" /etc/X11/xorg.conf
  97. # Prevent interference between GPUs, add this to the host or other containers running Xorg as well
  98. echo -e "Section \"ServerFlags\"\n Option \"AutoAddGPU\" \"false\"\nEndSection" | sudo tee -a /etc/X11/xorg.conf > /dev/null
  99. # Default display is :0 across the container
  100. export DISPLAY=":0"
  101. # Run Xorg server with required extensions
  102. Xorg vt7 -noreset -novtswitch -sharevts -dpi "${DPI}" +extension "GLX" +extension "RANDR" +extension "RENDER" +extension "MIT-SHM" "${DISPLAY}" &
  103. # Wait for X11 to start
  104. echo "Waiting for X socket"
  105. until [ -S "/tmp/.X11-unix/X${DISPLAY/:/}" ]; do sleep 1; done
  106. echo "X socket is ready"
  107. # Run the x11vnc + noVNC fallback web interface if enabled
  108. if [ "${NOVNC_ENABLE,,}" = "true" ]; then
  109. if [ -n "$NOVNC_VIEWPASS" ]; then export NOVNC_VIEWONLY="-viewpasswd ${NOVNC_VIEWPASS}"; else unset NOVNC_VIEWONLY; fi
  110. x11vnc -display "${DISPLAY}" -passwd "${BASIC_AUTH_PASSWORD:-$PASSWD}" -shared -forever -repeat -xkb -snapfb -threads -xrandr "resize" -rfbport 5900 ${NOVNC_VIEWONLY} &
  111. /opt/noVNC/utils/novnc_proxy --vnc localhost:5900 --listen 8080 --heartbeat 10 &
  112. fi
  113. # Start KDE desktop environment
  114. /usr/bin/dbus-launch /usr/bin/startplasma-x11 &
  115. # Add custom processes right below this line, or within `supervisord.conf` to perform service management similar to systemd
  116. echo "Session Running. Press [Return] to exit."
  117. read