R Academy · 课时

部署 Shiny 应用

将应用发布到 shinyapps.io、Shiny Server 和 Docker 容器环境

第 4 / 4 课13 个步骤

部署 Shiny 应用 是 CoddyKit 上的免费 R Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 R Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 R Academy 课程共包含 4 节课。

部署选项概览

Shiny 应用可以根据预算、预期流量和控制需求部署到多个平台:

  • shinyapps.io:由 Posit 管理的云托管服务——最简单,并提供免费套餐。
  • Shiny Server(开源版):自行托管在 Linux 上,免费。
  • Posit Connect:商业级企业平台,同时支持 R Markdown 和 Plumber。
  • Docker + rocker/shiny:提供最大的可移植性和控制能力。
# Summary of deployment options and their trade-offs:
# shinyapps.io: managed, auto-scaling, per-instance pricing
# Shiny Server: self-hosted, unlimited users, needs sysadmin
# Posit Connect: enterprise SSO, scheduling, REST APIs
# Docker: any cloud provider, reproducible environments

cat('Choose based on: scale, budget, infra control needs')

用于部署的 app.R 结构

可部署的 Shiny 应用必须包含一个单独的 app.R 文件(同时包含 ui 和 server),或者包含两个文件 ui.R 和 server.R。所有程序包依赖项都必须在文件顶部使用 library() 声明。数据文件必须位于同一目录中,或能够通过相对于应用目录的路径访问。

# Minimal app.R for deployment
library(shiny)
library(ggplot2)
library(dplyr)

# Load data relative to app directory
data <- readRDS('data/processed_data.rds')

ui <- fluidPage(
  titlePanel('My Deployed App'),
  sidebarLayout(
    sidebarPanel(selectInput('var', 'Variable:', choices = names(data))),
    mainPanel(plotOutput('main_plot'))
  )
)

server <- function(input, output, session) {
  output$main_plot <- renderPlot({
    ggplot(data, aes_string(x = input$var)) + geom_histogram()
  })
}

shinyApp(ui, server)

rsconnect::deployApp()

rsconnect 程序包负责将应用部署到 shinyapps.io 和 Posit Connect。首先配置账户凭据,然后在应用目录中调用 rsconnect::deployApp()。它会自动打包所有 R 文件、数据和清单文件。

library(rsconnect)

# One-time setup: link your shinyapps.io account
# rsconnect::setAccountInfo(
#   name   = 'your_account_name',
#   token  = 'YOUR_TOKEN',
#   secret = 'YOUR_SECRET'
# )

# Deploy the app in the current directory
rsconnect::deployApp(
  appDir  = '.',          # or 'path/to/app'
  appName = 'my_analysis_app',
  forceUpdate = TRUE
)

shinyapps.io 设置

shinyapps.io 是获取公共网址最快捷的方式。在 shinyapps.io 创建免费账户,从控制面板复制令牌和密钥,然后调用 setAccountInfo()。免费套餐每月允许使用 5 个应用和 25 个活跃小时。

library(rsconnect)

# Copy credentials from shinyapps.io -> Account -> Tokens
rsconnect::setAccountInfo(
  name   = 'your_username',
  token  = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  secret = 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'
)

# Verify the connection
rsconnect::accountInfo()

# List currently deployed apps
rsconnect::applications()

Shiny Server 开源版

Shiny Server 运行在 Linux(Ubuntu/RHEL)上,并从 /srv/shiny-server/ 目录提供 Shiny 应用。每个子目录都会成为一个应用,对应的地址为 http://server:3838/subdirname/。它是免费的,并支持不限数量的并发用户(受服务器容量限制)。

# Install Shiny Server on Ubuntu:
# sudo apt-get install r-base
# sudo R -e 'install.packages(c("shiny", "rmarkdown"))'
# wget https://download3.rstudio.org/ubuntu-20.04/x86_64/shiny-server-1.5.21.1012-amd64.deb
# sudo dpkg -i shiny-server-1.5.21.1012-amd64.deb

# Deploy an app:
# sudo cp -r /path/to/myapp /srv/shiny-server/myapp
# Access at: http://your-server:3838/myapp

# Config file: /etc/shiny-server/shiny-server.conf
cat('Shiny Server config controls ports, auth, and app paths')

使用 rocker/shiny 的 Docker

rocker/shiny Docker 镜像提供预配置的 Shiny Server。将应用目录挂载到容器中即可立即提供应用服务。Docker 可确保可复现性——同一个镜像在任何主机上运行时都保持一致。

# Dockerfile for a custom Shiny app
# FROM rocker/shiny:4.4.0
#
# # Install R package dependencies
# RUN R -e 'install.packages(c("ggplot2","dplyr","DT"))'
#
# # Copy app files
# COPY myapp/ /srv/shiny-server/myapp/
#
# EXPOSE 3838

# Build and run:
# docker build -t my-shiny-app .
# docker run -p 3838:3838 my-shiny-app

# Access at: http://localhost:3838/myapp

使用 renv 管理可复现的依赖项

renv 会创建项目级程序包库,并通过锁定文件(renv.lock)记录精确的程序包版本。部署时,该锁定文件可确保服务器或 Docker 镜像安装与开发期间完全相同的程序包版本。

library(renv)

# Initialise renv in the project (creates renv.lock)
renv::init()

# After installing/updating packages, record the state
renv::snapshot()

# On the server: restore exact versions from lockfile
renv::restore()

# Check lockfile for a specific package version
renv::dependencies()  # lists all used packages

用于配置的环境变量

绝不要将 API 密钥、数据库密码或特定环境的设置硬编码到应用代码中。请使用环境变量,并通过 Sys.getenv('VAR_NAME', unset = NA) 读取。在本地环境中将其设置在 .Renviron 中,在生产环境中则设置在托管平台的环境配置中。

# In .Renviron (never commit this file):
# DB_HOST=prod-db.example.com
# DB_PASSWORD=secret123
# API_KEY=key_abc

# In app.R:
db_host <- Sys.getenv('DB_HOST',     unset = 'localhost')
db_pass <- Sys.getenv('DB_PASSWORD', unset = '')
api_key <- Sys.getenv('API_KEY',     unset = '')

if (api_key == '') {
  warning('API_KEY not set — some features disabled')
}

Posit Connect 概览

Posit Connect 是用于部署 Shiny 应用、R Markdown 文档、Plumber API 等内容的企业级平台。它支持:

  • 通过 LDAP 或 SAML 实现单点登录(SSO)
  • 按计划执行 R Markdown 报告
  • 在应用级别进行访问控制
  • 自动扩缩容和负载均衡

部署使用与 shinyapps.io 相同的 rsconnect::deployApp() 工作流程。

library(rsconnect)

# Configure connection to Posit Connect server
rsconnect::addServer(
  url  = 'https://connect.yourcompany.com',
  name = 'my_connect_server'
)

# Authenticate with API key
rsconnect::connectApiUser(
  account = 'jsmith',
  server  = 'my_connect_server',
  apiKey  = Sys.getenv('CONNECT_API_KEY')
)

# Deploy
rsconnect::deployApp(server = 'my_connect_server')

部署前检查清单

将 Shiny 应用部署到生产环境之前,请确认:

  • 所有文件路径都使用相对路径,而不是绝对路径。
  • 敏感数据(API 密钥、密码)都从环境变量中读取。
  • 程序包依赖项通过 library() 或 renv.lock 明确声明。
  • 大型数据文件在 server.R 顶部加载一次,而不是在响应式代码内部加载。
  • 错误消息不会向最终用户暴露内部信息。
# Production-hardened app.R patterns

# Load data once at startup (not per-session)
app_data <- readRDS('data/processed.rds')  # outside server()

server <- function(input, output, session) {
  # Reference app_data directly — already in memory
  output$plot <- renderPlot({
    subset_data <- app_data[app_data$group == input$grp, ]
    plot(subset_data$x, subset_data$y)
  })

  # Sanitise error messages
  tryCatch({
    risky_operation()
  }, error = function(e) {
    showNotification('An error occurred.', type = 'error')
    # log the real error internally, not to user
    message('Error: ', conditionMessage(e))
  })
}

扩展规模时的注意事项

Shiny 应用基于会话运行:每位用户都会获得自己的 R 进程(或工作进程)。扩展规模的策略包括:

  • 在启动时加载预先计算的数据,而不是为每个会话重复计算。
  • 对于多个会话共享的昂贵计算,使用 bindCache() 进行响应式缓存。
  • 多个工作进程:Shiny Server Pro 和 Posit Connect 会启动并行的 R 进程。
  • 数据库后端:使用 DBI/pool 进行并发数据库访问。
library(shiny)
library(pool)

# Create a database connection pool at startup
# (shared across all sessions)
pool <- dbPool(
  drv      = RPostgres::Postgres(),
  host     = Sys.getenv('DB_HOST'),
  dbname   = 'analytics',
  user     = Sys.getenv('DB_USER'),
  password = Sys.getenv('DB_PASSWORD'),
  minSize  = 2,
  maxSize  = 10
)

onStop(function() { poolClose(pool) })

server <- function(input, output, session) {
  output$tbl <- renderTable({
    dbGetQuery(pool, 'SELECT * FROM metrics LIMIT 100')
  })
}

快速检查

在已部署的 Shiny 应用中,处理 API 密钥和数据库密码的推荐方式是什么?

部署 Shiny 应用回顾

部署 Shiny 应用的要点:

  • 部署选项:shinyapps.io(最简单)、Shiny Server(自行托管)、Posit Connect(企业级)、Docker。
  • app.R 必须使用 library() 声明所有依赖项;使用 renv::snapshot() 保存可复现的版本。
  • rsconnect::deployApp() 会打包应用并将其推送到 shinyapps.io 或 Posit Connect。
  • 使用 rocker/shiny 的 Docker 可提供最大的可移植性。
  • 使用 Sys.getenv() 管理凭据——绝不要将机密信息硬编码。
  • 在启动时加载大型数据集(位于 server() 外部),以便在多个会话之间共享。
  • 使用连接池(pool 程序包)进行并发数据库访问。
# Minimal production-ready structure
# myapp/
#   app.R           <- ui + server + shinyApp()
#   data/           <- processed datasets
#   R/              <- modules and helpers
#   renv.lock       <- package version snapshot
#   .Renviron       <- local env vars (gitignored)

# Deploy:
library(rsconnect)
rsconnect::deployApp(
  appDir  = 'myapp',
  appName = 'my_production_app'
)
免费开始

用 AI 导师学习 R — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
43
课程
159

常见问题解答

「部署 Shiny 应用」课时是免费的吗?

是的 — 「部署 Shiny 应用」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。

「部署 Shiny 应用」这节课中我会学到什么?

将应用发布到 shinyapps.io、Shiny Server 和 Docker 容器环境 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 R Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「部署 Shiny 应用」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 R Academy 课中编写并运行代码吗?

能。每节 R Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 深入理解响应式编程
  2. 使用 Shiny 模块复用代码
  3. 使用 renderUI 和 insertUI 创建动态用户界面
  4. 部署 Shiny 应用
← 返回 R Academy