Reputation: 29
I was run shiny app through docker. But it works on RStudio but when I run it through docker it gives an error:
Undefined error in httr call. httr output: Failed to connect to localhost port 4445 after 0 ms: Connection refused
Shiny Code:
# app.R
library(shiny)
library(RSelenium)
ui <- fluidPage(
actionButton("btn", "Click Me"),
textOutput("result")
)
server <- function(input, output, session) {
# Start the remote driver
remDr <- remoteDriver(
remoteServerAddr = "localhost", # Docker container host
port = 4445L, # Docker container port
browserName = "chrome",
)
observeEvent(input$btn, {
output$result <- renderText({
remDr$open()
# Navigate to a website (e.g., Google)
remDr$navigate("https://www.google.com")
remDr$maxWindowSize()
# Perform some actions (e.g., print page title)
title <- remDr$getTitle()
return(as.character(title))
})
})
session$onSessionEnded(function() {
# Close the remote driver
remDr$close()
})
}
shinyApp(ui, server)
Dockerfile:
FROM rocker/shiny:4
# Install R packages required
# Change the packages list to suit your needs
RUN R -e "install.packages(c('shiny', 'RSelenium', 'httr'), dependencies=TRUE)"
# Copy the Shiny app files into the image
COPY app.R /srv/shiny-server/
# Expose port 3838 for Shiny app
EXPOSE 3838
# Run Shiny app on container start
CMD ["R", "-e", "shiny::runApp('/srv/shiny-server/app.R', host = '0.0.0.0', port = 3838)"]
Executed Docker Command:
docker pull selenium/standalone-chrome:4.2.2
docker run -d -p 4445:4444 --shm-size 4g selenium/standalone-chrome:4.2.2
docker build -t shiny-rselenium .
docker run -p 3838:3838 shiny-rselenium
Everything works perfectly on RStudio. But I face that error when I go to localhost:3838. How Can I fix this problem?
Upvotes: 0
Views: 138
Reputation: 17389
In the context of the container, localhost
resolves to the container instance itself and not to the host system. If you are using Docker Dektop and want to go though published port, you could try replacing localhost
with host.docker.internal
, i.e. :
remDr <- remoteDriver(
remoteServerAddr = "host.docker.internal", # Docker container host
port = 4445L, # Docker container port
browserName = "chrome",
)
Though I'd rather use Docker Compose and let it handle networking.
First, let's update remoteDriver()
call so it can be configured through environment variables and same file could be used in different environments, defaults set to localhost:4445
:
remDr <- remoteDriver(
remoteServerAddr = Sys.getenv("SELENIUM_HOST", "localhost"),
port = as.integer(Sys.getenv("SELENIUM_PORT", "4445")),
browserName = "chrome",
)
comopse.yaml
:services:
shiny-rselenium:
build: .
ports:
- "3838:3838"
environment:
- SELENIUM_HOST=selenium
- SELENIUM_PORT=4444
depends_on:
- selenium
selenium:
image: "selenium/standalone-chrome:4.2.2"
shm_size: 4g
PS > docker compose up -d
[+] Building 0.0s (0/0) docker:default
[+] Running 3/3
✔ Network shinydkr_default Created 0.1s
✔ Container shinydkr-selenium-1 Started 0.1s
✔ Container shinydkr-shiny-rselenium-1 Started 0.1s
PS > docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
shinydkr-selenium-1 selenium/standalone-chrome:4.2.2 "/opt/bin/entry_poin…" selenium 23 seconds ago Up 22 seconds 4444/tcp, 5900/tcp
shinydkr-shiny-rselenium-1 shinydkr-shiny-rselenium "R -e 'shiny::runApp…" shiny-rselenium 23 seconds ago Up 22 seconds 0.0.0.0:3838->3838/tcp
PS > docker compose down
[+] Running 3/3
✔ Container shinydkr-shiny-rselenium-1 Removed 10.4s
✔ Container shinydkr-selenium-1 Removed 4.3s
✔ Network shinydkr_default Removed
Upvotes: 0