You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golem框架Shiny应用在Google Cloud Run部署时图片路径配置问题

问题描述

目标

在Shiny应用中渲染多个以图片为分面标签的ggplot图表,完整源码可查看对应GitHub仓库。

细节与问题

需创建两个共用同一批图片的图表。在常规Shiny应用中,可在global.R中读取图片后在服务器端生成图表。在Golem框架下,创建了R/global.R文件,代码如下:

labels_flowers <- c(
  setosa     = paste0("<img src='", "inst/app/www", "/", "setosa.jpg' width='100'/>"),
  versicolor = paste0("<img src='", "inst/app/www", "/", "versicolor.jpg' width='100'/>"),
  virginica  = paste0("<img src='", "inst/app/www", "/", "virginica.jpg' width='100'/>")
)

随后在两个模块中使用该变量。

模块示例

模块代码如下:

#' plot UI Function
#'
#' @description A shiny Module.
#'
#' @param id,input,output,session Internal parameters for {shiny}.
#'
#' @noRd
#'
#' @import shiny
#' @import ggplot2
#' @import ggtext
mod_plot_ui <- function(id){
  ns <- NS(id)
  tagList(
    plotOutput(ns("myplot"))
  )
}

#' plot Server Functions
#'
#' @noRd
mod_plot_server <- function(id, data){
  moduleServer( id, function(input, output, session){
    ns <- session$ns
    output$myplot <- renderPlot({
      ggplot(data = data()) +
        geom_histogram(aes(Sepal.Length)) +
        facet_wrap(~ Species, labeller = as_labeller(labels_flowers)) +
        theme(strip.text.x = ggtext::element_markdown(size = 20))
    })
  })
}

app_ui.R和app_server.R中对模块的调用方式如下:

app_ui.R

#' The application User-Interface
#'
#' @param request Internal parameter for `{shiny}`.
#'     DO NOT REMOVE.
#' @import shiny
#' @noRd
app_ui <- function(request) {
  tagList(
    # Leave this function for adding external resources
    golem_add_external_resources(),
    # Your application UI logic
    fluidPage(
      h1("example"),
      mod_plot_ui("plot1"),
      mod_plot2_ui("plot2")
    )
  )
}

#' Add external Resources to the Application
#'
#' This function is internally used to add external
#' resources inside the Shiny application.
#'
#' @import shiny
#' @importFrom golem add_resource_path activate_js favicon bundle_resources
#' @noRd
golem_add_external_resources <- function() {
  add_resource_path(
    "www",
    app_sys("app/www")
  )

  tags$head(
    favicon(),
    bundle_resources(
      path = app_sys("app/www"),
      app_title = "example"
    )
    # Add here other external resources
    # for example, you can add shinyalert::useShinyalert()
  )
}

app_server.R

#' The application server-side
#'
#' @param input,output,session Internal parameters for {shiny}.
#'     DO NOT REMOVE.
#' @import shiny
#' @import ggplot2
#' @import ggtext
#' @noRd
app_server <- function(input, output, session) {

  df_iris <- reactive(iris)

  mod_plot_server("plot1", df_iris)
  mod_plot2_server("plot2", df_iris)

}

部署问题

应用在本地和shinyapps上运行正常,但通过Docker部署到Google Cloud Run时出现错误:
错误截图


解决方案

问题核心是图片路径配置不符合Golem部署后的资源映射规则,以及Docker环境下的文件结构差异。需做以下修改:

1. 修正R/global.R中的图片路径

Golem框架会将inst/app/www目录构建后映射到/www路径下,直接使用映射后的路径即可,无需硬编码开发时的目录结构:

labels_flowers <- c(
  setosa     = paste0("<img src='/www/setosa.jpg' width='100'/>"),
  versicolor = paste0("<img src='/www/versicolor.jpg' width='100'/>"),
  virginica  = paste0("<img src='/www/virginica.jpg' width='100'/>")
)

2. 确保Dockerfile正确处理资源文件

如果使用rocker/shiny类镜像,需保证Golem构建后的app/www目录被正确复制到容器中,典型Dockerfile示例:

# 基础镜像
FROM rocker/shiny:latest

# 安装依赖
RUN apt-get update && apt-get install -y \
    libssl-dev \
    libcurl4-openssl-dev \
    libfontconfig1-dev \
    libharfbuzz-dev \
    libfribidi-dev \
    libpng-dev \
    libtiff5-dev \
    libjpeg-dev

# 安装R包
RUN R -e "install.packages(c('shiny', 'ggplot2', 'ggtext', 'golem'))"

# 复制应用文件
COPY . /app
WORKDIR /app

# 启动应用
CMD ["R", "-e", "shiny::runApp(appDir = '/app', host = '0.0.0.0', port = as.numeric(Sys.getenv('PORT')))"]

3. 验证资源路径有效性

可在app_ui.R中添加测试代码,确认图片路径是否正确:

tags$img(src = "/www/setosa.jpg", width = "100px")

若该图片能正常显示,说明路径配置无误,ggplot分面标签的图片也能正常加载。


内容的提问来源于stack exchange,提问作者umair durrani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 12:02:10