Skip to content

Programmatic Deployment with rsconnect#

Overview#

It is possible to use the rsconnect R package to programmatically deploy content to a Connect server. Furthermore, Connect-hosted content can use rsconnect to deploy additional content to itself or to another Connect server.

Note

Posit Connect includes experimental HTTP APIs that let you build your own deployment workflows. Those APIs will replace the rsconnect package as the preferred way to perform programmatic deployment. The Deploying Content recipes in the Posit Connect API Cookbook will get you started with the content APIs. All of the Content API endpoints are described in the Posit Connect API Reference.

Configuring Connect to deploy content with rsconnect requires:

  1. administrator privileges for Connect, and
  2. sudo or root privileges on the server where Connect is installed.

Use Case: A Shiny Application#

Here we present a use case that explains how to configure Connect for programmatic deployment; code for our example Shiny application is also available.

Use Case Scenario#

Bob White develops a Shiny application that:

  1. Renders an R Markdown document.
  2. Deploys the generated document using rsconnect

Bob deploys his Shiny application to Connect. The application, as noted above, can automatically deploy documents it generates to Connect. However, the Connect server must first be configured to authorize deployment from rsconnect.

Installing rsconnect#

The rsconnect package is not yet available on Bob's Connect server, so Bob installs it by running R as root (sudo R) and issuing the following command in the R console. In practice, rsconnect may already be available.

install.packages("rsconnect")

Configuring a Custom "RunAs" User#

Since Bob does not want to allow arbitrary Connect users to deploy content using rsconnect, he configures a custom RunAs user, robert, for his Shiny application. See the User Account for Processes section for configuring the RunAs user on a per-application basis in Connect.

Configuring rsconnect#

Important

rsconnect configuration requires a user home directory. In this use case, a valid home directory is required for the robert user account.

Since Bob's Shiny application will be running as the robert user, Bob (at a server console) switches to the robert user:

sudo su robert

Next, while running as robert, Bob runs R and issues the following commands in the R console:

library(rsconnect)
rsconnect::addConnectServer('http://myserveraddress:3939', 'mylocaldeployserver')
rsconnect::connectUser(server='mylocaldeployserver')

Note

The rsconnect server name, mylocaldeployserver, is an arbitrary name that is used to identify a Connect server when using rsconnect. You can choose any name you wish.

After the last command, Bob sees the following output:

A browser window should open; if it doesn't, you may authenticate manually by visiting http://myserveraddress:3939/__login__?url=......

Waiting for authentication...

Bob copies the URL in the output above and pastes it into a Web browser. Then Bob authenticates with his Connect user credentials. Bob's Connect user name (with publishing privileges) is rwhite.

After successfully connecting his Connect account to rsconnect, Bob sees this message at the R console:

Account registered successfully: Bob White (rwhite)

The server and account information are persisted to configuration files on the server in Bob's home directory:

/home/robert/.config/R/connect/servers/mylocaldeployserver.dcf
/home/robert/.config/R/connect/accounts/mylocaldeployserver/connectuser.dcf

Deploying Content with rsconnect#

Now rsconnect is configured to use the rwhite Connect account when running with the robert server account. If Bob's Shiny application uses robert as its RunAs user, it can deploy content using rsconnect.

CRAN Note#

If you don't already have it in an RProfile, be sure to specify a default CRAN repository in your application before issuing the rsconnect command to deploy content. For example:

options(repos=c(CRAN="https://cran.rstudio.com"))
rsconnect::deployDoc(doc="out.Rmd", appName="ServerDeployedDoc",
                     account="rwhite", server="mylocaldeployserver")

Warning and Security Information#

Please restrict access to any Connect content that can deploy arbitrary content via rsconnect. The Connect Dashboard's "Permissions" document provides details on securing content in Connect.

Do not enable deployment via rsconnect for the default Applications.RunAs user; if you do so, all your Connect users will be able to deploy content using your rsconnect credentials.

Once a Connect user authorizes rsconnect to deploy content under a particular server account, any content that runs under that server account can use rsconnect to deploy content without further authentication.

For example, Bob logs in to a server console as Unix user robert. Bob then configures rsconnect to deploy content. During the authorization step, Bob signs in to Connect as a publisher with user name rwhite. Now, any Connect application that is configured with a RunAs user of robert can deploy additional content using the Connect user rwhite, regardless of who owns the application.

Example Shiny Application#

Below is an example Shiny application that knits R Markdown text and deploys the resulting content using rsconnect.

library(knitr)
library(rsconnect)
library(shiny)
library(shinyAce)
library(rmarkdown)

# Default text for editor
defaultMarkdown <- '
### Sample R Markdown
This is some markdown text. It may also have embedded R code
which will be executed.
'

# A Shiny UI for editing R Markdown
ui <- shinyUI(
  bootstrapPage(
    headerPanel("Embedded Deployment Example"),
    div(
      class="container-fluid",
      div(class="row-fluid",
          div(class="col-sm-6",
              h2("Source R-Markdown"),
              aceEditor("rmd", mode="markdown", value=defaultMarkdown),
              actionButton("eval", "Update")
          ),
          div(class="col-sm-6",
              h2("Knitted Output"),
              htmlOutput("knitDoc")
          )
      )
    )
  )
)

# A Shiny application that generates and deploys R Markdown content
server <- shinyServer(function(input, output, session) {

  # Only update and deploy when the 'Update' button is clicked
  rmd <- eventReactive(input$eval, {
    input$rmd
  })

  output$knitDoc <- renderUI({
    writeLines(rmd(), "out.Rmd")
    knit2html(input="out.Rmd", fragment.only = TRUE, quiet = TRUE)
    options(repos=c(CRAN="https://cran.rstudio.com"))
    rsconnect::deployDoc(doc="out.Rmd", appName="GeneratedDoc",
                         account="rwhite", server="mylocaldeployserver")
    return(isolate(HTML(
      readLines("out.html")
    )))
  })
})

# Run the application
shinyApp(ui = ui, server = server)