Running with a Proxy

Posit Connect can be run behind a proxy server. The proxy server needs to be configured so it correctly handles traffic to and from Posit Connect. This section describes how to configure Nginx or Apache HTTPD as a reverse proxy in front of Posit Connect.

Posit Connect needs to receive the original request URL from the reverse proxy so that it can generate fully-qualified URLs and return them to the requesting client. We recommend that proxies add an X-RSC-Request header to requests. The value of the X-RSC-Request header should be the absolute URL of the original request made by the client (e.g. https://connect.proxy.company.com/some/path/).

Some proxies (like Amazon Web Services Elastic Load Balancer, for example), do not make it possible to add custom headers. If the X-RSC-Request header is not supplied, the standard headers X-Forwarded-Proto, X-Forwarded-Host, and X-Forwarded-Port are used in a “best effort” attempt to determine the original request URL.

The X-Forwarded headers are not appropriate when the proxy performs path rewriting (e.g. serving beneath https://proxy.company.com/rsc/). Use X-RSC-Request when path-rewriting. X-RSC-Request takes precedence when both X-RSC-Request and the X-Forwarded headers are supplied.

Use the proxied URL as your Server.Address configuration setting.

; /etc/rstudio-connect/rstudio-connect.gcfg
[Server]
Address = https://connect.proxy.company.com/

If your proxy secures traffic with SSL, but uses an insecure (HTTP) connection to Posit Connect, users of the Posit Connect dashboard may receive a warning stating that Connect is being accessed over an insecure connection. The HTTP.NoWarning setting disables this warning.

; /etc/rstudio-connect/rstudio-connect.gcfg
[HTTP]
NoWarning = true

To support Shiny, Streamlit, and Bokeh apps, the proxy should pass websocket connections through to Posit Connect.

Users are able to upload an image to each application. By default the image is limited to 10MB in size. Note that some proxies may be configured to reject uploads of excessive size. Modify the image size limitation with the Applications.MaxAppImageSize configuration setting.

; /etc/rstudio-connect/rstudio-connect.gcfg
[Applications]
;; Use a 5MB limit
MaxAppImageSize = 5000000

Nginx as reverse proxy

On Ubuntu, a version of Nginx that supports reverse-proxying can be installed using the following command:

sudo apt-get install nginx

On Red Hat, you can install Nginx using the following command:

sudo yum install nginx

On SUSE, you can install Nginx using the following command:

sudo zypper install nginx

Simple configuration

This example configuration lets Nginx act as a reverse proxy to Posit Connect. The configuration does no path rewriting; all requests beneath the URL http://proxy.company.com/ are routed to Connect. The incoming request URI is communicated to Connect using the X-RSC-Request header.

This configuration assumes that Posit Connect running on the same server as the Nginx proxy and listening on port 3939. Update the localhost:3939 references if your proxy and Connect run on different hosts or if Connect is listening on a different port.

http {
  map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
  }
  server {
    listen 80;

    # Disables checking of client request body size.
    client_max_body_size 0;

    location / {
      proxy_set_header X-RSC-Request $scheme://$http_host$request_uri;
      proxy_pass http://localhost:3939;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
      proxy_http_version 1.1;
      proxy_buffering off; # Required for XHR-streaming
    }
  }
}

Restart Nginx after any configuration change.

sudo systemctl restart nginx

Path rewriting configuration

This example configuration lets Nginx act as a reverse proxy to Posit Connect from beneath a custom path (e.g. /positconnect/). All requests beneath the URL http://proxy.company.com/positconnect/ are routed to Connect; requests without the /positconnect/ prefix are not handled. The incoming request URI is communicated to Connect using the X-RSC-Request header.

This configuration assumes that Posit Connect running on the same server as the Nginx proxy and listening on port 3939. Update the localhost:3939 references if your proxy and Connect run on different hosts or if Connect is listening on a different port.

http {
  map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
  }
  server {
    listen 80;

    # Disables checking of client request body size.
    client_max_body_size 0;

    location /rsconnect/ {
      rewrite ^/rsconnect/(.*)$ /$1 break;
      proxy_set_header X-RSC-Request $scheme://$http_host$request_uri;
      proxy_pass http://localhost:3939;
      proxy_redirect / /rsconnect/;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
      proxy_http_version 1.1;
    }
  }
}

Restart Nginx after any configuration change.

sudo systemctl restart nginx

Apache as reverse proxy

The Apache HTTPD server can act as a reverse proxy for Posit Connect.

Install Apache on Ubuntu:

sudo apt-get install apache2

Install Apache on Red Hat:

sudo yum install httpd

Install Apache on SUSE:

sudo zypper install apache2

Our example configurations will use the Apache modules mod_rewrite, mod_headers, mod_proxy_http, and mod_proxy_wstunnel. Enable these modules with the commands:

a2enmod rewrite
a2enmod headers
a2enmod proxy_http
a2enmod proxy_wstunnel

Simple configuration

This example configuration lets Apache act as a reverse proxy to Posit Connect. The configuration does no path rewriting; all requests beneath the URL http://proxy.company.com/ are routed to Connect. The incoming request URI is communicated to Connect using the X-RSC-Request header.

This configuration assumes that Posit Connect running on the same server as the Apache proxy and listening on port 3939. Update the localhost:3939 references if your proxy and Connect run on different hosts or if Connect is listening on a different port.

Depending on the layout of your Apache installation, you may need the Listen and VirtualHost directives in different files.

Listen 80

<VirtualHost *:80>
  RewriteEngine on
  # store variable values with dummy rewrite rules
  RewriteRule . - [E=req_scheme:%{REQUEST_SCHEME}]
  RewriteRule . - [E=http_host:%{HTTP_HOST}]
  RewriteRule . - [E=req_uri:%{REQUEST_URI}]
  # set header with variables
  RequestHeader set X-RSC-Request "%{req_scheme}e://%{http_host}e%{req_uri}e"
  # unprefixed websocket proxying
  RewriteCond %{HTTP:Upgrade} websocket [NC]
  RewriteCond %{HTTP:Connection} upgrade [NC]
  RewriteRule ^/(.*) "ws://localhost:3939/$1" [P,L]

  <Location />
    ProxyPass http://localhost:3939/ connectiontimeout=5
  </Location>
</VirtualHost>

Path rewriting configuration

This example configuration lets Apache act as a reverse proxy to Posit Connect from beneath a custom path (e.g. /positconnect/). All requests beneath the URL http://proxy.company.com/positconnect/ are routed to Connect; requests without the /positconnect/ prefix are not handled. The incoming request URI is communicated to Connect using the X-RSC-Request header.

This configuration assumes that Posit Connect running on the same server as the Apache proxy and listening on port 3939. Update the localhost:3939 references if your proxy and Connect run on different hosts or if Connect is listening on a different port.

Depending on the layout of your Apache installation, you may need the Listen and VirtualHost directives in different files.

Listen 80

<VirtualHost *:80>
  RewriteEngine on

  RewriteRule ^/rsconnect$ /rsconnect/ [R]
  # store variable values with dummy rewrite rules
  RewriteRule . - [E=req_scheme:%{REQUEST_SCHEME}]
  RewriteRule . - [E=h_host:%{HTTP_HOST}]
  RewriteRule . - [E=req_uri:%{REQUEST_URI}]
  # set header with variables
  RequestHeader set X-RSC-Request "%{req_scheme}e://%{h_host}e%{req_uri}e"
  RewriteCond %{HTTP:Upgrade} websocket [NC]
  RewriteCond %{HTTP:Connection} upgrade [NC]
  RewriteRule /rsconnect/(.*) "ws://localhost:3939/$1" [P,L]

  <Location /rsconnect/>
    ProxyPass http://localhost:3939/ connectiontimeout=5
    ProxyPassReverse /rsconnect/
    ProxyPassReverse /
  </Location>
</VirtualHost>