Search code examples
httpnginxhttpsshinyshiny-server

How to replace http address to https for Shiny App


I have a Shiny app hosted in Digitalocean with Web-server as Nginx. The Web-address looks like

http://www.exacmple.com/ShinyApp

However I wish if I could change the http to https. i.e. all request to this App would be routed to https://www.exacmple.com/ShinyApp

I already have SSL certificate installed from letsencrypt, and certificate file is placed at below addresses:

/etc/letsencrypt/live/example.com/fullchain.pem;
/etc/letsencrypt/live/example.com/privkey.pem;

Currently, my Nginx Proxy file is set like below:

##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# http://wiki.nginx.org/Pitfalls
# http://wiki.nginx.org/QuickStart
# http://wiki.nginx.org/Configuration
#
# Generally, you will want to move this file somewhere, and start with a clean
# file but keep this around for reference. Or just disable in sites-enabled.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##

# Default server configuration
#
  map $http_upgrade $connection_upgrade {
      default upgrade;
      ''      close;
    }



server {
    listen 80 default_server;
    listen [::]:80 default_server;
        server_name example.com www.example.com;
    if ($http_host = example.com) {
            rewrite  (.*)  https://www.example.com$1;
          }



    root /var/www/html;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
    }

location /ShinyApp/ {
      rewrite ^/ShinyApp/(.*)$ /$1 break;
      proxy_pass http://localhost:4242;    
      proxy_redirect http://localhost:4242/ $scheme://$host/ShinyApp/;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
      proxy_read_timeout 20d;
      proxy_buffering off;
    }
}

To implement for https, I have appended this file as below (the location section)

location /ShinyApp/ {
      rewrite ^/ShinyApp/(.*)$ /$1 break;
      SSLEngine on
      ssl_certificate           /etc/letsencrypt/live/example.com/fullchain.pem;
       ssl_certificate_key       /etc/letsencrypt/live/example.com/privkey.pem;

      ProxyPreserveHost On
      proxy_pass http://localhost:4242;
      roxyPassReverse http://localhost:4242;
      proxy_redirect http://localhost:4242/ $scheme://$host/ShinyApp/;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
      proxy_read_timeout 20d;
      proxy_buffering off;
    }

However above change fails to implement https request.

I have gone through various suggestions available over Web (e.g. HTTPS for Shiny apps?) however failed to find any workable solution.

Any pointer towards the right direction would be very helpful.

Thanks,


Solution

  • Common practice for this is to use two server blocks:

    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name example.com www.example.com;
        return 301 https://$host$request_uri;
    }
    
    server {
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        server_name example.com www.example.com;
        ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
        ... # root, index and other top-level directives here
        location /ShinyApp/ {
            # your backend configuration here
        }
    }
    

    Don't use ssl_certificate and ssl_certificate_key directives inside a location blocks, pay attention on a context in which nginx directives may or may not be used. SSLEngine, ProxyPreserveHost and ProxyPassReverse are apache directives, remove them! Test your configuration with nginx -t before reloading nginx with a new configuration.