grych / drab

Remote controlled frontend framework for Phoenix.

Home Page:https://tg.pl/drab

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Drab, production, and reverse proxy

guidotripaldi opened this issue · comments

When using in production, an app is often behind an apache/nginx server for domain virtualization or balancing, so the external port (80) is different from the actual app port (i.e. 4000). The necessary mapping between the two ports, on apache, is usually done by a reverse proxy directive, for example:

ProxyPass / http://example.com:4000/
ProxyPassReverse / http://example.com:4000/ 

In these cases Drab fails the web socket connection. How to address this kind problem?

javascript console:
WebSocket connection to 'ws://example.com/socket/websocket?__drab_return=SFMyNTY.g3QAAAACZAAEZGF0YWwAAAAFaAJkAAxfX2NvbnRyb2xsZXJkACJFbGl4aXIuRnJvbnRlbmRXZWIuR3JvdXBDb250cm9sbGVyaAJkAAtfX2NvbW1hbmRlcmQAIUVsaXhpci5Gcm9udGVuZFdlYi5Hcm91cENvbW1hbmRlcmgCZAAGX192aWV3ZAAcRWxpeGlyLkZyb250ZW5kV2ViLkdyb3VwVmlld2gCZAAIX19hY3Rpb25kAARzaG93aAJkAAlfX2Fzc2lnbnNqamQABnNpZ25lZG4GAElQ0LZjAQ.hUrGkh3ppMgZtcczY4MaBrTfKSfEmBETYXAxb5Ky1oE&__client_lib_version=6&vsn=2.0.0' failed: Unexpected response code: 400

My nginx configuration for tg.pl/drab:

location /drab {
    include proxy.conf;
    proxy_http_version 1.1;
    proxy_redirect off;
    proxy_pass http://drab;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Cluster-Client-Ip $remote_addr;

    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

You may also take a look to https://github.com/grych/drab-poc config, but remember it redirects to /drab path (as http://tg.pl and http://tg.pl/drab are different applications.

Solution for apache environment

  1. Load the ws tunnel module adding this directive in /etc/httpd/conf/httpd.conf:

LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

  1. set up a proxy for both http (and/or https) and ws adding the following directives inside the virtualhost block for your domain in the /etc/httpd/conf/httpd.conf file:
ProxyPass /socket/ ws://example.com:4000/socket/
ProxyPassReverse /socket/ ws://example.com:4000/socket/
ProxyPass / http://example.com:4000/
ProxyPassReverse / http://example.com:4000/
  1. being sure to write the directives in the correct order:

The configured ProxyPass and ProxyPassMatch rules are checked in the order of configuration. The first rule that matches wins. So usually you should sort conflicting ProxyPass rules starting with the longest URLs first.

  1. restart apache:
    # apachectl restart

(maybe we could add these sample configurations for nginx and apache in the wiki so others can easily add more examples, and add some references to it in the documentation to explain the needs for a specific configuration that enables websocket when a drab app is behind a proxy, as it couldn't be obvious)

Sure, we should. Would you like to do it?