Despliegue: shinyapps.io, Posit Connect, ShinyProxy

r
shiny
El espectro de opciones según privacidad, escala y presupuesto. shinyapps.io para el atajo, Posit Connect para enterprise managed, ShinyProxy para open-source enterprise, self-hosting con Docker.

El espectro de despliegue

Tu app funciona en local. Para que el usuario la use, hay que ponerla en algún servidor accesible. Las cuatro opciones reales:

Opción Quién gestiona Coste Cuándo
shinyapps.io Posit (cloud) Free / 39\(/mes / 99\)/mes / 299\(/mes | Apps pequeñas o equipos pequeños | | **Posit Connect** | Tu empresa (servidor on-prem o cloud) | Licencia anual (\)$$$) Enterprise con presupuesto
ShinyProxy Tú/tu equipo (Docker) Gratis (open source) Enterprise sin licencias
Self-hosted con shiny-server Tú/tu equipo (VPS) Coste del servidor Proyectos pequeños/medianos a medida

La elección depende de tres ejes: privacidad (¿dónde están los datos?), escala (¿cuántos usuarios concurrentes?), presupuesto (¿qué puedes pagar?). Lo veremos opción por opción.

shinyapps.io: el atajo

shinyapps.io es el servicio gestionado de Posit. Subes la app, te dan una URL. Mínima configuración.

install.packages("rsconnect")

# Configurar credenciales (una vez)
rsconnect::setAccountInfo(
  name   = "tu_usuario",
  token  = "...",
  secret = "..."
)

# Subir la app
rsconnect::deployApp(appDir = "ruta/a/tu/app")

Cuándo elegirla:

  • App de portfolio personal o proyecto pequeño.
  • Pocos usuarios (free tier = 25 horas/mes activas. Planes pagos escalan).
  • No necesitas integración con SSO de tu empresa.
  • Te basta con dominio *.shinyapps.io.

Cuándo NO:

  • Datos sensibles que no pueden salir de tu organización (sale de tu infra a la de Posit).
  • Necesitas más de unas pocas decenas de usuarios concurrentes (los planes pagos escalan, pero el coste también).
  • Necesitas dominio propio sin redirección.

Free tier: 5 apps, 25 horas activas/mes. Suficiente para prototipos y demos. Para producción de verdad, plan pagado.

Posit Connect: enterprise managed

Posit Connect (antes RStudio Connect) es el servidor enterprise comercial de Posit. Lo instalas en tu infraestructura (servidor on-prem o cloud propio) y sirve apps Shiny, documentos Quarto, dashboards, APIs y modelos vetiver.

Lo que te da:

  • Autenticación enterprise (SSO con SAML, OIDC, LDAP).
  • Permisos por app (público, autenticado, grupo específico).
  • Versionado y rollback de despliegues.
  • Escalado con múltiples procesos por app.
  • Métricas y monitoreo integrados.
  • Sirve también Quarto, Plumber APIs, modelos.

Cuándo elegirla:

  • Eres parte de una empresa con presupuesto para herramientas de datos.
  • Necesitas SSO con el directorio corporativo.
  • Apps con datos sensibles que deben quedarse en tu infra.
  • Quieres una herramienta para servir todo el ecosistema R/Python (Shiny + Quarto + APIs + ML).

Cuándo NO:

  • Proyecto personal o equipo pequeño sin presupuesto enterprise.
  • Solo tienes una app o dos, la curva de instalación y administración no compensa.

Coste: licencia anual basada en número de usuarios o cores. Habla con Posit para precios concretos (típicamente miles a decenas de miles de € al año).

ShinyProxy: enterprise open-source

ShinyProxy (de OpenAnalytics, no de Posit) es la alternativa open-source para servir apps Shiny a escala. La filosofía: cada usuario corre en un contenedor Docker dedicado.

Arquitectura básica:

  1. Cada app Shiny se empaqueta en una imagen Docker.
  2. ShinyProxy gestiona el ciclo de vida: cuando un usuario entra, levanta un contenedor. Cuando sale, lo apaga.
  3. Autenticación se integra con LDAP, OAuth2, Keycloak, etc.

Cuándo elegirlo:

  • Necesitas autenticación enterprise pero sin pagar Connect.
  • Tienes infraestructura Docker/Kubernetes ya en uso.
  • Quieres escalabilidad horizontal real (más usuarios = más contenedores).
  • Te apañas con setup manual y un equipo DevOps mínimo.

Cuándo NO:

  • No tienes nadie que sepa Docker en tu equipo.
  • Tu única app es un experimento personal, overkill.
  • Necesitas también servir Quarto/APIs/modelos desde el mismo sitio (Connect lo hace. ShinyProxy es solo Shiny).

Es gratuito y robusto, pero la curva de aprendizaje (Docker + Spring Boot + auth) no es trivial.

Self-hosted con shiny-server

shiny-server es el servidor open-source minimal de Posit (gratuito desde hace años). Lo instalas en un VPS (Ubuntu suele bastar) y sirve apps desde una carpeta:

# Instalación rápida en Ubuntu
sudo apt-get install gdebi-core
wget https://download3.rstudio.org/ubuntu-18.04/x86_64/shiny-server-1.5.x.deb
sudo gdebi shiny-server-1.5.x.deb

Las apps van en /srv/shiny-server/, una carpeta por app. Sin autenticación nativa, sin permisos granulares, todo es público por defecto.

Cuándo elegirlo:

  • Proyecto pequeño/mediano sin auth necesaria (o auth puesta delante con nginx + auth básica).
  • Tienes ya un VPS y la app es simple.
  • Coste mínimo (solo pagas el VPS, ~5-20€/mes).

Cuándo NO:

  • Necesitas autenticación seria.
  • Escalado: shiny-server open-source es single-process por app, un usuario lento bloquea a los demás. Connect/ShinyProxy resuelven esto, este no.

Es el patrón típico para apps personales o de portfolio que quieren dominio propio. “Pon una app Shiny detrás de tu nombre.com”, shiny-server + nginx en un VPS es la receta clásica.

Consideraciones de escala

Hay tres ejes que afectan el deployment:

Concurrencia

  • shinyapps.io: planes definen máximo de conexiones simultáneas.
  • Posit Connect: configurable, escalable con processes paralelos.
  • ShinyProxy: un contenedor por usuario, escala bien horizontalmente.
  • shiny-server open-source: limitado a un proceso por app, cuello de botella con más de unos pocos usuarios.

Si tu app es de uso intermitente para pocos usuarios, cualquiera vale. Si tendrá decenas o cientos concurrentes, Connect o ShinyProxy.

Latencia

R no es rápido para procesar peticiones, Shiny tampoco. Si tu app tiene operaciones de varios segundos, los usuarios concurrentes esperan en cola. Soluciones:

  • promises + future: operaciones largas en threads separados.
  • Caching agresivo con bindCache() (lo veremos en una ruta futura).
  • Pre-computar datos pesados en cron jobs separados, no en el server.

Autenticación

  • shinyapps.io: solo en plan Standard+ con cuentas Posit Cloud.
  • Posit Connect: SSO enterprise nativo.
  • ShinyProxy: OAuth/Keycloak/LDAP.
  • shiny-server open-source: tú lo añades por delante (nginx + auth_basic, o un reverse proxy con OAuth).

Si necesitas SSO corporativo y no puedes pagar Connect, ShinyProxy es la respuesta. Si necesitas algo más simple (auth básica de HTTP), un nginx delante de shiny-server basta.

Decisión rápida

Tu situación Opción
Portfolio personal, demo shinyapps.io free / shiny-server en VPS
App pequeña pero con tráfico shinyapps.io plan Starter
Empresa con presupuesto, datos sensibles Posit Connect
Empresa sin presupuesto Posit pero con DevOps ShinyProxy
Equipo pequeño que ya tiene VPS y nginx shiny-server open-source + nginx
Apps + modelos + Quarto en la misma infra Posit Connect (es el que lo cubre todo)

Trampas habituales

  • Deployment como pensamiento posterior. “Hago la app y luego veo cómo la subo”, y descubres al final que tu app depende de una API privada inaccesible desde shinyapps.io, o que necesitas SSO corporativo que no soporta tu plan. Piensa deployment al principio del proyecto.
  • Subir a producción sin probar tiempo real con datos reales. Local funciona. En producción, los archivos con rutas absolutas fallan, las dependencias no están, la zona horaria es distinta. Prueba el deployment antes de prometer fecha.
  • Olvidar renv o Dockerfile para reproducibilidad. Sin un sistema de fijar versiones, en seis meses tu app dejará de funcionar porque una dependencia cambió. renv::snapshot() antes de cada deploy es buena higiene.
  • Logs ignorados. En producción, los errores del server van a logs (no a la consola). Saber dónde están y cómo leerlos es la diferencia entre depurar en 5 minutos o en 5 horas. Familiarízate con los logs de tu plataforma desde el primer deploy.

En la siguiente entrega

Has cubierto todas las piezas de Shiny: anatomía, reactividad, componentes, validación, módulos, estado, deployment. Solo queda un caso real end-to-end que junte todo en un dashboard publicable. Es el cierre de la ruta.