
How to setup Shiny Server reverse proxy via RoseHosting (Virtual Private Server) VPS
Quick Summary of Contents
Recently, a customer of 15+ years contacted me requesting technical assistance in regards to an upcoming book launch.
In the book, the customer references a few links that are to redirect readers to a website of on-page apps containing interactive charts and graphs. Readers are able to visit website, add their own data, and then view the same data as well as adjust the data using charting and graphing controls.
To achieve the interactive charting and graphing functionality for each app on website, this customer chose to use Shiny Server from RStudio.com. I had not realized the full capability of the RStudio service offering as a robust professional data science solution for reporting.
Nevertheless, the customer contacted me because they preferred not to use RStudio Connect and Shinyapps.io in favor of desiring to use Shiny Server Pro. However, the one catch with using Shiny Server Pro is that it requires a Linux Server — this customer is a Windows shop. 😳
Not having worked with Shiny before, I was able to successfully install R and Shiny on a RoseHosting (Virtual Private Server) VPS running CentOS7. With Shiny up and running, I was able to view the default welcome page simply typing in the domain I used followed by port 3838 (Shiny’s default listening port): http://domainname:3838/.
This is all good and the general public was able to access the url; however, the downside is the general public must remember to append the port to the domain every time they type the url into a browser.
And from where I come from, having nearly 2 decades of experience in user interface and experience, forcing the use of remembering a port number by the general public is a showstopper, to say the least.
So, I started on the journey to discover how feasible it was to have a Shiny Server proxy or mask as the domain only (i.e., http://domainname/) and not domain and port (i.e., http://domainname:3838/).
Having worked in, with, and around Linux most of my web and software development career, I was familiar quite familiar working with Virtual Host files to host multiple websites from one server. But this reverse proxy business? Uh, not so much.
What is this reverse proxy using virtual hosts business?
I Googled a few searches only to discover convoluted and piece-meal-ish answers that filled with unexplainable technical jargon that wasn’t intuitive nor straight forward to implement.
But fortunately for me, I did some reading up on reverse proxy using virtual hosts and found that implementing the code below with the first few lines of Virtual Host code allowed me to mask the domain name and not include the port.
ProxyRequests off ProxyPass / http://yourdomain:3838/ ProxyPassReverse / http://yourdomain:3838/
A couple of things to note about the aforementioned directives. First, ProxyRequests is set to off by default, and allows or prevents Apache https from functioning as a forward proxy server.
Next, the ProxyPass directive allows for virtual mapping of the local server, often referred to as reverse proxy or gateway. In our example, we’re explicitly binding the local virtual path of / to the local server address of Shiny Server: http://yourdomain:3838. Finally, the ProxyPassReverse directive allows for the URL in the Location, Content-Location and URI headers on HTTP redirect responses.
Note: Be sure you have mod_proxy and related modules enabled in your web server environment.
With just the 3 lines of code above, I was able to open a browser, visit customer’s domain for Shiny Server, and interact with the default page Shinny apps. I didn’t have to remember that pesky port number or anything. And that’s it!
Let me know if you have any questions about how to best setup Shiny Server reverse proxy via RoseHosting (Virtual Private Server) VPS.
Shiny Server Reverse Proxy for Virtual Host Port 80
The following Virtual Host code is used to reverse proxy against port 80.
<VirtualHost <ip>:80 > ProxyRequests off ProxyPass / http://yourdomain:3838/ ProxyPassReverse / http://yourdomain:3838/ ServerName www.yourdomain ServerAlias www.yourdomain yourdomain ServerAdmin webmaster@yourdomain DocumentRoot /home/user/domains/yourdomain/public_html ScriptAlias /cgi-bin/ /home/user/domains/yourdomain/public_html/cgi-bin/ UseCanonicalName OFF SetEnvIf X-Forwarded-Proto "https" HTTPS=on RewriteEngine On RewriteCond %{HTTPS} !=on RewriteCond %{HTTP:X-Forwarded-Proto} !https [NC] RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] <IfModule !mod_ruid2.c> SuexecUserGroup user user </IfModule> <IfModule mod_ruid2.c> RMode config RUidGid user user #RGroups apache access RGroups @none </IfModule> CustomLog /var/log/httpd/domains/yourdomain.bytes bytes CustomLog /var/log/httpd/domains/yourdomain.log combined ErrorLog /var/log/httpd/domains/yourdomain.error.log <Directory /home/user/domains/yourdomain/public_html> php_admin_flag engine ON php_admin_value sendmail_path '/usr/sbin/sendmail -t -i -f user@yourdomain' php_admin_value mail.log /home/user/.php/php-mail.log php_admin_value open_basedir /home/user/:/tmp:/var/tmp:/opt/alt/php73/usr/share/pear/:/dev/urandom:/usr/local/lib/php/:/usr/local/php73/lib/php/ </Directory> </VirtualHost>
Shiny Server Reverse Proxy for Virtual Host Port 443
The following Virtual Host code is used to reverse proxy against port 443 (commonly known as the SSL/TLS port).
<VirtualHost <ip>:443 > ProxyRequests off ProxyPass / http://yourdomain:3838/ ProxyPassReverse / http://yourdomain:3838/ SSLEngine on SSLCertificateFile /usr/local/directadmin/data/users/user/domains/yourdomain.cert.combined SSLCertificateKeyFile /usr/local/directadmin/data/users/user/domains/yourdomain.key SSLCACertificateFile /usr/local/directadmin/data/users/user/domains/yourdomain.cacert ServerName www.yourdomain ServerAlias www.yourdomain yourdomain ServerAdmin webmaster@yourdomain DocumentRoot /home/user/domains/yourdomain/private_html ScriptAlias /cgi-bin/ /home/user/domains/yourdomain/public_html/cgi-bin/ UseCanonicalName OFF <IfModule !mod_ruid2.c> SuexecUserGroup user user </IfModule> <IfModule mod_ruid2.c> RMode config RUidGid user user #RGroups apache access RGroups @none </IfModule> CustomLog /var/log/httpd/domains/yourdomain.bytes bytes CustomLog /var/log/httpd/domains/yourdomain.log combined ErrorLog /var/log/httpd/domains/yourdomain.error.log <Directory /home/user/domains/yourdomain/private_html> php_admin_flag engine ON php_admin_value sendmail_path '/usr/sbin/sendmail -t -i -f user@yourdomain' php_admin_value mail.log /home/user/.php/php-mail.log php_admin_value open_basedir /home/user/:/tmp:/var/tmp:/opt/alt/php73/usr/share/pear/:/dev/urandom:/usr/local/lib/php/:/usr/local/php73/lib/php/ </Directory> </VirtualHost>
Leave a Comment