Add a Nginx reverse proxy to combine all the used ports into one single port

This will allow this web UI to sit nicely behind a reverse proxy.

Dynamically set the ports used for the
- VNC service
- noVNC service
- Pulseaudio socket
- VNC audio transport websocket

Remove all mentions of the above used ports in the Dockerfile.
This commit is contained in:
Josh.5
2022-09-17 23:28:52 +12:00
committed by Josh Sunnex
parent 38d9442c7d
commit 6340f4113e
8 changed files with 121 additions and 29 deletions

View File

@@ -254,8 +254,18 @@ RUN \
&& sed -i '/ document.title =/c\ document.title = "Steam Headless - noVNC";' \
/opt/noVNC/app/ui.js \
&& \
echo "**** Update apt database ****" \
&& apt-get update \
&& \
echo "**** Install nginx support ****" \
&& apt-get install -y \
nginx \
&& \
echo "**** Section cleanup ****" \
&& apt-get clean autoclean -y \
&& apt-get autoremove -y \
&& rm -rf \
/var/lib/apt/lists/* \
/tmp/noVNC* \
/tmp/novnc.tar.gz
@@ -464,18 +474,12 @@ ENV \
# Configure required ports
ENV \
PORT_SSH="2222" \
PORT_VNC="5900" \
PORT_AUDIO_STREAM="5901" \
PORT_NOVNC_WEB="8083" \
PORT_AUDIO_WEBSOCKET="32123" \
NEKO_NAT1TO1=""
# Expose the required ports
EXPOSE 2222
EXPOSE 5900
EXPOSE 5901
EXPOSE 8083
EXPOSE 32123
# Set entrypoint
RUN chmod +x /entrypoint.sh

View File

@@ -194,6 +194,7 @@ RUN \
echo
# Install noVNC
# TODO: Add nginx
ARG NOVNC_VERSION=1.2.0
RUN \
echo "**** Fetch noVNC ****" \
@@ -415,17 +416,11 @@ ENV \
# Configure required ports
ENV \
PORT_SSH="2222" \
PORT_VNC="5900" \
PORT_AUDIO_STREAM="5901" \
PORT_NOVNC_WEB="8083" \
PORT_AUDIO_WEBSOCKET="32123"
PORT_NOVNC_WEB="8083"
# Expose the required ports
EXPOSE 2222
EXPOSE 5900
EXPOSE 5901
EXPOSE 8083
EXPOSE 32123
# Set entrypoint
RUN chmod +x /entrypoint.sh

View File

@@ -45,13 +45,10 @@ Unraid's Linux kernel by default does not have the modules required to support c
> __Warning__
>
> Be aware that, by default, this container requires at least 8083, 5900, 5901, 32123, and 2222 available for the WebUI, VNC, Web Audio, and SSH to work. It will also require any ports that Steam requires for Steam Remote Play.
> Be aware that, by default, this container requires at least 8083 and 2222 available for the WebUI and SSH to work. It will also require any ports that Steam requires for Steam Remote Play.
You can override the default ports used by the container with these variables:
- PORT_SSH (Default: 2222)
- PORT_VNC (Default: 5900)
- PORT_AUDIO_STREAM (Default: 5901)
- PORT_NOVNC_WEB (Default: 8083)
- PORT_AUDIO_WEBSOCKET (Default: 32123)
3. No server restart is required, however. Ensure that the **steam-headless** Docker container is recreated after installing the **uinput** plugin for it to be able to detect the newly added module.

View File

@@ -1,10 +1,48 @@
echo "**** Configure VNC ****"
function get_unused_port() {
__start_port=${1}
__start_port=$((__start_port+1))
for __check_port in $(seq ${__start_port} 65000); do
[[ -z $(netstat -ap 2> /dev/null | grep ${__check_port}) ]] && break;
done
echo ${__check_port}
}
# Export empty values to start
# Without this, supervisor will not be able to parse the ini configs
export PORT_VNC
export PORT_NOVNC_SERVICE
export PORT_AUDIO_WEBSOCKET
export PORT_AUDIO_STREAM
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
if [ ${WEB_UI_MODE} = "vnc" ]; then
echo "Enable VNC server"
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/vnc.ini
# Configure random ports for VNC service, pulseaudio socket, noVNC service and audio transport websocket
# Note: Ports 32035-32248 are unallocated port ranges. We should be able to find something in here that we can use
# REF: https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?&page=130
export PORT_VNC=$(get_unused_port 32035)
echo "Configure VNC service port '${PORT_NOVNC_SERVICE}'"
export PORT_NOVNC_SERVICE=$(get_unused_port ${PORT_VNC})
echo "Configure noVNC service port '${PORT_NOVNC_SERVICE}'"
export PORT_AUDIO_WEBSOCKET=$(get_unused_port ${PORT_NOVNC_SERVICE})
echo "Configure audio websocket port '${PORT_AUDIO_WEBSOCKET}'"
export PORT_AUDIO_STREAM=$(get_unused_port ${PORT_AUDIO_WEBSOCKET})
echo "Configure pulseaudio encoded stream port '${PORT_AUDIO_STREAM}'"
# Configure Nginx proxy for the websocket and VNC
sed -i "s|<USER>|${USER}|" /opt/noVNC/nginx.conf
sed -i "s|<PORT_NOVNC_WEB>|${PORT_NOVNC_WEB}|" /opt/noVNC/nginx.conf
sed -i "s|<PORT_NOVNC_SERVICE>|${PORT_NOVNC_SERVICE}|" /opt/noVNC/nginx.conf
sed -i "s|<PORT_AUDIO_WEBSOCKET>|${PORT_AUDIO_WEBSOCKET}|" /opt/noVNC/nginx.conf
mkdir -p /var/log/vncproxy
chown -R ${USER} /var/log/vncproxy
if [[ "${ENABLE_VNC_AUDIO}" == "true" ]]; then
# Credits for this audio patch:
# - https://github.com/novnc/noVNC/issues/302
@@ -12,8 +50,8 @@ if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
# - https://github.com/calebj/noVNC
if [ -f /opt/noVNC/audio.patch ]; then
echo "Patching noVNC with audio websocket"
# Enable supervisord script
sed -i "s|32123|${PORT_AUDIO_WEBSOCKET}|" /opt/noVNC/audio.patch
# Update port specification in patch file
sed -i "s|<PORT_AUDIO_WEBSOCKET>|${PORT_AUDIO_WEBSOCKET}|" /opt/noVNC/audio.patch
# Apply patch
pushd /opt/noVNC/ &> /dev/null
patch -p1 --input=/opt/noVNC/audio.patch --batch --quiet

View File

@@ -6,7 +6,7 @@ autorestart=true
# Retry a restart a few times.
# This allows this container to start up before X is ready and restart the process until it becomes available.
# Each restart will have a small delay of a few seconds. So 50 attempts should be a few mins.
startretries=50
startretries=50
priority=50
user=%(ENV_USER)s
directory=/home/%(ENV_USER)s

View File

@@ -18,7 +18,8 @@ autostart=false
autorestart=true
priority=30
user=%(ENV_USER)s
command=/opt/noVNC/utils/launch.sh --vnc localhost:%(ENV_PORT_VNC)s --listen %(ENV_PORT_NOVNC_WEB)s
# /opt/noVNC/utils/launch.sh --vnc localhost:${PORT_VNC} --listen ${PORT_NOVNC_SERVICE}
command=/opt/noVNC/utils/launch.sh --vnc localhost:%(ENV_PORT_VNC)s --listen %(ENV_PORT_NOVNC_SERVICE)s
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
stopsignal=INT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/novnc.log
@@ -27,3 +28,20 @@ stdout_logfile_backups=7
stderr_logfile=/home/%(ENV_USER)s/.cache/log/novnc.err.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=7
[program:vncproxy]
autostart=false
autorestart=true
priority=30
numprocs=1
startsecs=0
user=%(ENV_USER)s
command=/usr/sbin/nginx -c /opt/noVNC/nginx.conf
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
stopsignal=INT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/vncproxy.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=7
stderr_logfile=/home/%(ENV_USER)s/.cache/log/vncproxy.err.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=7

View File

@@ -102,14 +102,14 @@ index cb6a9fd..4d599e1 100644
UI.rfb.focus();
+
+ let audio_url;
+ let host = window.location.hostname;
+ let port = 32123;
+ // let host = window.location.hostname;
+ // let port = '<PORT_AUDIO_WEBSOCKET>';
+ if (window.location.protocol === "https:") {
+ audio_url = 'wss';
+ } else {
+ audio_url = 'ws';
+ }
+ audio_url += '://' + host + ':' + port;
+ audio_url += '://' + window.location.host + '/audiowebsock';
+
+ UI.webaudio = new WebAudio(audio_url);
+ UI.toggleAudio();
@@ -326,14 +326,14 @@ index 8e2f5cb..d3cf6ab 100644
// successfully connected to a server
function connectedToServer(e) {
+ let audio_url;
+ let host = window.location.hostname;
+ let port = 32123;
+ // let host = window.location.hostname;
+ // let port = '<PORT_AUDIO_WEBSOCKET>';
+ if (window.location.protocol === "https:") {
+ audio_url = 'wss';
+ } else {
+ audio_url = 'ws';
+ }
+ audio_url += '://' + host + ':' + port;
+ audio_url += '://' + window.location.host + '/audiowebsock';
+
+ wa = new WebAudio(audio_url);
+ document.getElementById('toggleAudioButton').style.display = "block";
@@ -360,7 +360,7 @@ index 8e2f5cb..d3cf6ab 100644
+ if (wa.connected) {
+ console.log('Stopping audio...')
+ wa.stop();
+ document.getElementById('toggleAudioButton').innerText = "Enable Audio (requires access to port 32123)";
+ document.getElementById('toggleAudioButton').innerText = "Enable Audio";
+ } else {
+ console.log('Starting audio websocket on: ' + audio_url)
+ wa.start();
@@ -410,7 +410,7 @@ index 8e2f5cb..d3cf6ab 100644
<body>
<div id="top_bar">
+ <div id="toggleAudioButton">Enable Audio (requires access to port 32123)</div>
+ <div id="toggleAudioButton">Enable Audio</div>
<div id="status">Loading</div>
<div id="sendCtrlAltDelButton">Send CtrlAltDel</div>
</div>

View File

@@ -0,0 +1,40 @@
daemon off;
worker_processes auto;
pid /tmp/vncproxy.pid;
error_log /home/<USER>/.cache/log/vncproxy.err.log;
events {
}
http {
server {
listen <PORT_NOVNC_WEB> default_server;
access_log /home/<USER>/.cache/log/vncproxy.log;
client_body_temp_path /tmp/client_body;
fastcgi_temp_path /tmp/fastcgi_temp;
proxy_temp_path /tmp/proxy_temp;
scgi_temp_path /tmp/scgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp;
location / {
proxy_pass http://127.0.0.1:<PORT_NOVNC_SERVICE>/;
}
location /websockify {
proxy_pass http://127.0.0.1:<PORT_NOVNC_SERVICE>/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
location /audiowebsock {
proxy_pass http://127.0.0.1:<PORT_AUDIO_WEBSOCKET>/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
}
}