ShinyProxy

De Wiki ISIG
Aller à la navigation Aller à la recherche

Attention : Page en cours de rédaction

ISIG-Apps passe sous ShinyProxy pour améliorer la stabilité et l'isolation de vos applications pendant les montées en charge. Le fonctionnement est très différent par rapport à l'ancien Shiny-Server et nécessite quelques bases dans l'utilisation de Docker. L'objectif de cette page est de vous guider, rapidement et simplement, dans le nouveau workflow dev > prod en partant du principe que vous ne connaissez encore pas grand-chose à Docker.

Principe de fonctionnement de ShinyProxy

ShinyProxy fonctionne comme un orchestrateur de conteneurs Docker. Chaque appli configurée doit avoir une image Docker associée présente sur le serveur qui exécute ShinyProxy. C'est ShinyProxy qui s'occupera ensuite de lancer et stopper un conteneur à chaque fois qu'un internaute se connectera ou se déconnectera de votre appli.

Conteneurisation de votre appli Shiny

Fixer le port

Choisir l'image source

https://rocker-project.org/images/

L'image r2u est une bonne base assez simple à utiliser, car elle va chercher des binaires précompilés des packages R que l'on souhaite installer et toutes leurs dépendances, librairies système incluses ! Pratiquement rien n'y est pré-installé, il faudra donc bien préciser toutes les dépendances dont vous avez besoin. En contrepartie, l'image sera plutôt légère, ce qui est une bonne chose !

Écrire le Dockerfile

Voici un exemple de Dockerfile pour l'application GloUrb :

# On commence par définir l'image sur laquelle va se baser la notre
FROM rocker/r2u:jammy

# On précise quelques infos qui permettrons d'identifier l'image
LABEL org.opencontainers.image.authors="Lise Vaudor <lise.vaudor@ens-lyon.fr>, Samuel Dunesme <samuel.dunesme@ens-lyon.fr>"
LABEL org.opencontainers.image.source="https://github.com/glourb/glourbapp"
LABEL org.opencontainers.image.documentation="https://evs-gis.github.io/glourbdoc/"
LABEL org.opencontainers.image.version="0.0.0.9000"
LABEL org.opencontainers.image.description="An app for the GloUrb project"

# On peut éventuellement générer des locales supplémentaires si notre appli utilise d'autres langues que l'anglais
RUN locale-gen fr_FR.UTF-8

# On liste maintenant toutes les dépendances R à installer
RUN Rscript -e 'install.packages("tidyr")'
RUN Rscript -e 'install.packages("shiny")'
RUN Rscript -e 'install.packages("config")'
RUN Rscript -e 'install.packages("testthat")'
RUN Rscript -e 'install.packages("tibble")'
RUN Rscript -e 'install.packages("purrr")'
RUN Rscript -e 'install.packages("dplyr")'
RUN Rscript -e 'install.packages("ggplot2")'
RUN Rscript -e 'install.packages("forcats")'
RUN Rscript -e 'install.packages("magrittr")'
RUN Rscript -e 'install.packages("golem")'
RUN Rscript -e 'install.packages("sf")'
RUN Rscript -e 'install.packages("plotly")'
RUN Rscript -e 'install.packages("spelling")'
RUN Rscript -e 'install.packages("mclust")'
RUN Rscript -e 'install.packages("leaflet")'
RUN Rscript -e 'install.packages("cluster")'
RUN Rscript -e 'install.packages("cowplot")'
RUN Rscript -e 'install.packages("FactoMineR")'
RUN Rscript -e 'install.packages("glue")'
RUN Rscript -e 'install.packages("grDevices")'
RUN Rscript -e 'install.packages("RColorBrewer")'
RUN Rscript -e 'install.packages("remotes")'
RUN Rscript -e 'install.packages("cicerone")'
RUN Rscript -e 'install.packages("RPostgres")'
RUN Rscript -e 'install.packages("DBI")'
RUN Rscript -e 'install.packages("DT")'

RUN Rscript -e 'remotes::install_github("glourb/glourbi")'

# On copie l'arborescence de fichiers dans un dossier app à la racine de l'image. Ce sera le working directory des containers lancés avec notre image
RUN mkdir /app
ADD . /app
WORKDIR /app

# Si besoin, on peut installer notre package
RUN R -e 'remotes::install_local()'

# On détermine le port qui sera exposé (attention à bien fixer le port sur lequel votre appli écoute, cf. ci-dessus)
EXPOSE 3838

# Pour plus de sécurité, on fait en sorte que les containers ne se lancent pas avec l'utilisateur "root", mais avec un utilisateur "app" dédié
RUN groupadd -g 1010 app && useradd -c 'app' -u 1010 -g 1010 -m -d /home/app -s /sbin/nologin app
USER app

# Enfin, on précise la commande qui permet de lancer notre appli. C'est cette commande qui sera lancée par défaut par tout nouveau container lancé avec notre image
CMD  ["R", "-f", "app.R"]

Construire l'image Docker

Pour construire l'image docker à l'aide du Dockerfile, il faut lancer la commande docker build. Il est important de taguer l'image avec l'option -t.

docker build ./Dockerfile -t ghcr.io/evs-gis/mapdoapp:latest -t ghcr.io/evs-gis/mapdoapp:2.0.1 -t ghcr.io/evs-gis/mapdoapp:$(git rev-parse --short HEAD)

Pousser l'image sur un registre

Configuration sur l'instance de dev

Forcer le redémarrage de tous les containers de votre appli (utile uniquement dans le cas où vous avez paramétré un nombre minimum de sièges supérieur à 0)

docker container restart $(docker ps -q -f ancestor="ghcr.io/evs-gis/mapdoapp:latest")

Configuration sur l'instance de prod

Mise à jour d'une appli