Running ShinyApps from RStudio-Server behind Nginx proxy

Hi,

I'm running Rstudio Server behind a Nginx-proxy on the same machine. Everything works fine sofar. But when I develop a ShinyApp and click RunApp. The App opens in a new Browser Tab but is grey. The url is /p/3568. When I bypass Nginx and access RS-server directly via :8787 it works fine.

Is there a way to configure Nginx such that starting the ShinyApp works?

Can you share your nginx configuration? see here for the official documentation http://docs.rstudio.com/ide/server-pro/access-and-security.html#running-with-a-proxy

Hi, I actually edited the config file according to the manual. And it works sofar. The only thing is running a ShinyApp. R obviously starts a little shinyserver locally and deploys the app on port 3568.

I assume, I have to tell nginx the port somehow. Unfortunately, I don't know how.

Here ist my nginx config
nginx.conf

http {

        map $http_upgrade $connection_upgrade {
                default upgrade;
                ''      close;
        }
.
.
.

sites-enabled/default:

server {
        listen 80 default_server;
        listen [::]:80 default_server;
        
#        rewrite ^/rstudio$ $scheme://$host/rstudio/ permanent;

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

The only difference is the $connection_upgrade ist defined in the http-part in nginx.conf. sites-enabled/default is than included at the end of nginx.conf with

include /etc/nginx/sites-enabled/*;

Thx.

I don't see anything obvious in the code you quote. Can you provide a complete but minimal example that shows the error?

Here a minimal working example with two files:

docker-compose.yml

version: '3.1'

services:
    proxy:
        image: nginx:alpine
        ports:
            - 80:80
        volumes:
            - ./default.conf:/etc/nginx/conf.d/default.conf


    rstudio:
        image: rocker/rstudio:3.5.1
        environment:
            PASSWORD: password

default.conf

  map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
  }

  server {
    listen 80;

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

After docker-compose up I can access http://localhost/rstudio and create and test Shiny applications.

Hi,

I just tested the same kind of thing. I logged into the machine were the proxy and rstudio server are running (so same scenario like in the docker example) and accessed http://localhost/rstudio and indeed it works. However, when I try to connect remotely to the server it fails.
Can you maybe try to connect to your docker-image remotely?

Here is error from the Chrome console:

shinyapp.js:310 Uncaught TypeError: Cannot read property 'readyState' of null
    at ShinyApp.$sendMsg (shinyapp.js:310)
    at ShinyApp.sendInput (shinyapp.js:140)
    at InputBatchSender.$sendNow (input_rate.js:220)

Unfortunately, it doesn't help me to figure out the problem.

I have no difficulty with using a Shiny app with my docker set-up when connecting from a different computer. Your error message might be helpful, though. Line 310 of shinyapp.js is here: https://github.com/rstudio/shiny/blob/c332c051f33fe325f6c2e75426daaabb6366d50a/srcjs/shinyapp.js#L310 That is in the part that handles websocket communication, which is something that normal RStudio Server does not use that [1]. Since it does work locally, my guess would be that your proxy is set-up correctly, but there is some other proxy or similar between you and the server that drops websocket connections.

[1] IIRC it is also used for accessing the terminal. Does that work for you?

I think we are getting closer. The terminal is not starting correctly from remote but works locally. Obviously, the websockets are dropped. However, when I bypass nginx and connect directly to //<server>:8787 it works flawless. This is why I thought something is wrong with my nginx conf.

It could still be some sort of proxy that ignores traffic on port 8787. But if you suspect a problem with your nginx configuration, then try to build an example that is both minimal and complete.

Hey I had the same problem and solved it with the following nginx.confs.
I have to mention, that I'm using a subdomain and tls encryption via an letsencrypt cert.

server {
        listen 80;
        listen [::]:80;
        server_name rstudio.example.com;
        include /etc/nginx/snippets/letsencrypt.conf;
        location / {
                return 302 https://$server_name$request_uri;
        }
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    #include certs
    include snippets/letsencrypt_certs.conf;
    ssl_protocols TLSv1.2;

    # set max upload size
    client_max_body_size 512M;
    fastcgi_buffers 64 4K;    

    server_name rstudio.example.com;

    location / {
        proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "upgrade";
		proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 90s;
        
        # Connect to local port
        proxy_pass http://127.0.0.1:8787;
    }
}

with "proxy_read_timeout XYZ;" you can prevent nginx to close the proxy after 60s of inactivity.