MarkEdmondson1234 / markedmondson.me-hugo

Files for the website
0 stars 2 forks source link

shiny-cloudrun/ #12

Open utterances-bot opened 3 years ago

utterances-bot commented 3 years ago

Shiny on Google Cloud Run - Scale-to-Zero R Web Apps · Mark Edmondson

How to create scale-to-zero Shiny apps on Google Cloud Run: pitfalls, how and why

https://code.markedmondson.me/shiny-cloudrun/

noamanemobidata commented 3 years ago

Hello Mark! Thank you for this great work! I see that google cloud run supports WebSockets since June 22, 2021 : https://cloud.google.com/run/docs/release-notes#June_22_2021

I try to use this service to host a simple app that display a google map :

library(shiny)
library(googleway)
ui <- fluidPage(
  google_mapOutput(outputId = "map", height = "800px")
)

server <- function(input, output){

  mapKey <- "****"
  output$map <- renderGoogle_map({
    google_map(key = mapKey) %>%
      add_drawing(drawing_modes = c("circle"))
  })

  observeEvent(input$map_circlecomplete, {
    print(input$map_circlecomplete)
  })
}

shinyApp(ui = ui, server = server, options = list(port =as.integer(Sys.getenv('PORT')), host = "0.0.0.0"))

with this Dockerfile :

FROM rocker/shiny

RUN apt-get update -y && apt-get install -y libssl-dev libmariadbclient-dev libxml2-dev libpq-dev libv8-dev libjpeg-dev libjq-dev libsodium-dev

COPY [".", "./"]

RUN R -e  "install.packages('shiny')"
RUN R -e  "install.packages('googleway')"

EXPOSE 8080

CMD ["Rscript", "app.R"]

The app runs But I get this Error : Static path must not have trailing slash

image info

MarkEdmondson1234 commented 3 years ago

Hi! Not come across this before, I suspect its a URL hardcoded in the R package you are using (googleway) that ends with / ? I don't think its specific to Cloud Run, unless you say its running fine on other platforms? It would be good to narrow down exactly where the error is occuring - in the R excution or in the Cloud Run backend etc.

If it is a platform issue, you may also need to look at making sure the websocket ports etc are open in your Shiny configuration.

Hope that helps!

noamanemobidata commented 3 years ago

It works in shinyapps.io, I fixed the issue and it works in Cloud Run also ( problem with Dockerfile )

FROM rocker/shiny:4.0.5

RUN apt-get update && apt-get install -y \
    libcurl4-gnutls-dev \
    libssl-dev

RUN R -e  "install.packages('shiny')"
RUN R -e  "install.packages('googleway')"

COPY shinyserver.config /etc/shiny-server/shiny-server.conf
COPY app.R /srv/shiny-server/app.R

EXPOSE 8080

USER shiny

# run app
CMD ["/usr/bin/shiny-server"]
MarkEdmondson1234 commented 3 years ago

Ok great! What is in the shiny-server.conf file that fixes it?

noamanemobidata commented 3 years ago

I changed the way of runing the app ( from CMD ["Rscript", "app.R"] to CMD ["/usr/bin/shiny-server"] )... which caused another problem : I have some environment variables in CLoud Run but the shiny user can't access it

MarkEdmondson1234 commented 3 years ago

Yeah thats a general gotcha for Shiny apps in general - they don't read environment arguments.

MarkEdmondson1234 commented 2 years ago

Found this video the other day which includes a demo of adding IAP to your app so its protected behind a Google login: https://youtu.be/uu97P0IWsO0

MarkEdmondson1234 commented 2 years ago

And also note there is now sessionAffinity setting which will try to route users to the same container, which may take away some of Joe's concerns in the article https://cloud.google.com/run/docs/configuring/session-affinity

noamanemobidata commented 2 years ago

Thank you Mark! Since Shiny is statful, I'm using Redis to store user sessions as explained here : https://www.youtube.com/watch?v=mgTI-paDNQ4&ab_channel=GoogleCloudTech

MarkEdmondson1234 commented 2 years ago

Oh interesting, so you have R code that stores the Shiny session state? Do you know of any example code? I wonder if with this sessionAffinity flag is available now that you still need to do that?