A la hora de distribuir aplicaciones creadas con Shiny nos podemos plantar la idea de usar imágenes de Docker. Algo que nos permite evitar posibles problemas de incompatibilidad debido a no disponer de la versión correcta de R, Shiny o cualquier otro paquete en el servidor. Una vez creada la aplicación crear una imagen de Docker con Shiny Server es relativamente sencillo, por lo que esta es una buena opción para tener en cuenta.
Estructura del proyecto
Para crear nuestra imagen Docker con Shiny Server vamos a utilizar una estructura de proyecto sencilla. Simplemente una carpeta app
con la aplicación Shiny y tres archivos.
+-- app +-- server.R +-- ui.R +-- ... +-- Dockerfile +-- shiny-server.conf +-- shiny-server.sh
Dockerfile
es el archivo en el que se guardan las instrucciones para crear la imagen Docker, shiny-server.conf
contiene la configuración del servidor Shiny y shiny-server.sh
es un script para ejecutar al lanzar el programa.
El archivo Dockerfile
Podemos crear un archivo Dockerfile
como el que se muestra a continuación. En el que se indica en la primera línea que nos vamos a basar en la última imagen disponible de r-base, aunque siempre podemos indicar una versión concreta de R. Para lo que es necesario reemplazar latest
por la versión necesaria.
FROM r-base:latest RUN apt-get update & apt-get install -y \ sudo \ gdebi-core \ pandoc \ pandoc-citeproc \ libcurl4-gnutls-dev \ libxt-dev \ libssl-dev \ libxml2 \ libxml2-dev # Instalacion de shiny server RUN wget --no-verbose https://s3.amazonaws.com/rstudio-shiny-server-os-build/ubuntu-12.04/x86_64/VERSION -O "version.txt" & \ VERSION=$(cat version.txt) & \ wget --no-verbose "https://s3.amazonaws.com/rstudio-shiny-server-os-build/ubuntu-12.04/x86_64/shiny-server-$VERSION-amd64.deb" -O ss-latest.deb & \ gdebi -n ss-latest.deb & \ rm -f version.txt ss-latest.deb # Instalacion de los paquetes necesarios RUN R -e "install.packages(c('shiny'), repos='http://cran.rstudio.com/')" COPY shiny-server.conf /etc/shiny-server/shiny-server.conf COPY /myapp /srv/shiny-server/ COPY shiny-server.sh /usr/bin/shiny-server.sh EXPOSE 80 CMD ["/usr/bin/shiny-server.sh"]
En la siguiente instrucción vamos a actualizar algunos de los paquetes de la distribución de Linux. Garantizando así tener las última versión de los paquetes. Posteriormente, necesitamos instalar Shiny Server, el cual descargamos directamente.
Una vez instalado Shiny Server hay que instalar los paquetes necesarios, para lo que se usara el install.packages()
de R. En este punto es importante no olvidarse de ningún paquete, ya que después puede que no funcione correctamente la aplicación dentro de la imagen.
Una vez realizada las instalaciones copiaremos nuestro programa en la imagen. El archivo de configuración de Shiny Server en la ruta /etc/shiny-server/
y el programa en /srv/shiny-server/
. Además de esto también copiaremos es script a /usr/bin
.
Finalmente expondremos el puerto en el que se encuentra la aplicación, en el caso del ejemplo el 80, e indicaremos que se lance el script para iniciar el servidor.
El archivo shiny-server.conf
En este archivo indicaremos las opciones de configuración de Shiny Server. Entre lo que se encuentra el usuario con el que se debe ejecutar la aplicación, el puerto donde se publicará y las ubicaciones de la aplicación y los logs. Por ejemplo, se puede usar el siguiente archivo.
run_as shiny; server { listen 80; location / { site_dir /srv/shiny-server; log_dir /var/log/shiny-server; directory_index on; } }
El archivo shiny-server.sh
Este archivo es prescindible, pero facilita ejecutar los comandos para iniciar el programa. Por seguridad crearemos la carpeta para los logs y le cambiaremos los permisos. Acto seguido ejecutamos shiny-server
indicando la ruta en la que se almacenarán los archivos de log.
#!/bin/sh mkdir -p /var/log/shiny-server chown shiny.shiny /var/log/shiny-server exec shiny-server >> /var/log/shiny-server.log 2>&1
Creación de imagen Docker con Shiny Server
Una vez creado el proyecto tendremos que crear la imagen. Para lo que, en la carpeta del proyecto, donde se encuentra el archivo Dockerfile
ejecutaremos la siguiente instrucción:
docker build -t shiny_app .
En donde shiny_app
lo podemos reemplazar por un nombre que sea significativo para nosotros. Una vez creada la imagen, lo que puede tardar algunos minutos dependiendo de los paquetes que sean necesario instalar, podemos ejecutar la imagen con el comando.
docker run --rm --name shiny_app -p 3000:80 shiny_app
En el cual hemos redireccionado el puerto 80 de la aplicación al 3000. Lo que nos permite acceder, si todo ha ido bien, a la aplicación con el navegador a través de la dirección http://localhost:3000/
.
Compartir la imagen Docker
En este punto solamente nos queda compartir la imagen, para lo que podemos guardar esta en un archivo tar.Algo que se consigue con el comando save
de docker
.
docker save shiny_app > shiny_app.tar
Conclusiones
En esta entrada hemos visto como es relativamente fácil crear una imagen Docker con Shiny Server para distribuir nuestro trabajo. El uso de Docker nos garantiza qué se usa exactamente las versiones de R, Shiny y los paquetes que realmente queremos, evitando problemas que pueden aparecer al cambiar las versiones.
Imagen de Mike Goad en Pixabay