Если вы развертываете RShiny с помощью docker, вы можете накрутить свой собственный образ или использовать рокер-образ Dockerhub.

Какое решение вы выберете, будет зависеть от ваших потребностей. Обычно я использую много пакетов для биоинформатики и / или анализа данных, и, на мой взгляд, ничто не сравнится с экосистемой conda. С другой стороны, иметь образ с уже установленным RShiny действительно приятно! Мне также очень нравится способ настройки образа rocker/shiny. Вы помещаете свои файлы в каталог, и пока у вас есть нужные пакеты, ваше блестящее приложение запускается напрямую!

Разверните простое блестящее приложение, используя качельку / блестящее изображение

Вот наше обычное блестящее приложение, по большей части украденное из R shiny docs. ;-)

#!/usr/bin/env Rscript

# This example comes from the r-shiny examples github repo.
# https://github.com/rstudio/shiny-examples/blob/master/001-hello/app.R

library(shiny)

# Define UI for app that draws a histogram ----
ui <- fluidPage(

  # App title ----
  titlePanel("Hello Shiny!"),

  # Sidebar layout with input and output definitions ----
  sidebarLayout(

    # Sidebar panel for inputs ----
    sidebarPanel(

      # Input: Slider for the number of bins ----
      sliderInput(inputId = "bins",
                  label = "Number of bins:",
                  min = 1,
                  max = 50,
                  value = 30)

    ),

    # Main panel for displaying outputs ----
    mainPanel(

      # Output: Histogram ----
      plotOutput(outputId = "distPlot")

    )
  )
)


# Define server logic required to draw a histogram ----
server <- function(input, output) {

  # Histogram of the Old Faithful Geyser Data ----
  # with requested number of bins
  # This expression that generates a histogram is wrapped in a call
  # to renderPlot to indicate that:
  #
  # 1. It is "reactive" and therefore should be automatically
  #    re-executed when inputs (input$bins) change
  # 2. Its output type is a plot
  output$distPlot <- renderPlot({

    x    <- faithful$waiting
    bins <- seq(min(x), max(x), length.out = input$bins + 1)

    hist(x, breaks = bins, col = "#75AADB", border = "white",
         xlab = "Waiting time to next eruption (in mins)",
         main = "Histogram of waiting times")

    })

}

# If you want to automatically reload the app when your codebase changes - should be turned off in production
options(shiny.autoreload = TRUE)

options(shiny.host = '0.0.0.0')
options(shiny.port = 8080)

# Create Shiny app ---- 
shinyApp(ui = ui, server = server)

Создайте каталог с именем shiny-app и вставьте указанный выше app.R.

Подайте свое приложение RShiny

Теперь, когда у вас есть приложение для обслуживания, вам нужно знать две фундаментальные концепции докеров. Как выставлять порты и как монтировать тома.

docker run --rm \ 
-v "$(pwd)/shiny-app":/srv/shiny-server \ 
-p 3838:3838

Вы должны увидеть сообщение о том, что ваше приложение RShiny запущено. Откройте браузер по адресу localhost:3838, и вы должны увидеть следующее приложение.

Здесь изображение рокера довольно изящное. Поскольку мы помещаем наше приложение прямо в /srv/shiny-server, оно сразу же запускается. Чтобы узнать, почему это происходит, давайте посмотрим на волшебство в Dockerfile.

Погрузитесь в образ Rocker / Shiny

FROM rocker/r-ver:3.6.3

RUN apt-get update && apt-get install -y \
    sudo \
    gdebi-core \
    pandoc \
    pandoc-citeproc \
    libcurl4-gnutls-dev \
    libcairo2-dev \
    libxt-dev \
    xtail \
    wget


# Download and install shiny server
RUN wget --no-verbose https://download3.rstudio.org/ubuntu-14.04/x86_64/VERSION -O "version.txt" && \
    VERSION=$(cat version.txt)  && \
    wget --no-verbose "https://download3.rstudio.org/ubuntu-14.04/x86_64/shiny-server-$VERSION-amd64.deb" -O ss-latest.deb && \
    gdebi -n ss-latest.deb && \
    rm -f version.txt ss-latest.deb && \
    . /etc/environment && \
    R -e "install.packages(c('shiny', 'rmarkdown'), repos='$MRAN')" && \
    cp -R /usr/local/lib/R/site-library/shiny/examples/* /srv/shiny-server/ && \
    chown shiny:shiny /var/lib/shiny-server

EXPOSE 3838

COPY shiny-server.sh /usr/bin/shiny-server.sh

CMD ["/usr/bin/shiny-server.sh"]

Здесь мы видим, что rocker/shiny образ использует базовый образ R Docker, а затем устанавливает блестящий пакет. Он также копирует shiny-server.sh файл из каталога сборки в образ. shiny-server.sh используется как запуск CMD. (Помните, RUN выполняет команду во время сборки, а CMD выполняет команду, когда контейнер запускается с docker run. Давайте исследуем shiny-server.sh файл запуска.

#!/bin/sh

# Make sure the directory for individual app logs exists
mkdir -p /var/log/shiny-server
chown shiny.shiny /var/log/shiny-server

if [ "$APPLICATION_LOGS_TO_STDOUT" != "false" ];
then
    # push the "real" application logs to stdout with xtail in detached mode
    exec xtail /var/log/shiny-server/ &
fi

# start shiny server
exec shiny-server 2>&1

Здесь мы видим, что сценарий shiny-server.sh выполняет команду с возможностью отправлять журналы на стандартный вывод или нет. Это то, что вы довольно часто будете видеть в контейнерах докеров. Когда вы строите, вы часто хотите видеть всю информацию журнала, но для производственных систем вам часто нужно, чтобы журналы были отправлены в файлы или инфраструктуру ведения журналов, такую ​​как logstash или elasticsearch.

Что делает shiny-server?

Мне всегда нравится копаться в самих контейнерах и видеть, что происходит, особенно когда речь идет о командах запуска и веб-серверах.

Чтобы покопаться в контейнере докеров, укажите флаг it (интерактивный и tty) и запустите команду bash. Это бросит вас прямо в раковину.

Выйдите из предыдущей команды запуска докера или не указывайте порт. В противном случае выполнение этой команды завершится ошибкой о том, что порт уже прослушивается.

docker run -it --rm \
-p 3838:3838 \
-v "$(pwd)/shiny-app":/srv/shiny-server \
rocker/shiny bash

Теперь, если я запускаю shiny-server --help, он запускает сервер Node и сообщает вам, какой файл конфигурации он просматривает. Я, как бесконечно любопытный человек, хотел узнать больше, поэтому пошел и посмотрел на репозиторий Github. Насколько я могу судить, и, пожалуйста, не держите меня за это, потому что я не особо говорю на javascript, но то, что он делает, - это читать в вашем файле конфигурации и создавать отдельный веб-сервер для каждой папки в /srv/shinyapps вместе с с красивыми маршрутами, которые соответствуют именам ваших папок, вот как вы получаете это красивое перетаскивание и сияние RShiny!

Создайте собственное изображение Rocker / Shiny

Теперь, если вы хотите установить какие-либо дополнительные системные пакеты, вам нужно будет создать новый образ.

Я также предпочитаю, чтобы мое приложение было в образе докера, а не монтировалось в файловой системе для производственных целей, поэтому мы сделаем это и здесь.

Ваша структура каталогов должна выглядеть так:

Dockerfile
shiny-app/
    app-R

Вот образец файла Dockerfile.

# Dockerfile
FROM rocker/shiny:3.6.3

RUN apt-get update && apt-get install -y \
    things-i-want-to-install
    
COPY shiny-app/app.R /srv/shiny-app/app.R

После того, как у вас есть Dockerfile настройка, вам просто нужно создать свой образ.

docker build -t my-rshiny-app .

За исключением, знаете ли, лучшего имени и более информативного имени, в котором абсолютно ничего не содержится.

Заворачивать

И это все! Ваш образ докера унаследует команду запуска от изображения рокера / блестящего, поэтому необходимо указать ее здесь. Просто добавьте дополнительные пакеты, скопируйте файлы и процветайте!

Первоначально опубликовано на https://www.dabbleofdevops.com.