deploy-shiny-app
Deploy Shiny App
Deploy a Shiny application to shinyapps.io, Posit Connect, or a Docker container.
When to Use
- Publishing a Shiny app for external or internal users
- Moving from local development to a hosted environment
- Containerizing a Shiny app for Kubernetes or Docker deployment
- Setting up automated deployment pipelines
Inputs
- Required: Path to the Shiny application
- Required: Deployment target (shinyapps.io, Posit Connect, or Docker)
- Optional: Account name and token (for shinyapps.io/Connect)
- Optional: Instance size preference
- Optional: Custom domain or URL path
Procedure
Step 1: Prepare the Application
Ensure the app is self-contained and deployable:
# Check for missing dependencies
rsconnect::appDependencies("path/to/app")
# For golem apps, ensure DESCRIPTION lists all Imports
devtools::check()
# Verify the app runs cleanly
shiny::runApp("path/to/app")
Verify these files exist:
app.R(orui.R+server.R)renv.lock(recommended for reproducible deployments).Rprofiledoes NOT callmcptools::mcp_session()in production
Expected: App runs locally without errors and all dependencies are captured.
On failure: If appDependencies() reports missing packages, install them and update renv.lock. If the app uses system libraries (e.g., gdal, curl), note them for the Docker path.
Step 2a: Deploy to shinyapps.io
# One-time account setup
rsconnect::setAccountInfo(
name = "your-account",
token = Sys.getenv("SHINYAPPS_TOKEN"),
secret = Sys.getenv("SHINYAPPS_SECRET")
)
# Deploy
rsconnect::deployApp(
appDir = "path/to/app",
appName = "my-app",
appTitle = "My Application",
account = "your-account",
forceUpdate = TRUE
)
Store credentials in .Renviron (never in code):
# .Renviron
SHINYAPPS_TOKEN=your_token_here
SHINYAPPS_SECRET=your_secret_here
Expected: App deployed and accessible at https://your-account.shinyapps.io/my-app/.
On failure: If authentication fails, regenerate tokens at shinyapps.io dashboard > Account > Tokens. If package installation fails on the server, check that all packages are available on CRAN — shinyapps.io cannot install from GitHub by default.
Step 2b: Deploy to Posit Connect
# Register server (one-time)
rsconnect::addServer(
url = "https://connect.example.com",
name = "production"
)
# Authenticate (one-time)
rsconnect::connectApiUser(
account = "your-username",
server = "production",
apiKey = Sys.getenv("CONNECT_API_KEY")
)
# Deploy
rsconnect::deployApp(
appDir = "path/to/app",
appName = "my-app",
server = "production",
account = "your-username"
)
Expected: App deployed and accessible on the Posit Connect instance.
On failure: If the server rejects the connection, verify the API key and server URL. If packages fail to install, check that Connect has access to the required repositories (CRAN, internal CRAN-like repos).
Step 2c: Deploy with Docker
Create a Dockerfile:
FROM rocker/shiny-verse:4.4.0
# Install system dependencies
RUN apt-get update && apt-get install -y \
libcurl4-openssl-dev \
libssl-dev \
libxml2-dev \
&& rm -rf /var/lib/apt/lists/*
# Install R packages
RUN R -e "install.packages(c('shiny', 'bslib', 'DT', 'plotly'))"
# Copy app
COPY . /srv/shiny-server/myapp/
# Configure Shiny Server
COPY shiny-server.conf /etc/shiny-server/shiny-server.conf
# Expose port
EXPOSE 3838
# Run
CMD ["/usr/bin/shiny-server"]
Create shiny-server.conf:
run_as shiny;
server {
listen 3838;
location / {
site_dir /srv/shiny-server/myapp;
log_dir /var/log/shiny-server;
directory_index on;
}
}
Build and run:
docker build -t myapp:latest .
docker run -p 3838:3838 myapp:latest
Expected: App accessible at http://localhost:3838.
On failure: If the build fails on package installation, add missing system libraries to the apt-get install line. If the app doesn't load, check Shiny Server logs: docker exec <container> cat /var/log/shiny-server/*.log.
Step 3: Verify Deployment
# Check the deployed URL responds
response <- httr::GET("https://your-app-url/")
httr::status_code(response) # Should be 200
# For Docker
response <- httr::GET("http://localhost:3838/")
httr::status_code(response)
Manual verification checklist:
- App loads without errors
- All interactive elements respond
- Data connections work in the deployed environment
- Authentication/authorization works (if applicable)
Expected: App responds with HTTP 200 and all features work.
On failure: Check server logs for the specific deployment platform. Common issues: environment variables not set in production, database connections using localhost instead of production URLs, or file paths that only exist locally.
Step 4: Configure Monitoring (Optional)
shinyapps.io
Monitor via the dashboard at https://www.shinyapps.io/admin/#/applications.
Posit Connect
# Check deployment status via API
connectapi::connect(
server = "https://connect.example.com",
api_key = Sys.getenv("CONNECT_API_KEY")
)
Docker
Add health check to Dockerfile:
HEALTHCHECK \
CMD curl -f http://localhost:3838/ || exit 1
Expected: Monitoring configured for the deployment target.
On failure: If health checks fail intermittently, increase timeout values. Shiny apps can be slow to respond during initial load.
Validation
- App deploys without errors
- Deployed URL responds with HTTP 200
- All interactive features work in production
- Environment variables/secrets are configured (not hardcoded)
- Credentials stored in
.Renvironor CI secrets, not in code - renv.lock committed for reproducible dependency resolution
Common Pitfalls
- Hardcoded file paths: Replace absolute paths with
system.file()(for package data) or environment variables (for external resources). - Development-only dependencies: Don't deploy
.Rprofilethat loadsmcptools::mcp_session()ordevtools. Use conditional loading or separate profiles. - Missing system libraries in Docker: R packages like sf, curl, and xml2 need system libraries. Add them to the Dockerfile's
apt-get install. - CRAN-only packages on shinyapps.io: shinyapps.io only installs from CRAN by default. GitHub-only packages need the
remotespackage and explicit installation in the deployment. - Forgotten environment variables: Database credentials, API keys, and other secrets must be configured in the deployment environment separately from code.
Related Skills
scaffold-shiny-app— create app structure before deploymentcreate-r-dockerfile— detailed Docker configuration for R projectssetup-docker-compose— multi-container setups for Shiny with databasessetup-github-actions-ci— CI/CD including automated deploymentoptimize-shiny-performance— performance tuning before deploying to production