Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Socket port not accessible #505

Open
pikeas opened this issue Mar 9, 2015 · 10 comments
Open

Socket port not accessible #505

pikeas opened this issue Mar 9, 2015 · 10 comments

Comments

@pikeas
Copy link

pikeas commented Mar 9, 2015

I have BrowserSync running in a docker container. Docker maps a random external port to the exposed internal port.

For BrowserSync, this means that the websocket cannot be reached when using the UI. The script used by the UI generates a URL which points at port setting, but the script is being run in a browser outside of the container context.

Example: port 3000 is mapped to 49300 and port 3001 (UI) is mapped to 49301. I visit http://site.dev:49301/ in my browser, the UI page loads. The UI scripts tries to connect to site.dev:3000, which fails.

I'm not really sure how to go about fixing this, as by design, the software running inside a container doesn't know which port the host has exposed.

@shakyShane
Copy link
Contributor

Interesting!

I'd be very interested in making BrowserSync work with Docker - so if you could point in the the right direction re: getting setup or a tutorial that would be great.

@pascalduez
Copy link

Greetings,

I'm trying to make Browser-sync work from a docker container as well, with no luck.
The service port is 6543.

So browser-sync start --proxy localhost:6543 seems to properly bootstrap but it fails after a second with a:

browser-sync start --proxy localhost:6543
[BS] Proxying: http://localhost:6543
[BS] Access URLs:
 --------------------------------------
       Local: http://localhost:3000
    External: http://[...]:3000
 --------------------------------------
          UI: http://localhost:3001
 UI External: http://[...]:3001
 --------------------------------------
/[...]/node_modules/browser-sync/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Receiver.js:222
  if (!this.state.fragmentedOperation) this.unfragmentedBufferPool.reset(true)
                 ^
TypeError: Cannot read property 'fragmentedOperation' of null
    at Receiver.endPacket (/[...]/node_modules/browser-sync/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Receiver.js:222:18)
    at Receiver.opcodes.1.finish (/[...]/node_modules/browser-sync/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Receiver.js:394:12)
    at Receiver.<anonymous> (/[...]/node_modules/browser-sync/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Receiver.js:372:33)
    at Receiver.add (/[...]/node_modules/browser-sync/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Receiver.js:87:24)
    at Socket.firstHandler (/[...]/node_modules/browser-sync/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/WebSocket.js:718:22)
    at Socket.emit (events.js:107:17)
    at readableAddChunk (_stream_readable.js:163:16)
    at Socket.Readable.push (_stream_readable.js:126:10)
    at TCP.onread (net.js:538:20)

@arnau
Copy link

arnau commented May 11, 2015

Hi, I'm trying to make browser-sync work with Docker as well. If you want a quick starting point, you can use the public docker image I'm working on: https://registry.hub.docker.com/u/ustwo/browser-sync

My problem seems to be a sort-of loop:

  1. Start docker browser-sync
  2. Modify a css
  3. browser-sync detects the change
  4. The browser gets the injection
  5. browser-sync detects again a change in the css (and that happens over and over)

@arnau
Copy link

arnau commented May 12, 2015

Hi, I created https://github.com/ustwo/docker-browser-sync to test use cases with browser-sync inside Docker.

@ajacques
Copy link

As far as the internal/external port issue, I've actually just started seeing this issue after upgrading to the latest version of browsersync. Everything used to work correctly since Browsersync would use the location hostname + port from the browser to create the socket.io path, but now after b2fa337 it seems now will use #{location.hostname}:#{port} which isn't correct in my case. I use NGINX in another docker container to proxy to the Browsersync docker container so the ports that Browsersync aren't going to be the external one.

Basically, if Browsersync reverts back to using location.host instead of location.hostname I think it should work.

@smyth64
Copy link

smyth64 commented Feb 23, 2016

Is there any workaround available how to fix this?

@hyzhak
Copy link

hyzhak commented Jul 23, 2016

👍

@hyshka
Copy link

hyshka commented Nov 22, 2016

Have any of you got this running? Would love to have the randomized host ports.

@keatz55
Copy link

keatz55 commented Jan 22, 2017

+1

@hanoii
Copy link

hanoii commented Aug 20, 2020

Although a very old issue I spent a considerable amount of time trying to see the issue and trying potential fixes.

I think I narrowed it down to different commits around work done on #625.

And probably other related ones.

I believe that when the issue above was done something was not properly thought and some other things were wrongly replaced. First when you set a proxy browser-sync is setting it to "snippet" mode and I believe that's wrong.

Also, you can set proxy with:

{
target: PROXY_URL
ws: true
}

Which apparently is intended to also proxy the webservice, but then on some other places it feels as the same setting is used in the opposite way.

While I think I could submit a PR I am also not sure if I will cover or be able to test all use cases (like the one on #625) and there seems to be little activity in terms of PRs in the module, so I tried to come up with a workaround.

While probably not great (still neat and useful) this is what I did and it does work.

// The following will overwite the default clinet:script plugin.
// The main issue of this is so that our browsersync works properly on both
// lando and non-lando environments. This is a hacky workaround of different
// issues with BS.
// @see https://github.com/BrowserSync/browser-sync/issues/505
// @see https://github.com/BrowserSync/browser-sync/issues/625
const bscCustom = {
  'plugin:name': 'client:script',
  ...bsc,
  plugin: function initCustom(options, requestBody, type) {
    for (i in requestBody) {
      if (typeof requestBody[i] === 'function') {
        requestBody[i] = (function (fn) {
          var wrappedFn = function() {
            var args = [...arguments].splice(0);
            var output = fn(args);
            return output.replace("___browserSync___.socketUrl = 'http://' + location.hostname + ':3000/browser-sync'", "___browserSync___.socketUrl = 'http://' + location.host + '/browser-sync'");
          }
          return wrappedFn;
        })(requestBody[i]);
      }
    }
    return bsc.plugin(options, requestBody, type);
  }
};

let bs_options = {
  plugins: [bscCustom],
  proxy: {
    target: process.env.MIX_BS_PROXY,
    proxyRes: [
      function(proxyRes, req, res) {
        const proxy_host = proxyRes.req.getHeader('host');
        const destination_host = req.headers['host'];

        // This is to allow our site to work for forms (POSTs).
        for (i in proxyRes.headers) {
          if (Array.isArray(proxyRes.headers[i])) {
            for (j in proxyRes.headers[i]) {
              proxyRes.headers[i][j] = proxyRes.headers[i][j].replace(proxy_host, destination_host);
            }
          }
          else {
            proxyRes.headers[i] = proxyRes.headers[i].replace(proxy_host, destination_host);
          }
        }
      }
    ]
  },
  files: ['assets/js/**/*.js', 'assets/css/**/*.css'],
};

I am setting the local client javascript back to what it was back then like what's mentioned above.

The proxyRes function might not be needed but I am also documenting it and it's an useful way of allowing POSTs (forms) to work.

It's possible that by doing this the intended fix for #625 is lost, so if you have other WS going through the proxy, this might not be the best way of doing it or you might need to do something further.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants