Desplegar aplicaciones Shiny a producción en contenedores Docker
20/1/2026
Docker es una plataforma que permite empaquetar aplicaciones y sus dependencias en contenedores, lo que simplifica el proceso de despliegue (deployment) y gestión de aplicaciones.
¿Qué es Docker?
Docker es un programa que te permite crear contenedores dentro de los cuales puedes ejecutar aplicaciones. Estos son entornos exclusivos y específicos para tu app, de manera que ya no la ejecutas en tu computador, sino que la ejecutas dentro del contenedor, que es una especie de computador virtual sólo para tu app. Estos contenedores son independientes entre sí y reproducibles, ayudándote a que tus apps siempre funcionen siempre igual, sin importar dónde las ejecutes.
Los objetivos principales de usar Docker en aplicaciones Shiny son:
- Garantizar un entorno de ejecución consistente y reproducible: al ejecutar la app en el contenedor, tienes garantizado que se ejecutará igual en otro computador, en un servidor Linux, o en cualquier entorno.
- Congelar las dependencias de la aplicación, para asegurarte de que se usan las versiones exactas de R y de los paquetes que utilices, además de ejecutarse en un mismo sistema operativo (usualmente Linux) con todas las librerías y configuraciones que éste requiera.
- Facilitar el despliegue en servidores o plataformas de nube, dado que tu app vive aislada dentro del contenedor, y por ende no requiere cambiar configuraciones ni instalar cosas al servidor.
En pocas palabras, Docker sirve para empaquetar tu aplicación Shiny junto con todo lo necesario para que funcione correctamente, y así poder desplegarla en cualquier lugar sin preocuparte por las diferencias en los entornos de ejecución. Esto significa que crearás un contenedor con una versión de Linux y de R específica, junto a todas las configuraciones e instalaciones que necesites.
Imágenes
Los contenedores Docker dependende imágenes. Las imágenes contienen un sistema operativo base y las configuraciones e instalaciones necesarias.
En el caso de R y Shiny existen las imágenes de Rocker Project, un proyecto que mantiene imágenes con versiones de R y todo lo necesario para usar R.
Existen imágenes de Shiny y Shiny-Verse, que es Shiny + paquetes del Tidyverse, para acelerar el despliegue si usas esos paquetes (recomendado).
Dockerfiles
Un Dockerfile es el archivo que contiene la receta para crear tu contenedor: empezando por la imagen que se usará como base, e incluyendo instalación de libreríass, copiado de archivos, configuración de puertos, y todo lo necesario para que tu aplicación funcione correctamente.
Creando contenedores para apps Shiny
Crear un contenedor automáticamente con {shiny2docker}
El paquete {shiny2docker} facilita enormemente esta tarea.
Simplemente instala el paquete con install.packages("shiny2docker") y luego, en el directorio de la app, ejecuta:
shiny2docker::shiny2docker(path = ".")
La función capturará las dependencias de tu aplicación y generará un dockerfile personalizado.
El paquete decidirá la imagen que usará como base, pero puedes cambiarla especificando el argumento FROM = "rocker/shiny-verse".
El dockerfile resultante se vería más o menos así:
FROM rocker/shiny:4.4.2
RUN apt-get update -y && apt-get install -y make pandoc libx11-dev libfontconfig1-dev libfreetype6-dev libcairo2-dev libpng-dev zlib1g-dev cmake libssl-dev libgdal-dev gdal-bin libgeos-dev libproj-dev libsqlite3-dev libudunits2-dev libicu-dev && rm -rf /var/lib/apt/lists/*
RUN mkdir -p /usr/local/lib/R/etc/ /usr/lib/R/etc/
RUN echo "options(renv.config.pak.enabled = FALSE, repos = c(CRAN = 'https://cran.rstudio.com/'), download.file.method = 'libcurl', Ncpus = 4)" | tee /usr/local/lib/R/etc/Rprofile.site | tee /usr/lib/R/etc/Rprofile.site
RUN R -e 'install.packages("remotes")'
RUN R -e 'remotes::install_version("renv", version = "1.1.4")'
COPY renv.lock renv.lock
RUN --mount=type=cache,id=renv-cache,target=/root/.cache/R/renv R -e 'renv::restore()'
WORKDIR /srv/shiny-server/
COPY . /srv/shiny-server/
EXPOSE 3838
CMD R -e 'shiny::runApp("/srv/shiny-server",host="0.0.0.0",port=3838)'
- Vemos que lo primero que hace es basarse en una imagen de Rocker Project con una versión específica de R.
- Luego instala librerías de Ubuntu con
apt-get install. - Después ejecuta varios comandos de Linux con
RUN, entre ellos los necesarios para activar{renv}y así instalar las versiones específicas de los paquetes usados en tu sesión de R. - Finalmente usa
COPYpara copiar los archivos de tu app a la carpeta/srv/shiny-server/, desde la cual se ejecutará tu app.
Crear un contenedor manualmente
También podemos crear un contenedor a mano, creando un archivo llamado Dockerfile que contenga, como mínimo, la imagen que usaremos, la instalación de librerías de Ubuntu requeridas y la instalación de paquetes de R.
FROM rocker/shiny-verse:4.5.2
RUN apt-get update -y && apt-get install -y
RUN apt-get install -y fonts-manrope
RUN apt-get install -y libudunits2-dev libgdal-dev libgeos-dev libproj-dev
RUN R -e 'install.packages("shinyWidgets")'
RUN R -e 'install.packages("shinycssloaders")'
RUN R -e 'install.packages("shinydisconnect")'
RUN R -e 'install.packages("shinyjs")'
RUN R -e 'install.packages("writexl")'
RUN R -e 'install.packages("gfonts")'
RUN R -e 'install.packages("ragg")'
RUN R -e 'install.packages("gt")'
RUN R -e 'install.packages("sf")'
RUN R -e 'install.packages("cli")'
RUN R -e 'install.packages("ggiraph")'
RUN R -e 'remotes::install_github("hrbrmstr/waffle")'
RUN sudo chown -R shiny:shiny /srv/shiny-server/
Luego, crea un archivo docker-compose.yml para definir el servicio de la app Shiny:
services:
shiny_server:
container_name: app
build:
context: .
dockerfile: Dockerfile
ports:
- "3838:3838" # cambiar primer puerto si tienes varias apps
volumes:
- ./app/:/srv/shiny-server/
restart: always
Este archivo coordinará el despliegue de tu contenedor, y copiará los contenidos de la carpeta app/ a /srv/shiny-server/ dentro del contenedor, así que asegúrate de que dentro de app/ (o el nombre de la carpeta de tu app) estén los archivos app.R o ui.R y server.R.
Ejecutando apps Shiny desde contenedores Docker
Para ejecutar el contenedor con tu app Shiny, deberías tener en un mismo directorio lo siguiente:
- El archivo
Dockerfilecon los pasos de instalación de tu contenedor, ya sea escrito por ti o creado por{shiny2docker} - El archivo
docker-compose.ymlpara coordinar el despliegue de tu contenedor - Una carpeta
app/(o el nombre de tu app) con los scripts y archivos necesarios para tu aplicación Shiny (app.R, etc).
Luego necesitas abrir una Terminal y ubicar la terminal en esa carpeta (cd ruta/a/carpeta/), y desde ahí ejecutar el siguiente comando:
docker compose up -d
Este comando levanta una aplicación Shiny hecha con Docker Compose en segundo plano, asumiendo que la carpeta desde la que ejecutaste el comando contiene el dockerfile y docker-compose.yml.
La primera vez que lo ejecutes, debería salir en la terminal el proceso de construcción del contenedor, con la instalación de todo lo que detallaste. Luego de unos minutos (dependiendo de la cantidad de paquetes y librerías que tengas que instalar), el contenedor debería estar listo y ejecutándose.
Para acceder a la aplicación, accede desde un navegador a localhost:3838, o reemplaza 3838 por el puerto que hayas definido en docker-compose.yml.
Para confirmar el estado de tus contenedores, sus nombres y puertos, ejecuta:
docker ps
Configuración avanzada
Permisos de escritura para Shiny
Si tu aplicación Shiny usa cache y decides que el cache se guarde en el disco (lo que aumenta la velocidad de la app para todos sus usuarios), necesitas que la aplicación tenga permiso para leer y escribir en la carpeta del cache. Esto es porque Shiny por defecto no puede escribir en el disco, por razones de seguridad, pero necesita escribir si se usa cache en disco para ir guardando las combinaciones de inputs nuevas que vayan realizando tus usuarios/as.
Para que Shiny pueda escribir en la carpeta del cache, en el archivo docker-compose.yml tienes que agregar la siguiente línea dentro del bloque shiny_server:
services:
shiny_server:
container_name: shiny_app
...
volumes:
- ...
post_start:
- command: ["sh", "-c", "chown -R shiny:shiny /srv/shiny-server/app_cache"] # dar permisos después de montar volumen
El argumento post_start ejecutará un comando justo después de montar el volumen, lo que le dará permisos a Shiny para escribir en la carpeta del cache. Asegúrate de reemplazar la ruta por el nombre de la carpeta que usas para guardar el cache en disco.
Comandos de Docker más frecuentes
Levantar una aplicación Shiny hecha con Docker Compose:
docker compose up -d
- Tienes que estar en la carpeta de la app
Bajar la aplicación Shiny hecha con Docker Compose:
docker compose down
- Tienes que estar en la carpeta de la app
Ver los contenedores Docker activos:
docker ps
Reconstruir y levantar la aplicación Shiny hecha con Docker Compose:
docker compose up --build --force-recreate -d
- Tienes que estar en la carpeta de la app
- Sirve para recibir cambios nuevos y asegurarte de que se aplicarán
Entrar a la consola de un contenedor Docker activo:
docker ps
docker exec -ti xxxx /bin/bash
- Reemplaza
xxxxpor el ID del contenedor
Revisar los logs de un contenedor Docker:
docker ps
docker logs xxxx
- Reemplaza
xxxxpor el ID o nombre del contenedor
Ver las imágenes Docker disponibles:
docker image ls
Eliminar una imagen Docker:
docker image ls
docker rmi xxxx
- Reemplaza
xxxxpor el ID de la imagen