0Pricing
R Academy · Урок

Развёртывание приложений Shiny

Публикуйте приложения на shinyapps.io, Shiny Server и в средах на основе Docker

«Развёртывание приложений Shiny» — бесплатный урок R Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения 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 — самый быстрый способ получить общедоступный URL. Создайте бесплатную учетную запись на сайте 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) и предоставляет приложения Shiny из каталога /srv/shiny-server/. Каждый вложенный каталог становится приложением по адресу 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')

Docker с rocker/shiny

Образ Docker rocker/shiny содержит предварительно настроенный 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, API Plumber и других материалов. Она поддерживает:

  • единую систему входа (SSO) через LDAP или SAML
  • запланированный запуск отчетов R Markdown
  • управление доступом на уровне приложения
  • автоматическое масштабирование и балансировку нагрузки

Развертывание выполняется с помощью того же процесса rsconnect::deployApp(), что и в shinyapps.io.

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')
  })
}

Быстрая проверка

Как рекомендуется хранить ключи API и пароли к базам данных в развернутом приложении Shiny?

Итоги развертывания приложений Shiny

Основные выводы из урока «Развертывание приложений Shiny»:

  • Варианты развертывания: shinyapps.io (самый простой), Shiny Server (самостоятельное размещение), Posit Connect (корпоративный вариант), Docker.
  • app.R должен объявлять все зависимости с помощью library(); для воспроизводимых версий используйте renv::snapshot().
  • rsconnect::deployApp() упаковывает приложение и отправляет его в shinyapps.io или Posit Connect.
  • Docker с rocker/shiny обеспечивает максимальную переносимость.
  • Для учетных данных используйте 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'
)

Часто задаваемые вопросы

Урок «Развёртывание приложений Shiny» бесплатный?

Да — полный текст урока «Развёртывание приложений Shiny» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс R Academy, подпишись на CoddyKit PRO. Курс R Academy содержит 4 уроков всего.

Чему я научусь в уроке «Развёртывание приложений Shiny»?

Публикуйте приложения на shinyapps.io, Shiny Server и в средах на основе Docker Ты практикуешь R Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать R Academy?

Предыдущий опыт не требуется. R Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Развёртывание приложений Shiny»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке R Academy?

Да. Каждый урок R Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Глубокое погружение в реактивное программирование
  2. Модули Shiny для повторного использования кода
  3. Динамический интерфейс с renderUI и insertUI
  4. Развёртывание приложений Shiny
← Назад к R Academy