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

View File

@@ -194,6 +194,7 @@ RUN \
echo echo
# Install noVNC # Install noVNC
# TODO: Add nginx
ARG NOVNC_VERSION=1.2.0 ARG NOVNC_VERSION=1.2.0
RUN \ RUN \
echo "**** Fetch noVNC ****" \ echo "**** Fetch noVNC ****" \
@@ -415,17 +416,11 @@ ENV \
# Configure required ports # Configure required ports
ENV \ ENV \
PORT_SSH="2222" \ PORT_SSH="2222" \
PORT_VNC="5900" \ PORT_NOVNC_WEB="8083"
PORT_AUDIO_STREAM="5901" \
PORT_NOVNC_WEB="8083" \
PORT_AUDIO_WEBSOCKET="32123"
# Expose the required ports # Expose the required ports
EXPOSE 2222 EXPOSE 2222
EXPOSE 5900
EXPOSE 5901
EXPOSE 8083 EXPOSE 8083
EXPOSE 32123
# Set entrypoint # Set entrypoint
RUN chmod +x /entrypoint.sh 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__ > __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: You can override the default ports used by the container with these variables:
- PORT_SSH (Default: 2222) - PORT_SSH (Default: 2222)
- PORT_VNC (Default: 5900)
- PORT_AUDIO_STREAM (Default: 5901)
- PORT_NOVNC_WEB (Default: 8083) - 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. 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 ****" 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 ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
if [ ${WEB_UI_MODE} = "vnc" ]; then if [ ${WEB_UI_MODE} = "vnc" ]; then
echo "Enable VNC server" echo "Enable VNC server"
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/vnc.ini 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 if [[ "${ENABLE_VNC_AUDIO}" == "true" ]]; then
# Credits for this audio patch: # Credits for this audio patch:
# - https://github.com/novnc/noVNC/issues/302 # - https://github.com/novnc/noVNC/issues/302
@@ -12,8 +50,8 @@ if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
# - https://github.com/calebj/noVNC # - https://github.com/calebj/noVNC
if [ -f /opt/noVNC/audio.patch ]; then if [ -f /opt/noVNC/audio.patch ]; then
echo "Patching noVNC with audio websocket" echo "Patching noVNC with audio websocket"
# Enable supervisord script # Update port specification in patch file
sed -i "s|32123|${PORT_AUDIO_WEBSOCKET}|" /opt/noVNC/audio.patch sed -i "s|<PORT_AUDIO_WEBSOCKET>|${PORT_AUDIO_WEBSOCKET}|" /opt/noVNC/audio.patch
# Apply patch # Apply patch
pushd /opt/noVNC/ &> /dev/null pushd /opt/noVNC/ &> /dev/null
patch -p1 --input=/opt/noVNC/audio.patch --batch --quiet patch -p1 --input=/opt/noVNC/audio.patch --batch --quiet

View File

@@ -18,7 +18,8 @@ autostart=false
autorestart=true autorestart=true
priority=30 priority=30
user=%(ENV_USER)s 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" environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
stopsignal=INT stopsignal=INT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/novnc.log 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=/home/%(ENV_USER)s/.cache/log/novnc.err.log
stderr_logfile_maxbytes=10MB stderr_logfile_maxbytes=10MB
stderr_logfile_backups=7 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(); UI.rfb.focus();
+ +
+ let audio_url; + let audio_url;
+ let host = window.location.hostname; + // let host = window.location.hostname;
+ let port = 32123; + // let port = '<PORT_AUDIO_WEBSOCKET>';
+ if (window.location.protocol === "https:") { + if (window.location.protocol === "https:") {
+ audio_url = 'wss'; + audio_url = 'wss';
+ } else { + } else {
+ audio_url = 'ws'; + audio_url = 'ws';
+ } + }
+ audio_url += '://' + host + ':' + port; + audio_url += '://' + window.location.host + '/audiowebsock';
+ +
+ UI.webaudio = new WebAudio(audio_url); + UI.webaudio = new WebAudio(audio_url);
+ UI.toggleAudio(); + UI.toggleAudio();
@@ -326,14 +326,14 @@ index 8e2f5cb..d3cf6ab 100644
// successfully connected to a server // successfully connected to a server
function connectedToServer(e) { function connectedToServer(e) {
+ let audio_url; + let audio_url;
+ let host = window.location.hostname; + // let host = window.location.hostname;
+ let port = 32123; + // let port = '<PORT_AUDIO_WEBSOCKET>';
+ if (window.location.protocol === "https:") { + if (window.location.protocol === "https:") {
+ audio_url = 'wss'; + audio_url = 'wss';
+ } else { + } else {
+ audio_url = 'ws'; + audio_url = 'ws';
+ } + }
+ audio_url += '://' + host + ':' + port; + audio_url += '://' + window.location.host + '/audiowebsock';
+ +
+ wa = new WebAudio(audio_url); + wa = new WebAudio(audio_url);
+ document.getElementById('toggleAudioButton').style.display = "block"; + document.getElementById('toggleAudioButton').style.display = "block";
@@ -360,7 +360,7 @@ index 8e2f5cb..d3cf6ab 100644
+ if (wa.connected) { + if (wa.connected) {
+ console.log('Stopping audio...') + console.log('Stopping audio...')
+ wa.stop(); + wa.stop();
+ document.getElementById('toggleAudioButton').innerText = "Enable Audio (requires access to port 32123)"; + document.getElementById('toggleAudioButton').innerText = "Enable Audio";
+ } else { + } else {
+ console.log('Starting audio websocket on: ' + audio_url) + console.log('Starting audio websocket on: ' + audio_url)
+ wa.start(); + wa.start();
@@ -410,7 +410,7 @@ index 8e2f5cb..d3cf6ab 100644
<body> <body>
<div id="top_bar"> <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="status">Loading</div>
<div id="sendCtrlAltDelButton">Send CtrlAltDel</div> <div id="sendCtrlAltDelButton">Send CtrlAltDel</div>
</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;
}
}
}