如何通过 Docker 部署我的闪亮应用程序(包含多个文件)

问题描述 投票:0回答:1

我想通过 Docker 部署一个由文件

ui
server
global
组成的闪亮应用程序。所有文件都在文件夹中
deploy_test
我模拟了这个数据集

set.seed(123)
dir.create("deploy_test")
setwd("deploy_test")
mydata_<-data.frame(
  gender=c(rep("Male",50),rep("Female",25)),
  height=c(rnorm(50,1.70,0.05),rnorm(25,1.65,1))
)
saveRDS(mydata_,file = "mydata_.RDS")

以下是我的文件内容:

1. 用户界面

source("global.R")

dashboardPage(
  dashboardHeader(title = "Test of app deployment"),
  dashboardSidebar(
    
    selectInput("gender","Gender",as.character(unique(mydata_$gender)))
  ),
  dashboardBody(
    
    fluidRow(
      column(6,plotOutput(
        "plot1"
      )),
      column(6,plotOutput(
        "plot2"
      ))
    ),
    fluidRow(
      dataTableOutput(
        "table"
      )
    )
  )
)

2. 服务器

source("global.R")

function(input, output, session){
  
  output$plot1<-renderPlot(
    {
      data_<-mydata_%>%filter(
        gender==input$gender
      )
      boxplot(data_$height)
    }
  )
  
  
  output$plot2<-renderPlot(
    {
      data_<-mydata_%>%filter(
        gender==input$gender
      )
      hist(data_$height)
    }
  )
  
  
  output$table<-renderDataTable(
    {
      data_<-mydata_%>%filter(
        gender==input$gender
      )
      data_
    }
  )
  
  
}

3. 全球

library(shinydashboard)
library(shiny)
library(tidyverse)
library(DT)
mydata_<-readRDS("mydata_.RDS")

4. DOCKERFILE

Dockerfile 与 Shiny 位于同一文件夹中:

# Base image
FROM rocker/shiny

#Make a directory in the container
RUN mkdir /home/shiny-app


# Install dependencies
RUN R -e "install.packages(c('tidyverse','shiny','shinydashboard','DT'))"

COPY . /home/shiny-app/

EXPOSE 8180

CMD ["R", "-e", "shiny::runApp('/home/shiny-app')"]

我毫无问题地构建了我的容器:

docker build -t deploy_test .

当我运行它时:

docker run -p  8180:8180 deploy_test

它生成链接: 收听 http://xxx.x.x.x:xxxx

但是当我访问链接时什么也没有出现: 我得到:

La connexion a échoué

r docker shiny deployment shinydashboard
1个回答
0
投票

这有几个部分:要么指定

runApp(.., host=, port=)
,要么转向使用父映像中的内置闪亮服务器。

修复
runApp

首先是您公开端口 8180,但

runApp
的默认设置可能是随机分配端口。来自
?runApp

    port: The TCP port that the application should listen on. If the
          ‘port’ is not specified, and the ‘shiny.port’ option is set
          (with ‘options(shiny.port = XX)’), then that port will be
          used. Otherwise, use a random port between 3000:8000,
          excluding ports that are blocked by Google Chrome for being
          considered unsafe: 3659, 4045, 5060, 5061, 6000, 6566,
          6665:6669 and 6697. Up to twenty random ports will be tried.

我的猜测是它不会随机选择 8180,至少不够可靠让你可以依赖它。第二个问题是使用 docker 的

-p
的网络端口转发转发到容器主机,而不是容器的
localhost
(
127.0.0.1
)。因此,我们还应该为您的呼叫分配一位主持人
runApp
。也许

CMD ["R", "-e", "shiny::runApp('/home/shiny-app',host='0.0.0.0',port=8180)"]

当我这样做时,我可以运行容器并连接到

http://localhost:8180
并且那个闪亮的应用程序可以工作。 (当然,我稍微修改了闪亮的代码,因为我没有你的数据,但那是无关紧要的。) 仅供参考,如果您的图像基于

FROM rocker/shiny-verse

而不是

FROM rocker/shiny
,则不需要
install.packages('tidyverse')
,这可以节省一大笔钱。另外,使用
rocker/shiny
rocker/shiny-verse
,您不需要
install.packages('shiny')
,因为它已经存在了。节省了两个包裹。
使用内置的shiny-server

推荐使用

rocker/shiny-verse

的方法是将您的应用程序放入

/srv/shiny-server/appnamegoeshere
中,并使用嵌入到 docker 镜像中的已功能闪亮服务器。
两个好处,一个后果:

好处#1:您可以在一个 Docker 镜像中部署和提供多个应用程序;
  • 好处#2:如果/当shiny失败或退出时,内置的shiny-server会自动重新启动它;当
  • runApp(.)
  • 失败时,它会停止。 (当然,这是在代码中存在明显错误的情况下由闪亮的重新启动逻辑控制的。)
    结果:您的本地浏览器必须在 URL 中包含应用程序名称,如 
  • http://localhost:8180/appnamegoeshere
  • 所示。
    http://localhost:8180
    页面是一个主要是静态的登陆页面,表示闪亮服务器正在工作,并且默认情况下它不会列出服务器正在提供服务的所有应用程序。
    
    
  • 这意味着您的
Dockerfile

可以是这样的:

# Base image
FROM rocker/shiny-verse

# Install dependencies (tidyverse and shiny are already included)
RUN R -e "install.packages(c('shinydashboard', 'DT'))"

# Make a directory in the container
RUN mkdir /srv/shiny-server/myapp
COPY . /srv/shiny-server/myapp

就是这样,无需再获取所需的一切,因为 
CMD

已在父图像中定义。因为shiny-server默认使用端口3838,所以你的运行命令现在是

docker run -p 3838:3838 deploy_test

并且您的本地浏览器使用 
http://localhost:3838/myapp

进行浏览。

(仅供参考,

RUN

中的顺序以及

Dockerfile
中的其他命令可能会产生影响。例如,如果您在
install.packages(.)
之前更改任何内容,那么当您重新构建图像时,它必须重新安装这些软件包。由于我们不再需要(重新)安装 "tidyverse",这应该是相当小的,但如果您坚持使用
rocker/shiny
并且必须
install.packages("tidyverse")
,那么这可以节省大量资金。通过此应用程序的
RUN
COPY
命令
after
install.packages(..)
,那么如果我们稍后重命名该应用程序和/或添加更多 docker 命令,则该 install.packages 步骤将被缓存/保留,并且不需要重新运行。)
    

© www.soinside.com 2019 - 2024. All rights reserved.