selkies-project / docker-nvidia-egl-desktop

KDE Plasma Desktop container designed for Kubernetes, supporting OpenGL EGL and GLX, Vulkan, and Wine/Proton for NVIDIA GPUs through WebRTC and HTML5, providing an open-source remote cloud/HPC graphics or game streaming platform.
https://github.com/selkies-project/docker-nvidia-egl-desktop/pkgs/container/nvidia-egl-desktop
Mozilla Public License 2.0
227 stars 48 forks source link

TURN server #39

Closed hwfan closed 3 months ago

hwfan commented 3 months ago

How to set the environment variables of TURN server when the docker container is accessed through local network? In my thinking, each container should have its own TURN server, and deploy without checking the public IP, but I don't know how to implement.

hwfan commented 3 months ago

One comment: when running KasmVNC mode, Xvnc is overwhelming the CPU of my machine... I have a 64 threads CPU in the host machine, and the usage can be 70-80% when running 3D program in the container.

ehfd commented 3 months ago

How to set the environment variables of TURN server when the docker container is accessed through local network? In my thinking, each container should have its own TURN server, and deploy without checking the public IP, but I don't know how to implement it.

There is currently a TURN server inside the container, yes. But it's useless unless host networking is used because it needs to open a bunch of all sorts of ports.

If not using host networking, it needs to open relay ports (can go between 49152-65535, should be set with TURN_MIN_PORT and TURN_MAX_PORT) as well as port 3478. And the UDP ports should be opened as well.

When using local networking, you can set SELKIES_TURN_HOST explicitly and it's the IP it will use.

ehfd commented 3 months ago

One comment: when running KasmVNC mode, Xvnc is overwhelming the CPU of my machine... I have a 64 threads CPU in the host machine, and the usage can be 70-80% when running 3D program in the container.

I understand that recently, KasmVNC introduced multithreaded JPEG/WebP encoding. Do you want it to limit the number of threads it uses? I can do that.

hwfan commented 3 months ago

One comment: when running KasmVNC mode, Xvnc is overwhelming the CPU of my machine... I have a 64 threads CPU in the host machine, and the usage can be 70-80% when running 3D program in the container.

I understand that recently, KasmVNC introduced multithreaded JPEG/WebP encoding. Do you want it to limit the number of threads it uses? I can do that.

I think there is urgent need. What about expose it as an environment variable?

ehfd commented 3 months ago

When using local networking, you can set SELKIES_TURN_HOST explicitly and it's the IP it will use.

I just updated the logic in the container. Wait 10 minutes.

Check https://github.com/selkies-project/docker-nvidia-egl-desktop/blob/912c58baf6ec58f2d8f433c9e48d6ea388248bbe/selkies-gstreamer-entrypoint.sh#L33-L43 and https://github.com/selkies-project/docker-nvidia-egl-desktop/blob/912c58baf6ec58f2d8f433c9e48d6ea388248bbe/Dockerfile#L590-L609.

ehfd commented 3 months ago

For your specific use case, I advise you to set docker run --pull=always --name egl -it -d --gpus 1 --tmpfs /dev/shm:rw -e TZ=UTC -e DISPLAY_SIZEW=1920 -e DISPLAY_SIZEH=1080 -e DISPLAY_REFRESH=60 -e DISPLAY_DPI=96 -e DISPLAY_CDEPTH=24 -e PASSWD=mypasswd -e SELKIES_ENCODER=nvh264enc -e SELKIES_VIDEO_BITRATE=8000 -e SELKIES_FRAMERATE=60 -e SELKIES_AUDIO_BITRATE=128000 -e SELKIES_BASIC_AUTH_PASSWORD=mypasswd -e SELKIES_TURN_HOST=(YOUR-INTERNAL-IP) -e SELKIES_TURN_PROTOCOL=udp -e TURN_MIN_PORT=65534 -e TURN_MAX_PORT=65535 -p 3478:3478 -p 3478:3478/udp -p 8080:8080 -p 65534-65535:65534-65535 -p 65534-65535:65534-65535/udp ghcr.io/selkies-project/nvidia-egl-desktop:latest, changing as adequate.

And of course, don't collide the TURN_MIN_PORT/TURN_MAX_PORT ports. You need two ports per session.

hwfan commented 3 months ago

And of course, don't collide the ports. You need two ports per session.

Thanks so much! This project saves my life. I need to deploy multiple 3D GUI projects in one host machine, and your project is the one that matches the need for both high performance and low resource cost.

ehfd commented 3 months ago

If you have one host machine and multiple instances, don't use this approach; use coTURN standalone or at least the coTURN container, this will pay off in the long-term.

https://github.com/selkies-project/selkies-gstreamer/blob/main/docs/firewall.md

hwfan commented 3 months ago

If you have one host machine and multiple instances, don't use this approach; use coTURN standalone or at least the coTURN container.

I have two questions:

  1. If I start one container that occupy port 3478 to start TURN server, can the other containers share this server?
  2. If the TURN server cannot be shared, can we change 3478 to another port based on the port mapping logic?
ehfd commented 3 months ago

If I start one container that occupy port 3478 to start TURN server, can the other containers share this server?

The issue here is that the credentials are generated at the start inside the TURN server. You're better off using a centralized coTURN server because of this and then just expose -p 8081:8080 for one container, -p 8082:8080 for another, and so on without the -e TURN_MIN_PORT=65534 -e TURN_MAX_PORT=65535 ports.

If the TURN server cannot be shared, can we change 3478 to another port based on the port mapping logic?

The centralized TURN server running on port 3478 can be shared, as long as -e TURN_MIN_PORT=65534 -e TURN_MAX_PORT=65535 are available as many as there are sessions, two per session.

hwfan commented 3 months ago

Thanks a lot! I'll try the centralized TURN server. I sincerely like this project. ;-)

ehfd commented 3 months ago
docker run --pull=always --name coturn -it -d --rm -e TURN_SHARED_SECRET=n0TaRealCoTURNAuthSecretThatIsSixtyFourLengthsLongPlaceholdPlace -e TURN_REALM=example.com -e TURN_PORT=3478 -e TURN_MIN_PORT=65500 -e TURN_MAX_PORT=65535 -p 3478:3478 -p 3478:3478/udp -p 65500-65535:65500-65535 -p 65500-65535:65500-65535/udp ghcr.io/selkies-project/selkies-gstreamer/coturn:main

So, do something like this, still point SELKIES_TURN_HOST, SELKIES_TURN_HOST, SELKIES_TURN_SHARED_SECRET accordingly in each desktop session, and then call it a day. This way, you only have to open the web interface port for the desktop sessions.

ehfd commented 3 months ago

As for KasmVNC, the issue is here. I'll whip up something quickly.

https://github.com/kasmtech/KasmVNC/issues/154#issuecomment-1708448566

ehfd commented 3 months ago

Implemented with KASMVNC_THREADS. Tested to work.

hwfan commented 3 months ago
docker run --pull=always --name coturn -it -d --rm -e TURN_SHARED_SECRET=n0TaRealCoTURNAuthSecretThatIsSixtyFourLengthsLongPlaceholdPlace -e TURN_REALM=example.com -e TURN_PORT=3478 -e TURN_MIN_PORT=65500 -e TURN_MAX_PORT=65535 -p 3478:3478 -p 3478:3478/udp -p 65500-65535:65500-65535 -p 65500-65535:65500-65535/udp ghcr.io/selkies-project/selkies-gstreamer/coturn:main

So, do something like this, still point SELKIES_TURN_HOST, SELKIES_TURN_HOST, SELKIES_TURN_SHARED_SECRET accordingly in each desktop session, and then call it a day. This way, you only have to open the web interface port for the desktop sessions.

Thanks so much! Following your instructions, now it works for multiple instances in one machine, with the centralized TURN server. Will close this issue.