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:
- administrator privileges for Connect, and
- 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:
- Renders an R Markdown document.
- 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)