Using haproxy with shiny server


#1

I am trying to use haproxy (on front machine) with shiny server (on backend machine). I have apache and wordpress on the backend machine too.

The proxy code examples for shiny server on the web are primarily for NginX and Apache. Shiny server uses websockets, I have been successful in using haproxy to connect to wordpress site through apache. However, I cannot get haproxy to work with shiny server where the client can either go to the wordpress site or to the shiny port.

I know that the shiny server works, since a). I can observe the demo code when I open the browser on the backend machine directly, and b). when I put in a proxy (following the link shown above) code in 000-default.conf for shiny, the website shows the shiny interface (instead of the wordpress interface). I am not sure how I can tell haproxy to switch between the two ports (80 for wordpress site, and 3838 for http of shiny site). Been banging my head against this problem for the last two days; any help would be really appreciated.

System config is: ubuntu 18.04 LTS, haproxy1.8.9-1ppa1~bionic, apache2.4.29, shiny-server

My current haproxy config file code is:

    global
	log /dev/log	local0
	log /dev/log	local1 notice
	chroot /var/lib/haproxy
	stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
	stats timeout 30s
	user haproxy
	group haproxy
	daemon

        maxconn 2048
	tune.ssl.default-dh-param 2048

	# Default SSL material locations
	ca-base /etc/ssl/certs
	crt-base /etc/ssl/private

	# Default ciphers to use on SSL-enabled listening sockets.
	# For more information, see ciphers(1SSL). This list is from:
	#  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
	# An alternative list with additional directives can be obtained from
	#  https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
	ssl-default-bind-ciphers 
	ssl-default-bind-options no-sslv3

defaults
	log	global
	mode	http
	option forwardfor
	option http-server-close
	retries 3
	option redispatch
	option	httplog
	option	dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
	errorfile 400 /etc/haproxy/errors/400.http
	errorfile 403 /etc/haproxy/errors/403.http
	errorfile 408 /etc/haproxy/errors/408.http
	errorfile 500 /etc/haproxy/errors/500.http
	errorfile 502 /etc/haproxy/errors/502.http
	errorfile 503 /etc/haproxy/errors/503.http
	errorfile 504 /etc/haproxy/errors/504.http

	stats enable
	stats uri /stats
	stats realm Haproxy\ Statistics
	stats auth username:password

frontend www-http
	bind FrontserverIPaddress:80
	reqadd X-Forwarded-Proto:\ http
	default_backend www-backend

frontend www-https
	bind frontendserverIPaddress:443 ssl crt /etc/ssl/private/datacolaboratory.com.pem
	reqadd X-Forwarded-Proto:\ https

	mode http
	timeout client 120s
	option forwardfor
	option http-server-close
	option http-pretend-keepalive

	acl is_websocket hdr(Upgrade) -i WebSocket
	acl is_websocket hdr_beg(Host) -i ws
	acl host_daco hdr_sub(Host) -i datacolaboratory.com
	use_backend bk_rshinyproxy if is_websocket host_daco

	default_backend www-backend

backend www-backend
	redirect scheme https if !{ ssl_fc }
	server www-1 backendserverIPaddress:80 check

backend bk_rshinyproxy
	option forwardfor
	option http-server-close
	option forceclose
	balance source
	timeout tunnel 1200s
        server shiny backendserverIPaddress:3838 weight 1 maxconn 1024 check

#2

How would you like haproxy to take the decision whether to route it to wordpress or your shiny site? The Host header?


#3

I would like it to decide based on: https://datacolaboratory.com should go to wordpress site and https://datacolaboratory.com/shinyapps to go to shiny site.Is that doable? I tried using:

    acl is_websocket path_beg /shinyapps
	acl is_websocket hdr(Connection) -i upgrade
	acl is_websocket hdr(Upgrade)	   -i websocket
	
	use_backend bk_rshinyproxy if is_websocket

instead of:

    acl is_websocket hdr(Upgrade) -i WebSocket
	acl is_websocket hdr_beg(Host) -i ws
	acl host_daco hdr_sub(Host) -i datacolaboratory.com
	use_backend bk_rshinyproxy if is_websocket host_daco

but that did not work. The haproxy log does seem to suggest the correct backend is being used, apache and shiny server logs are not complaining, but the browser still says:

Page not found
Sorry, but the page you requested doesn't exist.

Bit unsure which log to look at since there must be a log somewhere that has the clue, but the obvious logs don’t appear to see anything.