#!/bin/bash -e # Source: # https://github.com/selkies-project/docker-nvidia-glx-desktop/blob/main/entrypoint.sh # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. # Make all NVIDIA GPUs visible by default export NVIDIA_VISIBLE_DEVICES=all export DEBIAN_FRONTEND=noninteractive export NVIDIA_DRIVER_CAPABILITIES=all export APPIMAGE_EXTRACT_AND_RUN=1 # System defaults that should not be changed export DISPLAY=:0 export XDG_RUNTIME_DIR=/tmp/runtime-user export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:/usr/lib/i386-linux-gnu${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} # Default environment variables (password is "mypasswd") export TZ=UTC export SIZEW=1920 export SIZEH=1080 export REFRESH=60 export DPI=96 export CDEPTH=24 export VIDEO_PORT=DFP export PASSWD=mypasswd init(){ # Start DBus without systemd sudo /etc/init.d/dbus start # Change time zone from environment variable sudo ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime && echo "$TZ" | sudo tee /etc/timezone > /dev/null # This symbolic link enables running Xorg inside a container with `-sharevts` sudo ln -snf /dev/ptmx /dev/tty7 # Allow starting Xorg from a pseudoterminal instead of strictly on a tty console if [ ! -f /etc/X11/Xwrapper.config ]; then echo -e "allowed_users=anybody\nneeds_root_rights=yes" | sudo tee /etc/X11/Xwrapper.config > /dev/null fi if grep -Fxq "allowed_users=console" /etc/X11/Xwrapper.config; then sudo sed -i "s/allowed_users=console/allowed_users=anybody/;$ a needs_root_rights=yes" /etc/X11/Xwrapper.config fi # Remove existing Xorg configuration if [ -f "/etc/X11/xorg.conf" ]; then sudo rm -f "/etc/X11/xorg.conf" fi } install_driver() { # Install NVIDIA userspace driver components including X graphic libraries if ! command -v nvidia-xconfig &> /dev/null; then # Driver version is provided by the kernel through the container toolkit export DRIVER_VERSION=$(head -n1 is easier and more intuitive than trying to find # the process ID and re-attach a shell. Additionally it prevents the main user-shell from being # monopoloized by stdout messages from supervisord andallows for additional commands to be run after # entrypoint.sh has finished. # # I will probably switch to using supervisord or docker-systemctl-replacement later as a more # stable solution after I'm done making constant changes to the project. # Starts an empty Xorg session on DDISPLAY:0 tmux new-session -d -s "xorg" tmux send-keys -t "xorg" "export DISPLAY=:0 && \ Xorg vt7 \ -noreset \ -novtswitch \ -sharevts \ -dpi ${DPI} \ +extension GLX \ +extension RANDR \ +extension RENDER \ +extension MIT-SHM ${DISPLAY}" ENTER echo "Waiting for X socket" until [ -S "/tmp/.X11-unix/X${DISPLAY/:/}" ]; do sleep 1; done echo "X socket is ready" # Start an x11vnc session that brodcasts the contents our X session tmux new-session -d -s "x11vnc" tmux send-keys -t "x11vnc" "export DISPLAY=:0 && \ sudo x11vnc -display ${DISPLAY} \ -shared \ -loop \ -repeat \ -xkb \ -snapfb \ -threads \ -xrandr resize \ -passwd "${BASIC_AUTH_PASSWORD:-$PASSWD}" \ -rfbport 5900 ${NOVNC_VIEWONLY}" ENTER # Start the no-vnc session that exposes x11vnc over websocket tmux new-session -d -s "novnc" tmux send-keys -t "novnc" "export DISPLAY=:0 && \ /opt/noVNC/utils/novnc_proxy \ --vnc localhost:5900 \ --listen 8080 \ --heartbeat 10" ENTER # Start the desktop session tmux new-session -d -s "app" tmux send-keys -t "app" "export DISPLAY=:0 && \ startxfce4" ENTER } init find_gpu install_driver create_xorg_conf start_app