Deploying a Shiny App
You’ve built an amazing Shiny app locally—now it’s time to share it with the world. Deployment is the final step in the Shiny development workflow, and fortunately R makes this remarkably straightforward. In this tutorial, we’ll cover the three most popular deployment platforms: shinyapps.io, RStudio Connect, and Docker-based deployments.
Prerequisites
Before deploying your app, ensure you have:
- A working Shiny app in a standalone script (
app.R) or as a folder withapp.Randwww/assets - An account on your chosen deployment platform
- The
rsconnectpackage installed:
install.packages("rsconnect")
Deploying to shinyapps.io
shinyapps.io is the easiest way to deploy Shiny apps. It’s a hosted service by Posit (formerly RStudio) that handles all server infrastructure for you.
Step 1: Connect Your Account
First, authorize rsconnect to access your shinyapps.io account:
library(rsconnect)
rsconnect::setAccountInfo(name = "your-account-name",
token = "YOUR_TOKEN",
secret = "YOUR_SECRET")
You get these credentials from your shinyapps.io dashboard under the “Tokens” tab.
Step 2: Deploy Your App
Deploying is a single function call:
library(shiny)
rsconnect::deployApp("path/to/your/app")
For a simple app.R in your current directory:
rsconnect::deployApp(".")
The first deployment uploads all your app’s dependencies, which may take a minute. Subsequent deployments are faster since rsconnect caches unchanged files.
Example: Deploying the diamonds explorer
# Create a simple app
ui <- fluidPage(
titlePanel("Diamond Explorer"),
selectInput("cut", "Select Cut:", choices = unique(diamonds$cut)),
plotOutput("hist")
)
server <- function(input, output) {
output$hist <- renderPlot({
library(ggplot2)
ggplot(diamonds[diamonds$cut == input$cut, ],
aes(carat)) + geom_histogram()
})
}
shinyApp(ui, server)
# Deploy it
rsconnect::deployApp(".")
After deployment, you’ll receive a URL like https://your-name.shinyapps.io/diamond-explorer/.
Deploying to RStudio Connect
RStudio Connect is a professional platform for sharing data products within organizations. It supports Shiny apps, R Markdown reports, APIs, and more.
Configuration
First, configure the server connection:
rsconnect::connectServer(url = "https://your-server.com",
apiKey = "your-api-key")
Get your API key from the RStudio Connect user settings.
Deployment
Deploy using the same deployApp() function:
rsconnect::deployApp("path/to/app",
server = "your-server-name",
account = "your-username")
Access Control
RStudio Connect lets you control who accesses your app:
# Make app visible to specific users
rsconnect::setAccessRecord(
appName = "my-shiny-app",
users = c("user1@company.com", "user2@company.com"),
accessType = "viewer"
)
Docker Deployment
For maximum control, deploy Shiny apps in Docker containers. This works on any cloud platform (AWS, GCP, Azure, DigitalOcean).
Create a Dockerfile
FROM rocker/shiny-verse:latest
# Install dependencies
RUN R -e "install.packages(c('shiny', 'ggplot2', 'dplyr'))"
# Copy app files
COPY app.R /srv/shiny/
COPY www /srv/shiny/www/
# Expose port
EXPOSE 3838
# Run Shiny Server
CMD ["R", "-e", "shiny::runApp('/srv/shiny', port = 3838, host = '0.0.0.0')"]
Build and Run
docker build -t my-shiny-app .
docker run -p 3838:3838 my-shiny-app
Push to Container Registry
docker tag my-shiny-app registry.example.com/my-shiny-app:latest
docker push registry.example.com/my-shiny-app:latest
Deployment Best Practices
1. Use renv for Reproducibility
The renv package locks your dependencies to ensure consistent behavior:
install.packages("renv")
renv::init()
renv::snapshot()
Commit renv.lock to version control. When deploying, rsconnect uses this file to install exact package versions.
2. Handle Secrets Properly
Never hardcode API keys or passwords in your app. Use environment variables:
api_key <- Sys.getenv("MY_API_KEY")
On shinyapps.io, add secrets via the dashboard’s “Variables” tab.
3. Optimize App Size
Large apps take longer to deploy. Remove unnecessary packages:
# Instead of library(ggplot2), use specific imports
library(dplyr, exclude = "filter")
4. Set Appropriate Resources
In shinyapps.io, configure instance size based on your app’s needs:
| Plan | Memory | Concurrent Users |
|---|---|---|
| Free | 1 GB | 25 |
| Starter | 2 GB | 50 |
| Professional | 8 GB | 200 |
Troubleshooting Deployment Issues
Package Not Available
If deployment fails with “package X is not available”:
- Check the package supports your R version
- Verify the package is on CRAN or a valid repository
- For GitHub packages, use
install_github()in your app before deploying
App Loads but Shows Errors
Enable debugging:
rsconnect::deployApp(".",
appName = "my-app",
launch.browser = FALSE,
lint = TRUE)
Connection Timeout
Increase the timeout in your rsconnect configuration or switch to a larger instance plan.
Updating Your Deployed App
After making changes to your app locally, redeploy with the same command:
rsconnect::deployApp(".")
The rsconnect package detects changes and uploads only modified files. To force a full redeploy (useful if dependency issues occur):
rsconnect::deployApp(".", forceRebuild = TRUE)
Scheduling and Background Tasks
RStudio Connect supports scheduled rendering and background jobs. This lets your app refresh data periodically:
# In an R Markdown report context
rmarkdown::render("report.Rmd",
params = list(refresh = TRUE))
Set up schedules through the RStudio Connect dashboard for automatic report generation.
Summary
Deploying Shiny apps is straightforward with the right platform:
- shinyapps.io: Easiest—fully managed, great for learning and small projects
- RStudio Connect: Best for organizations needing security and access control
- Docker: Maximum flexibility for custom infrastructure
Key takeaways:
- Use
rsconnect::deployApp()for most deployments - Leverage
renvfor reproducible environments - Store secrets in environment variables, never in code
Your app is now live and accessible to the world!