0Pricing
R Academy · Lezione

Distribuzione delle app Shiny

Pubblichi app su shinyapps.io, Shiny Server e ambienti basati su Docker

Distribuzione delle app Shiny è una lezione R Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento R Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso R Academy include 4 lezioni in totale.

Panoramica delle opzioni di deployment

Le app Shiny possono essere distribuite su diverse piattaforme, a seconda del budget, del traffico previsto e del livello di controllo richiesto:

  • shinyapps.io: hosting cloud gestito da Posit — è l'opzione più semplice ed è disponibile un piano gratuito.
  • Shiny Server (open source): self-hosted su Linux, gratuito.
  • Posit Connect: commerciale, di livello enterprise, supporta anche R Markdown e Plumber.
  • Docker + rocker/shiny: massima portabilità e controllo.
# 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')

Struttura di app.R per il deployment

Un'app Shiny distribuibile deve avere un unico file app.R (che contiene sia ui sia server) oppure due file, ui.R e server.R. Tutte le dipendenze dai package devono essere dichiarate con library() all'inizio del file. I file di dati devono trovarsi nella stessa directory dell'app oppure essere accessibili tramite un percorso relativo.

# 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()

Il package rsconnect gestisce il deployment su shinyapps.io e Posit Connect. Per prima cosa, configuri le credenziali del proprio account, quindi chiami rsconnect::deployApp() dalla directory dell'app. La funzione include automaticamente tutti i file R, i dati e un manifest.

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
)

Configurazione di shinyapps.io

shinyapps.io è il modo più rapido per ottenere un URL pubblico. Crei un account gratuito su shinyapps.io, copi token e secret dalla dashboard e chiami setAccountInfo(). Il piano gratuito consente di avere 5 app con 25 ore di attività al mese.

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 Open Source

Shiny Server viene eseguito su Linux (Ubuntu/RHEL) e pubblica le app Shiny dalla directory /srv/shiny-server/. Ogni sottodirectory diventa un'app disponibile all'indirizzo http://server:3838/subdirname/. È gratuito e supporta un numero illimitato di utenti contemporanei, nei limiti della capacità del server.

# 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 con rocker/shiny

L'immagine Docker rocker/shiny fornisce uno Shiny Server preconfigurato. Monti la directory dell'app nel container per pubblicarla immediatamente. Docker garantisce la riproducibilità: la stessa immagine viene eseguita nello stesso modo su qualsiasi host.

# 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 per dipendenze riproducibili

renv crea una libreria di package a livello di progetto e un lockfile (renv.lock) che registra le versioni esatte dei package. Durante il deployment, questo lockfile garantisce che il server o l'immagine Docker installi esattamente le stesse versioni dei package utilizzate durante lo sviluppo.

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

Variabili d'ambiente per la configurazione

Non inserisca mai direttamente nel codice dell'app le chiavi API, le password dei database o le impostazioni specifiche dell'ambiente. Utilizzi invece variabili d'ambiente, lette con Sys.getenv('VAR_NAME', unset = NA). Le imposti localmente in .Renviron e, per la produzione, nella configurazione dell'ambiente della piattaforma di hosting.

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

Panoramica di Posit Connect

Posit Connect è la piattaforma enterprise per il deployment di app Shiny, documenti R Markdown, API Plumber e altro. Supporta:

  • Single Sign-On (SSO) tramite LDAP o SAML
  • Esecuzione pianificata di report R Markdown
  • Controllo degli accessi a livello di app
  • Scalabilità automatica e bilanciamento del carico

Il deployment utilizza lo stesso flusso di lavoro rsconnect::deployApp() di 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')

Checklist prima del deployment

Prima di distribuire un'app Shiny in produzione, verifichi che:

  • Tutti i percorsi dei file utilizzino percorsi relativi, non assoluti.
  • I dati sensibili (chiavi API, password) vengano letti dalle variabili d'ambiente.
  • Le dipendenze dai package siano esplicite tramite library() o renv.lock.
  • I file di dati di grandi dimensioni vengano caricati una sola volta all'inizio di server.R, non all'interno di reactive.
  • I messaggi di errore non espongano informazioni interne agli utenti finali.
# 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))
  })
}

Considerazioni sulla scalabilità

Le app Shiny sono basate su sessioni: ogni utente riceve un processo R (o worker) dedicato. Strategie di scalabilità:

  • Carichi dati precalcolati all'avvio invece di eseguire i calcoli per ogni sessione.
  • Utilizzi la cache reattiva con bindCache() per i calcoli onerosi condivisi tra le sessioni.
  • Più worker: Shiny Server Pro e Posit Connect avviano processi R paralleli.
  • Backend di database: utilizzi DBI/pool per l'accesso concorrente al database.
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')
  })
}

Verifica rapida

Qual è il modo consigliato per gestire le chiavi API e le password dei database in un'app Shiny distribuita?

Riepilogo del deployment delle app Shiny

Punti chiave del deployment delle app Shiny:

  • Opzioni di deployment: shinyapps.io (più semplice), Shiny Server (self-hosted), Posit Connect (enterprise), Docker.
  • app.R deve dichiarare tutte le dipendenze con library(); utilizzi renv::snapshot() per ottenere versioni riproducibili.
  • rsconnect::deployApp() raggruppa e invia l'app a shinyapps.io o Posit Connect.
  • Docker con rocker/shiny offre la massima portabilità.
  • Utilizzi Sys.getenv() per le credenziali: non inserisca mai direttamente nel codice i segreti.
  • Carichi i dataset di grandi dimensioni all'avvio, al di fuori di server(), per condividerli tra le sessioni.
  • Utilizzi pool di connessioni (package pool) per l'accesso concorrente al database.
# 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'
)

Domande Frequenti

La lezione «Distribuzione delle app Shiny» è gratuita?

Sì — il testo completo di «Distribuzione delle app Shiny» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso R Academy, passa a CoddyKit PRO. Il corso R Academy include 4 lezioni in totale.

Cosa imparerò in «Distribuzione delle app Shiny»?

Pubblichi app su shinyapps.io, Shiny Server e ambienti basati su Docker Eserciti R Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare R Academy?

Non è richiesta alcuna esperienza precedente. R Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Distribuzione delle app Shiny»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione R Academy?

Sì. Ogni lezione R Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Approfondimento della programmazione reattiva
  2. Moduli Shiny per riutilizzare il codice
  3. Interfaccia dinamica con renderUI e insertUI
  4. Distribuzione delle app Shiny
← Torna a R Academy