GUI Desktop
With docker-nvidia-glx-desktop or docker-nvidia-egl-desktop, users may start a GUI Desktop interface accelerated with NVIDIA GPUs. Out of the two containers, docker-nvidia-glx-desktop is generally recommended to be used because it supports Vulkan. Use docker-nvidia-egl-desktop without Vulkan support when the container must be possible to run with software acceleration fallback without GPUs, or when multiple containers have to be shared in one GPU. Please give the repositories a star!
DNS Setup
Use the command ping turn.nrp-nautilus.io
on your client (install iputils-ping
when using Linux if the ping
command does not work) to check that your DNS is correctly configured. If the latency is considerably high (over 60-70 miliseconds), consider changing your client DNS server to 8.8.8.8
and 8.8.4.4
or the DNS over HTTPS / DNS over TLS options provided by Google. CloudFlare's DNS server (addresses 1.1.1.1
and 1.0.0.1
) may show issues locating the nearest relay server, which is crucial for performance.
Usage
The below is a reference configuration xgl.yml
for docker-nvidia-glx-desktop.
apiVersion: apps/v1
kind: Deployment
metadata:
name: xgl
spec:
replicas: 1
selector:
matchLabels:
app: xgl
template:
metadata:
labels:
app: xgl
spec:
hostname: xgl
containers:
- name: xgl
image: ghcr.io/ehfd/nvidia-glx-desktop:latest
env:
- name: TZ
value: "UTC"
- name: SIZEW
value: "1920"
- name: SIZEH
value: "1080"
- name: REFRESH
value: "60"
- name: DPI
value: "96"
- name: CDEPTH
value: "24"
- name: VIDEO_PORT
value: "DP-0"
# Choose either `value:` or `secretKeyRef:` but not both at the same time
- name: PASSWD
# value: "mypasswd"
valueFrom:
secretKeyRef:
name: my-pass
key: my-pass
# Uncomment this to enable noVNC, disabing selkies-gstreamer and ignoring all its parameters except `BASIC_AUTH_PASSWORD`, which will be used for authentication with noVNC, `BASIC_AUTH_PASSWORD` also defaulting to `PASSWD` if not provided
# - name: NOVNC_ENABLE
# value: "true"
###
# selkies-gstreamer parameters, for additional configurations see lines that start with "parser.add_argument" in https://github.com/selkies-project/selkies-gstreamer/blob/master/src/selkies_gstreamer/__main__.py
###
# Change `WEBRTC_ENCODER` to `x264enc` if your GPU doesn't support `H.264 (AVCHD)` under the `NVENC - Encoding` section in https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new
- name: WEBRTC_ENCODER
value: "nvh264enc"
- name: WEBRTC_ENABLE_RESIZE
value: "false"
- name: ENABLE_AUDIO
value: "true"
- name: ENABLE_BASIC_AUTH
value: "true"
# Defaults to `PASSWD` if unspecified, choose either `value:` or `secretKeyRef:` but not both at the same time
# - name: BASIC_AUTH_PASSWORD
# value: "mypasswd"
# valueFrom:
# secretKeyRef:
# name: my-pass
# key: my-pass
###
# Uncomment below to use your TURN server with shared secret for improved network compatibility
###
- name: TURN_HOST
value: "turn.nrp-nautilus.io"
- name: TURN_PORT
value: "3478"
# Provide only `TURN_SHARED_SECRET` for time-limited shared secret authentication or both `TURN_USERNAME` and `TURN_PASSWORD` for legacy long term authentication, but do not provide both authentication methods at the same time
- name: TURN_SHARED_SECRET
valueFrom:
secretKeyRef:
name: my-pass
key: turn-secret
# - name: TURN_USERNAME
# value: "username"
# Choose either `value:` or `secretKeyRef:` but not both at the same time
# - name: TURN_PASSWORD
# value: "mypasswd"
# valueFrom:
# secretKeyRef:
# name: turn-password
# key: turn-password
stdin: true
tty: true
ports:
- name: http
containerPort: 8080
protocol: TCP
resources:
limits:
memory: 64Gi
cpu: "16"
nvidia.com/gpu: 1
requests:
memory: 100Mi
cpu: 100m
volumeMounts:
- mountPath: /dev/shm
name: dshm
- mountPath: /cache
name: xgl-cache-vol
- mountPath: /home/user
name: xgl-root-vol
dnsPolicy: None
dnsConfig:
nameservers:
- 8.8.8.8
- 8.8.4.4
volumes:
- name: dshm
emptyDir:
medium: Memory
- name: xgl-cache-vol
emptyDir: {}
# persistentVolumeClaim:
# claimName: xgl-cache-vol
- name: xgl-root-vol
emptyDir: {}
# persistentVolumeClaim:
# claimName: xgl-root-vol
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: nautilus.io/vis
operator: NotIn
values:
- suncave
# - key: topology.kubernetes.io/region
# operator: In
# values:
# - us-west
The below is a reference configuration egl.yml
for docker-nvidia-egl-desktop.
apiVersion: apps/v1
kind: Deployment
metadata:
name: egl
spec:
replicas: 1
selector:
matchLabels:
app: egl
template:
metadata:
labels:
app: egl
spec:
hostname: egl
containers:
- name: egl
image: ghcr.io/ehfd/nvidia-egl-desktop:latest
env:
- name: TZ
value: "UTC"
- name: SIZEW
value: "1920"
- name: SIZEH
value: "1080"
- name: REFRESH
value: "60"
- name: DPI
value: "96"
- name: CDEPTH
value: "24"
# Choose either `value:` or `secretKeyRef:` but not both at the same time
- name: PASSWD
# value: "mypasswd"
valueFrom:
secretKeyRef:
name: my-pass
key: my-pass
# Uncomment this to enable noVNC, disabing selkies-gstreamer and ignoring all its parameters except `BASIC_AUTH_PASSWORD`, which will be used for authentication with noVNC, `BASIC_AUTH_PASSWORD` also defaulting to `PASSWD` if not provided
# - name: NOVNC_ENABLE
# value: "true"
###
# selkies-gstreamer parameters, for additional configurations see lines that start with "parser.add_argument" in https://github.com/selkies-project/selkies-gstreamer/blob/master/src/selkies_gstreamer/__main__.py
###
# Change `WEBRTC_ENCODER` to `x264enc` if your GPU doesn't support `H.264 (AVCHD)` under the `NVENC - Encoding` section in https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new
- name: WEBRTC_ENCODER
value: "nvh264enc"
- name: WEBRTC_ENABLE_RESIZE
value: "false"
- name: ENABLE_AUDIO
value: "true"
- name: ENABLE_BASIC_AUTH
value: "true"
# Defaults to `PASSWD` if unspecified, choose either `value:` or `secretKeyRef:` but not both at the same time
# - name: BASIC_AUTH_PASSWORD
# value: "mypasswd"
# valueFrom:
# secretKeyRef:
# name: my-pass
# key: my-pass
###
# Uncomment below to use your TURN server with shared secret for improved network compatibility
###
- name: TURN_HOST
value: "turn.nrp-nautilus.io"
- name: TURN_PORT
value: "3478"
# Provide only `TURN_SHARED_SECRET` for time-limited shared secret authentication or both `TURN_USERNAME` and `TURN_PASSWORD` for legacy long term authentication, but do not provide both authentication methods at the same time
- name: TURN_SHARED_SECRET
valueFrom:
secretKeyRef:
name: my-pass
key: turn-secret
# - name: TURN_USERNAME
# value: "username"
# Choose either `value:` or `secretKeyRef:` but not both at the same time
# - name: TURN_PASSWORD
# value: "mypasswd"
# valueFrom:
# secretKeyRef:
# name: turn-password
# key: turn-password
stdin: true
tty: true
ports:
- name: http
containerPort: 8080
protocol: TCP
resources:
limits:
memory: 64Gi
cpu: "16"
nvidia.com/gpu: 1
requests:
memory: 100Mi
cpu: 100m
volumeMounts:
- mountPath: /dev/shm
name: dshm
- mountPath: /cache
name: egl-cache-vol
- mountPath: /home/user
name: egl-root-vol
dnsPolicy: None
dnsConfig:
nameservers:
- 8.8.8.8
- 8.8.4.4
volumes:
- name: dshm
emptyDir:
medium: Memory
- name: egl-cache-vol
emptyDir: {}
# persistentVolumeClaim:
# claimName: egl-cache-vol
- name: egl-root-vol
emptyDir: {}
# persistentVolumeClaim:
# claimName: egl-root-vol
# affinity:
# nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# nodeSelectorTerms:
# - matchExpressions:
# - key: topology.kubernetes.io/region
# operator: In
# values:
# - us-west
Customization
value:
and valueFrom
must not exist at the same time. Comment out emptyDir: {}
and uncomment persistentVolumeClaim:
, then changing claimName:
after uncommenting to the name of your PVC (rook-ceph-block
, rook-ceph-block-east
, or rook-ceph-block-pacific
is the recommended StorageClass depending on your server location). Refer to the POSIX section for more information.
Check the README.md
of both GitHub repositories docker-nvidia-glx-desktop or docker-nvidia-egl-desktop for more details on configuration customization. Please give the repositories a star too!
Secret Generation
Before generating the Kubernetes secret, receive the TURN Shared Secret by asking in the Nautilus Support Matrix Chatroom, and replace TURN_SHARED_SECRET
to the value that you have received. Replace YOUR_PASSWORD
with the password for the container that you intend to use. If you want to use a different name instead of my-pass
or turn-secret
, make sure to update the above xgl.yml
or egl.yml
files as well as the below command. The first my-pass
is the name of the secret, and the second my-pass
right after --from-literal=
and turn-secret
are the keys.
After customizing, run the below command in edited form:
kubectl create secret generic my-pass --from-literal=my-pass=YOUR_PASSWORD --from-literal=turn-secret=TURN_SHARED_SECRET
Container Start
After saving and editing the reference configuration, run either of these commands to start the container depending on the type of your container:
kubectl create -f xgl.yml
kubectl create -f egl.yml
Exposing the Container
The below reference configuration xgl-ingress.yml
is to expose your docker-nvidia-glx-desktop container to the *.nrp-nautilus.io
endpoint. Replace YOUR_ENDPOINT
to the subdomain you want to use. You can just use kubectl port-forward deployment/xgl 8080:8080
and access localhost:8080, but this will have higher latency.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: haproxy
name: xgl
spec:
rules:
- host: YOUR_ENDPOINT.nrp-nautilus.io
http:
paths:
- backend:
service:
name: xgl
port:
name: http
path: /
pathType: ImplementationSpecific
tls:
- hosts:
- YOUR_ENDPOINT.nrp-nautilus.io
---
apiVersion: v1
kind: Service
metadata:
name: xgl
labels:
app: xgl
spec:
selector:
app: xgl
ports:
- name: http
protocol: TCP
port: 8080
Run the below command after saving the changed reference configuration file:
kubectl create -f xgl-ingress.yml
Access YOUR_ENDPOINT.nrp-nautilus.io
with your web browser.
The below reference configuration egl-ingress.yml
is to expose your docker-nvidia-egl-desktop container to the *.nrp-nautilus.io
endpoint. Replace YOUR_ENDPOINT
to the subdomain you want to use. You can just use kubectl port-forward deployment/egl 8080:8080
and access localhost:8080, but this will have higher latency.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: haproxy
name: egl
spec:
rules:
- host: YOUR_ENDPOINT.nrp-nautilus.io
http:
paths:
- backend:
service:
name: egl
port:
name: http
path: /
pathType: ImplementationSpecific
tls:
- hosts:
- YOUR_ENDPOINT.nrp-nautilus.io
---
apiVersion: v1
kind: Service
metadata:
name: egl
labels:
app: egl
spec:
selector:
app: egl
ports:
- name: http
protocol: TCP
port: 8080
Run the below command after saving the changed reference configuration file:
kubectl create -f egl-ingress.yml
Access YOUR_ENDPOINT.nrp-nautilus.io
with your web browser. The user name is "user" without the quotes and the password is the my-pass
secret that you have set.
Container Customization
You can import either https://github.com/ehfd/docker-nvidia-glx-desktop.git
or https://github.com/ehfd/docker-nvidia-egl-desktop.git
by importing with Repo by URL from https://gitlab.nrp-nautilus.io/projects/new#import_project. Refer to Building in GitLab on how you can change and build your own customized container.
Please use the below .gitlab-ci.yml
file to build the container on GitLab and push to the container repository (set UBUNTU_RELEASE
to any supported Ubuntu LTS release):
image: gcr.io/kaniko-project/executor:debug
stages:
- build-and-push
build-and-push-job:
stage: build-and-push
script:
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
- /kaniko/executor --use-new-run=true --snapshotMode=redo --cache=true --push-retry=10 --build-arg=UBUNTU_RELEASE=20.04 --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE:${CI_COMMIT_SHA:0:8} --destination $CI_REGISTRY_IMAGE:latest
Again, please give both docker-nvidia-glx-desktop and docker-nvidia-egl-desktop a star if the containers were useful to you.