Multi-server Installation

Workbench | Enhanced Advanced

These directions describe a multi-server installation for Posit Workbench in a load-balanced cluster.

For alternative installation instructions, see our recommended installation paths.

This page includes instructions for downloading Posit professional products. Download and/or use of these products is governed under the terms of the Posit End User License Agreement. By downloading, you agree to the terms posted there. The same instructions apply if you still use a legacy RStudio Server Pro license configuration (no launcher enabled).

Prerequisites

Before you install, you must review and meet the Requirements.

This installation has five phases:

  1. Prepare the shared cluster resources
  2. Install Workbench on each node
  3. Configure Workbench
  4. Restart the cluster
  5. Verify the installation

Phase 1: Prepare the shared cluster resources

A load-balanced cluster uses a shared database and shared storage, and optionally an external load balancer. Set up these resources once, before you install Workbench on each node.

Step 1: Create the Postgres database

A Postgres database is required to run Workbench in a load-balanced configuration.

  • Create an empty database for the rstudio-server process to connect to.
  • Do not share this database with other products or services.
  • To use SSL certificate authorization instead of a password, configure Postgres to use SSL with your certificates.

For detailed requirements, see PostgreSQL.

Step 2: Set up shared storage

In a load-balanced configuration, Workbench requires POSIX-compliant shared storage. Shared storage stores the following data:

  • Users’ home directories:
    • Automatic home directory creation requires the NFS home directory storage be configured with no_root_squash
  • Project sharing:
  • Workbench session data:

This guide assumes that your NFS server exports the following drives:

/etc/exports
# Shared storage for user home directories
/var/nfs/workbench/home             *(rw,sync,no_subtree_check,no_root_squash)

# Shared storage for project sharing
/var/nfs/workbench/shared-storage   *(rw,sync,no_subtree_check,no_root_squash)
Tip

This guide uses an NFS server for shared storage. However, other POSIX-compliant shared storage solutions work as well. The most common shared storage solutions are:

Step 3: Set up an external load balancer (optional)

Workbench includes an internal load balancer. We recommend that you also use an external front-end load balancer (such as Nginx or Apache) for stronger cluster resilience. When you configure the external load balancer:

  • Enable sticky sessions for the most efficient operation. Sticky sessions are required if you use SAML for authentication.
  • Use a load balancing method that distributes sessions across the available nodes, such as an IP hash or round robin.
  • Forward websockets correctly between the proxy server and Workbench so that all Workbench functions work correctly. See Forwarding websockets for more details.
  • Configure timeouts of at least 60 seconds. See Check the connection timeout.

To learn more, see:

Phase 2: Install Workbench on each node

After the shared cluster resources are ready, install Workbench on two or more nodes.

Step 1: Install R & Python

Install R

  • Follow the steps to Install R.

    Note

    Our recommended installation instructions for R allow you to make multiple versions of R available and avoid replacing existing versions of R when updating system packages.

Install Python

Installing Python is optional unless you need to run JupyterLab or Jupyter Notebook sessions, or to run Python code in any IDE.

  • Install a version of Python on the server following the steps to Install Python.

    Note

    RStudio Pro and VS Code do not require Python. However, we recommend installing Python to give users the most choice and the option to develop in Python, R, or both.

ImportantPre-installing with cloud-init or EC2 user data

If you pre-install R or Python with a cloud-init or Amazon Elastic Compute Cloud (EC2) user-data script, the script runs once at first boot, before networking is fully established. If the network is not ready, apt-get and curl can fail silently and leave a server with no runtimes installed. Before you start Workbench, confirm that R and Python are present on the server. If either runtime is missing, re-run the Install R and Install Python steps.

Step 2: Download and install

  • If you need to use Workbench with SELinux in enforcing mode, follow the steps provided in the Access and Security - SELinux Configuration documentation to install the SELinux policy module.

  • Download and install Workbench version 2026.09.0:

RHEL 9 / 10
Terminal
curl -O https://download2.rstudio.org/server/rhel9/x86_64/rstudio-workbench-rhel-2026.09.0-x86_64.rpm
sudo yum install rstudio-workbench-rhel-2026.09.0-x86_64.rpm
RHEL 8
Terminal
curl -O https://download2.rstudio.org/server/rhel8/x86_64/rstudio-workbench-rhel-2026.09.0-x86_64.rpm
sudo yum install rstudio-workbench-rhel-2026.09.0-x86_64.rpm
Terminal
curl -O https://download2.rstudio.org/server/jammy/amd64/rstudio-workbench-2026.09.0-amd64.deb
sudo apt-get install ./rstudio-workbench-2026.09.0-amd64.deb
Terminal
curl -O https://download2.rstudio.org/server/opensuse15/x86_64/rstudio-workbench-2026.09.0-x86_64.rpm
sudo zypper install rstudio-workbench-2026.09.0-x86_64.rpm
Note

You download a package named rstudio-workbench, but the installed service and management commands use rstudio-server. For example, you manage the service with sudo rstudio-server restart. This naming reflects the product’s earlier name, RStudio Server Pro.

Upon installation, Workbench configuration file (/etc/rstudio/rserver.conf) contains a default configuration to run Workbench using local launcher sessions, without SSL enabled, listening on port 8787.

We strongly recommend running Workbench on a secured network or enabling TLS/SSL. Review the Secure Sockets (SSL) documentation before you continue the installation.

For air-gapped (offline) environments, download the files on a connected machine and securely copy them to the air-gapped environment following your approved process. Then, proceed to Step 3: Activate license and follow the offline activation option.

Step 3: Activate license

Run the following command to determine the status of your license:

sudo rstudio-server license-manager status

Posit recommends using license file activation. License files work well in all environments including ephemeral, container-based, or air-gapped environments. See License activation methods or the License Management page for more details.

If you have a license file:

  1. Transfer the file to the server hosting Workbench.

  2. Ensure the license file is owned by the Workbench service user and is not readable by other users, then copy the file into /var/lib/rstudio-server:

    sudo chown rstudio-server <license-file>.lic
    sudo chmod 0600 <license-file>.lic
    sudo cp -a <license-file>.lic /var/lib/rstudio-server/
Note

The default Workbench server-user user is rstudio-server. If your installation is configured with a different server-user, ensure the file is owned by that user.

  1. If the server uses SELinux in enforcing mode, update the security context on the license file:

    sudo restorecon /var/lib/rstudio-server/<license-file>.lic
  2. Restart Workbench for the license to take effect:

    sudo rstudio-server restart

Phase 3: Configure Workbench

This phase covers configuring Workbench to run in a load-balanced configuration.

Step 1: Configure networking

Expose the following ingress ports on each node running Workbench:

Port Range Description
22 Port 22 is exposed for SSH access.
8787 If using HTTP, by default, Workbench runs on port 8787. This guide will use HTTP.
443 If using HTTPS, Workbench runs on port 443.
5559 By default, Launcher runs on port 5559.
ip_local_port_range, for example 32000 - 65535 When using Local Launcher, a wide range of ephemeral ports must be open for Launcher to claim. This port range is determined using the ip_local_port_range parameter. To determine the range for your instance, run the following command sudo cat /proc/sys/net/ipv4/ip_local_port_range. Then, adjust the firewall to allow node-to-node communication across the port range. For more details, see launcher-local-proxy setting.

For more information, see Networking.

Step 2: Mount shared storage

Mount two directories on each node running Workbench:

  • Home directories: The users’ home directories must exist in shared storage and be accessible to each node.
  • Shared storage: An explicit directory must exist in shared storage and be accessible to each node to be used by Workbench.

Run the following commands on each Workbench node to install nfs-common and mount the NFS directories. If you use existing shared storage, change the local and mount paths as required:

# Install nfs-common
sudo apt-get update
sudo apt-get install -y nfs-common

# Replace this value with the IP address for your NFS server
NFS_HOST="<REPLACE-WITH-YOUR-NFS-HOST>"

# Create the directories for the NFS mount
sudo mkdir -p /nfs/workbench/home
sudo mkdir -p /nfs/workbench/shared-storage

# Define the mount configuration
sudo tee -a /etc/fstab <<EOF
${NFS_HOST}:/var/nfs/workbench/home             /nfs/workbench/home              nfs auto,noac,nofail,noatime,nolock,intr,tcp,actimeo=1800,lookupcache=pos 0 0
${NFS_HOST}:/var/nfs/workbench/shared-storage   /nfs/workbench/shared-storage    nfs auto,noac,nofail,noatime,nolock,intr,tcp,actimeo=1800,lookupcache=pos 0 0
EOF

# Mount all of the mount points in /etc/fstab
sudo mount -av
Important

You must use the lookupcache=pos option when multiple Workbench nodes share the NFS file system. It caches positive lookups, but does not cache negative ones, so a stale not-found entry does not mask a file created on another node.

While this might cause poorer lookup-cache performance, it prevents difficult-to-diagnose intermittent file-consistency errors.

Change the owner of the directories:

  • /nfs/workbench/home: Should be owned by root:root.
  • /nfs/workbench/shared-storage: Should be owned by nobody:nogroup. For more information on the recommended mount options, refer to Project sharing and NFS.
sudo chown -R root:root /nfs/workbench/home
sudo chown -R nobody:nogroup /nfs/workbench/shared-storage

Step 3: Provision users

Because Workbench requires each user to have a Unix account and a home directory, each node in the cluster must have the following:

  • A Unix account for each user with consistent IDs.
  • Access to the users’ home directories.

This guide presents two common options for provisioning users:

For example, say you have two users: user1 and user2. To manually provision these users, do the following:

  • On one node only, run the following commands to create the user and a home directory in shared storage:
# Create user1
NAME="user1"
PASSWORD="password"
sudo useradd --create-home --home-dir /nfs/workbench/home/$NAME -s /bin/bash $NAME
echo -e "${PASSWORD}\n${PASSWORD}" | sudo passwd $NAME

# Create user2
NAME="user2"
PASSWORD="password"
sudo useradd --create-home --home-dir /nfs/workbench/home/$NAME -s /bin/bash $NAME
sudo echo -e "${PASSWORD}\n${PASSWORD}" | sudo passwd $NAME
  • On all other nodes, run the following commands to create the users. You do not need to re-create the home directories:
# Create user1
NAME="user1"
PASSWORD="password"
sudo useradd --home-dir /nfs/workbench/home/$NAME -s /bin/bash $NAME
echo -e "${PASSWORD}\n${PASSWORD}" | sudo passwd $NAME

# Create user2
NAME="user2"
PASSWORD="password"
sudo useradd --home-dir /nfs/workbench/home/$NAME -s /bin/bash $NAME
echo -e "${PASSWORD}\n${PASSWORD}" | sudo passwd $NAME
Warning

Do not use password as your password; set a unique and secure password for each user.

Many customers automate user provisioning with SSSD. For more details, see Provisioning with sssd.

The following is an example SSSD configuration file. Your configuration depends on your Active Directory or LDAP setup. In this example:

  • override_homedir ensures home directories are created in the shared storage.
/etc/sssd/sssd.conf
[sssd]
config_file_version = 2
services = nss, pam
domains = LDAP

[nss]
filter_users = root,named,avahi,haldaemon,dbus,radiusd,news,nscd
filter_groups =

[pam]

[domain/LDAP]
default_shell = /bin/bash
override_homedir = /nfs/workbench/home/%u
id_provider = ldap
auth_provider = ldap
chpass_provider = ldap
sudo_provider = ldap
enumerate = true
cache_credentials = false
ldap_schema = rfc2307
ldap_uri = "<REPLACE-WITH-YOUR-VALUE>"
ldap_search_base = dc=example,dc=org
ldap_user_search_base = dc=example,dc=org
ldap_user_object_class = posixAccount
ldap_user_name = uid
ldap_group_search_base = dc=example,dc=org
ldap_group_object_class = posixGroup
ldap_group_name = cn
ldap_id_use_start_tls = false
ldap_tls_reqcert = never
ldap_tls_cacert = /etc/ssl/certs/ca-certificates.crt
ldap_default_bind_dn = cn=admin,dc=example,dc=org
ldap_default_authtok = admin
access_provider = ldap
ldap_access_filter = (objectClass=posixAccount)
min_id = 1
max_id = 0
ldap_user_uuid = entryUUID
ldap_user_shell = loginShell
ldap_user_uid_number = uidNumber
ldap_user_gid_number = gidNumber
ldap_group_gid_number = gidNumber
ldap_group_uuid = entryUUID
ldap_group_member = memberUid
ldap_auth_disable_tls_never_use_in_production = true
use_fully_qualified_names = false
ldap_access_order = filter

Step 4: Set the configuration files

Set the following configuration files on each node in the Workbench cluster.

Note

To avoid maintaining a separate copy of these files on every node, store the shared configuration files on the cluster’s shared storage and point each node at that location. Set XDG_CONFIG_DIRS (or RSTUDIO_CONFIG_DIR) on each node so that Workbench reads its configuration from the shared directory. For example, XDG_CONFIG_DIRS=/etc:/shared/etc reads node-local files from /etc/rstudio and shared files from /shared/etc/rstudio. See Alternate configuration file location.

Keep workbench-nss.conf at /etc/rstudio/workbench-nss.conf on every node. The NSS module does not read XDG_CONFIG_DIRS or RSTUDIO_CONFIG_DIR. See Workbench NSS configuration.

/etc/rstudio/rserver.conf

Set server-shared-storage-path to a location in shared storage:

sudo tee -a /etc/rstudio/rserver.conf <<EOF
server-shared-storage-path=/nfs/workbench/shared-storage
EOF

Open rserver.conf and set load-balancing-enabled=1. The file already sets load-balancing-enabled=0, so edit that line:

load-balancing-enabled=1

See rserver.conf for all configuration options.

/etc/rstudio/launcher.conf

Open launcher.conf and set address=0.0.0.0. The file already sets address=localhost, so edit that line:

address=0.0.0.0

See Launcher Configuration for all configuration options.

/etc/rstudio/database.conf

Before you create the database configuration file, decide whether to authenticate Workbench with the PostgreSQL server by password or by SSL certificate.

Run the appropriate snippet below to create or append to /etc/rstudio/database.conf. Then copy this file and the secure-cookie-key file to all nodes in the cluster.

For password authorization
# Replace the variables with the appropriate value for your database
POSTGRES_HOST="localhost"
POSTGRES_DB="rstudio"
POSTGRES_USER="rstudio"
POSTGRES_PASSWORD="<plain-text-password>"

POSTGRES_PASSWORD_ENCRYPTED=$(echo $POSTGRES_PASSWORD | sudo rstudio-server encrypt-password)

sudo tee -a /etc/rstudio/database.conf <<EOF
provider=postgresql
password=${POSTGRES_PASSWORD_ENCRYPTED}
connection-uri=postgresql://${POSTGRES_USER}@${POSTGRES_HOST}:5432/${POSTGRES_DB}?sslmode=allow
EOF
For SSL certificate authorization
# Replace the variables with the appropriate value for your database
POSTGRES_HOST="<REPLACE-WITH-YOUR-VALUE>"
POSTGRES_DB="<REPLACE-WITH-YOUR-VALUE>"
POSTGRES_USER="<REPLACE-WITH-YOUR-VALUE>"
POSTGRES_SSL_CERT="<REPLACE-WITH-PATH-TO-CERT>"
POSTGRES_ROOT_CERT="<REPLACE-WITH-PATH-TO-CERT>"
POSTGRES_SSL_KEY="<REPLACE-WITH-PATH-TO-KEY>"


sudo tee -a /etc/rstudio/database.conf <<EOF
provider=postgresql
connection-uri=postgresql://${POSTGRES_USER}@${POSTGRES_HOST}:5432/${POSTGRES_DB}?sslcert=${POSTGRES_SSL_CERT}&sslkey=${POSTGRES_SSL_KEY}&sslrootcert=${POSTGRES_ROOT_CERT}
EOF

See PostgreSQL for additional PostgreSQL configuration options.

(Optional) /etc/rstudio/load-balancer

Configure any custom settings in /etc/rstudio/load-balancer. See Configuration for detailed options.

Phase 4: Restart the cluster

After you finish configuring Workbench:

  • Restart the Workbench service (run on all nodes):

    sudo systemctl restart rstudio-server
  • Restart the Launcher service (run on all nodes):

    sudo systemctl restart rstudio-launcher

Phase 5: Verify the installation

After completing the steps above, Workbench should be running in a load-balanced configuration.

Run the following command from one of the Workbench nodes to verify that Workbench is aware of all the nodes in the cluster:

sudo rstudio-server list-nodes

To verify that Workbench is operating correctly, do the following:

  • Open Workbench in a new browser tab:

    • If you use an external load balancer, use its URL.
    • If you do not use an external load balancer, use the URL for one of the nodes in the cluster.
  • Log into Workbench using your username and password.

  • Click the + New Session button. Clear the Auto-join session check box. Then, launch four RStudio Pro sessions.

  • After the sessions are running, open each session and confirm that you can use the IDE.

  • SSH into any one of the Workbench nodes and run the following commands:

    curl http://localhost:8787/load-balancer/status
    # ip-172-31-29-53:8787 - 172.31.29.53  Load: 0.0063, 0.019, 0
    #    48751 - user1
    #    39972 - user1
    #
    # ip-172-31-28-224:8787 - 172.31.28.224  Load: 0.051, 0.041, 0.029
    #    39959 - user1
    #    40055 - user1

    You should see four sessions running. These sessions should be distributed across the two nodes.

  • If all sessions are on the same node, run an R script in one of the sessions to consume node resources. For example:

    test.R
    df <- data.frame(
        x = c(1:1000000),
        y = c(1:1000000)
    )
    
    for (i in c(1:500)) {
        print(i)
        fit <- lm(x ~ y, df)
    }
  • Then create new sessions until you confirm that Workbench distributes them across the nodes.

  • Next, launch one session for the other three IDEs:

    • Jupyter Notebook
    • JupyterLab
    • VS Code
  • After the sessions start, open each session and confirm that you can use the IDE.

Next steps

After you install and verify the cluster, complete the Initial Configuration to secure the server and set up authentication before users sign in.

Additional information

Additionally:

  • Job Launcher: This is the tooling that provides the ability for Posit Workbench to start processes locally. Job Launcher is required to start JupyterLab, Jupyter Notebook, and VS Code sessions. The focus of this guide uses the Local Plugin. Workbench can also be configured with other plugins such as the Slurm Plugin and the Kubernetes Plugin.
  • Local Plugin: This is a Job Launcher plugin that launches executables on the local machine (the same machine on which the Launcher is running).
  • Load balancing: Refers to Workbench’s ability to be configured to load balance sessions across two or more nodes within a cluster. This provides both increased capacity as well as higher availability.
  • Upgrading Positron: When upgrading Positron in a load-balanced cluster, you must perform the upgrade on each node. See the load-balanced deployments section for the procedure.

When combined with load balancing, the Job Launcher and Local Plugin can launch sessions across different nodes in the cluster. Launcher with the Local Plugin is enabled by default.

flowchart LR
accTitle: Mermaid diagram
accDescr {
A mermaid diagram showing a map example of how the job launcher and local plugin combined with load balancing allows you to launch sessions across different nodes in a cluster.
}
u1(User)
u2(User)
u3(User)
b1(Browser)
b2(Browser)
b3(Browser)
workbench1(Workbench)
workbench2(Workbench)
session(RStudio Session)
jupyter(Jupyter Session)
vscode(VS Code Session)
job(Workbench Job)
lb(External Load Balancer)
nfs(Shared Storage)
pg(Postgres)
u1---b1
u2---b2
u3---b3
b1---lb
b2---lb
b3---lb
lb---workbench1
lb---workbench2
server1-.-nfs
server2-.-nfs
server1-.-pg
server2-.-pg
subgraph server1 [Linux Server]
    workbench1---jupyter
    workbench1---job
end
subgraph server2 [Linux Server]
    workbench2---session
    workbench2---vscode
end
workbench1-.-workbench2
classDef server fill:#e27e53,stroke:#ab4d26
classDef product fill:#447099,stroke:#213D4F,color:#F2F2F2
classDef session fill:#7494B1,color:#F2F2F2,stroke:#213D4F
classDef req fill:#72994E,stroke:#1F4F4F
class server1,server2 server
class workbench1,workbench2 product
class session,jupyter,vscode,job session
class u1,u2,u3,b1,b2,b3,lb element
class pg,nfs req

Back to top