netbootxyz / docker-netbootxyz

netboot.xyz docker container
https://netboot.xyz/docs/docker
162 stars 50 forks source link

Reverse proxying does not work #32

Open hexadecagram opened 1 year ago

hexadecagram commented 1 year ago

LABEL build_version=netboot.xyz version: 0.6.7-nbxyz21 Build-date: 2022-12-09T02:25:23

Hello,

I am attempting to run docker-netbootxyz behind a reverse proxy so that I can have the administrative interface located at http://example.com/netbootxyz and the assets at http://example.com/assetsxyz. I am running netbootxyz as a Docker Stack (not just a service), with host-based rather than overlay networking which is better for maintaining stateful connections, and I use HAProxy and Apache to accomplish the reverse proxying.

Setting it up this way mostly seems to work just fine except that the webpage never progresses past saying "Getting Dashboard" with a pulsating disc, at which time I see this in Chrome's debugging console:

polling.js:311          GET https://example.com/socket.io/?EIO=4&transport=polling&t=OLK-hzD 503 (Service Unavailable)
create @ polling.js:311
Request @ polling.js:255
request @ polling.js:207
doPoll @ polling.js:232
poll @ polling.js:98
doOpen @ polling.js:58
open @ transport.js:49
open @ socket.js:162
Socket @ socket.js:103
open @ manager.js:108
Manager @ manager.js:39
lookup @ index.js:29
(anonymous) @ netbootxyz-web.js:9

If I then examine netbootxyz-web.js, the issue is plainly obvious at line 9. As you will notice in my Apache configuration, I have attempted to remedy the situation by adding the line ProxyHTMLURLMap /socket.io /netbootxyz/socket.io, which has no effect because ProxyHTMLURLMap evidently does not have the proper context to match that line, so "/socket.io" never gets modified, and it looks like it's the wrong thing to do here, anyway.

I can't recall the exact method that I've used in the past, but I know that I can work around this by piping netbootxyz-web.js through a shell script before it is served out by Apache. Nevertheless, anyone else that would like to reverse-proxy netbootxyz would likely bump into this issue, so it's worth mentioning. I will continue to work on this as time permits and post any findings.

Here are the relevant sections of my configurations.

docker-compose.yaml

version: "3.8"
  netbootxyz:
    image: ghcr.io/netbootxyz/netbootxyz
    deploy:
      mode: global
    ports:
      - target: 69
        published: $NETBOOTXYZ_TFTP_PORT
        protocol: udp
        mode: host
      - target: 80
        published: $NETBOOTXYZ_ASSETS_PORT
        mode: host
      - target: 3000
        published: $NETBOOTXYZ_CONFIG_PORT
        mode: host
    volumes:
      - netbootxyz_config:/config
      - netbootxyz_assets:/assets
    environment: [TZ]

volumes:
  netbootxyz_assets:
    name: netbootxyz_assets
    driver_opts:
      type: "nfs"
      o: "addr=server"
      device: ":/netbootxyz"
  netbootxyz_config:
    name: netbootxyz_config

haproxy.cfg

backend netbootxyz
    option httpchk OPTIONS *
    http-check send hdr Host localhost
    http-request redirect prefix / drop-query append-slash if { path /netbootxyz }
    server netbootxyz proxy_mod_proxy:80 check resolvers default # ssl verify none

backend assetsxyz
    option httpchk OPTIONS *
    http-check send hdr Host localhost
    http-request redirect prefix / drop-query append-slash if { path /assetsxyz }
    server assetsxyz proxy_mod_proxy:80 check resolvers default # ssl verify none

extra/proxy-html.conf

ProxyRequests Off

ProxyHTMLURLMap http://netbootxyz:3000/ /netbootxyz/
<Location /netbootxyz/>
    Header edit Set-Cookie expr=^(.*[Dd]omain)=([^;]+)(.*)$ \1=example.com\3
    Header edit Set-Cookie expr=^(.*[Pp]ath)=([^;]+)(.*)$ \1=/netbootxyz\3
    ProxyHTMLEnable On
    ProxyHTMLExtended On
    ProxyPass http://netbootxyz:3000/
    ProxyPassReverse http://netbootxyz:3000/
    ProxyHTMLURLMap /socket.io /netbootxyz/socket.io
    ProxyHTMLURLMap / /netbootxyz/
    RequestHeader unset Accept-Encoding
</Location>

ProxyHTMLURLMap http://netbootxyz:80/ /assetsxyz/
<Location /assetsxyz/>
    Header edit Set-Cookie expr=^(.*[Dd]omain)=([^;]+)(.*)$ \1=example.com\3
    Header edit Set-Cookie expr=^(.*[Pp]ath)=([^;]+)(.*)$ \1=/assetsxyz\3
    ProxyHTMLEnable On
    ProxyHTMLExtended On
    ProxyPass http://netbootxyz:80/
    ProxyPassReverse http://netbootxyz:80/
    ProxyHTMLURLMap / /assetsxyz/
    RequestHeader unset Accept-Encoding
</Location>