yihui / servr

A simple HTTP server in R
https://cran.rstudio.com/package=servr
278 stars 35 forks source link

How to run server inside docker #49

Closed pythiantech closed 4 years ago

pythiantech commented 4 years ago

I am using servr to serve leaflet tiles in a Shiny application :

deamon_id <- servr::httd(port = 8001, daemon = TRUE)

base_map <- leaflet() %>% 
    addTiles( urlTemplate = "http://localhost:8001/test/{z}_{x}_{y}.jpg")

The application works well locally. However when I dockerize and try to run it, the tiles don't show up. I guess this is because the dockerized version of the application is looking for a server running locally on 8001 which is obviously not the case. Is there any way I can overcome this problem?

cderv commented 4 years ago

Can you provide a reproducible example with docker so that we completly understand the issue with servr ? Like a Dockerfile we could use. It would really help ! Thank you !

pythiantech commented 4 years ago

@cderv this is the Dockerfile

# get shiny server plus tidyverse packages image
FROM rocker/shiny:3.6.3

# system libraries of general use
RUN apt-get update && apt-get install -y \
    sudo \
    pandoc \
    pandoc-citeproc \
    libcurl4-gnutls-dev \
    libcairo2-dev \
    libxt-dev \
    libssl-dev \
    libssh2-1-dev \
    libudunits2-dev \
    libgdal-dev libgeos-dev libproj-dev libfontconfig1-dev  \
    libxml2-dev #Need this for xml2 which in turn is needed by highcharter

# install R packages required 
RUN R -e "install.packages('RgoogleMaps', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('dplyr', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('ggplot2', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('tidyr', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('readr', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('stringr', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('purrr', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('leaflet', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('leaflet.extras', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('leaflet.minicharts', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('sf', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('shiny', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('shinyjs', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('shinythemes', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('shinyWidgets', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('servr', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('waiter', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('splitr', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('shinyalert', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('shinyTime', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('lubridate', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('leafem', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('leafpop', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('leafpm', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('dygraphs', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('xts', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('XML', repos='http://www.omegahat.net/R')"
RUN R -e "install.packages('highcharter', repos='http://cran.rstudio.com/')"

# copy the app to the image

COPY /EmergencyManagement /srv/shiny-server/
RUN chmod -R +rx /srv/shiny-server/

# select port
EXPOSE 3838 8001

# allow permission
RUN chown -R shiny:shiny /srv/shiny-server
pythiantech commented 4 years ago

Also the logs show that the httpd server is running

Serving the directory /srv/shiny-server at http://127.0.0.1:8001

Listening on http://127.0.0.1:35889
cderv commented 4 years ago

OK but we don't have the code of your app in their. So we can't try to reproduce.

Just a guess then: You may need to change the default servr configuration so that it works with your docker stuff. See ?servr::server_config. You can change the host. Either by an option, or by passing host = in httd()

pythiantech commented 4 years ago

@cderv thanks! Been going through the documentation which says that host is A string that is a valid IPv4 address that is owned by this server, or "0.0.0.0" to listen on all IP addresses. Does it mean that I will have to put in the IP address of the Docker container here? I am sorry but I am not too conversant with this.

cderv commented 4 years ago

basemap <- leaflet() %>% addTiles( urlTemplate = "http://localhost:8001/test/{z}{x}_{y}.jpg")

Does this generates a url with localhost that is in the HTML file ? and the browser try to get access to localhost ?

From what I can guess it is and that is why I think you should put a url accessible from the browser (the client outside docket).

I can't run your example so for now it is just guesses and it may not be that at all ! Trying to build a small reproducible example with your issue would help us investigate.

pythiantech commented 4 years ago

The leaflet package adds map tiles which I am trying to serve through a folder called test, locally. This folder contains custom tiles in jpg format. When I run the Shiny application locally, there is no issue because the folder getting served is located at http://localhost:8001/test/. The issue is that when I dockerize the application, on the host machine, there is no folder at http://localhost:8001/test/. This folder is inside the docker container and not the host machine. Within the container I can see that it is running fine. But my Leaflet map is looking for the folder on the host machine and not the container. I don't this is a servr issue. More of a Docker/Leaflet issue.

cderv commented 4 years ago

I don't this is a servr issue. More of a Docker/Leaflet issue.

Then this should be better asked on RStudio Community (https://community.rstudio.com/) - There is a broad community of R users ready to help, and maybe someone has done something similar.

Curently, I can't help more without a proper minimal reproducible example, so that I can run your case on my computer.

pythiantech commented 4 years ago

@cderv thanks, appreciate your help. I'll see if I can provide you with a reprex at some stage.

cderv commented 4 years ago

One thing you can try though is setting the host to 0.0.0.0

deamon_id <- servr::httd(port = 8001, host = "0.0.0.0", daemon = TRUE)

Did you try that already ?

pythiantech commented 4 years ago

Hallelujah! That worked. Thank you so much @cderv

pythiantech commented 4 years ago

Amended the code:

deamon_id <- servr::httd(port = 8001, daemon = TRUE, host = '0.0.0.0')

base_map <- leaflet() %>% 
    addTiles( urlTemplate = "http://0.0.0.0:8001/test/{z}_{x}_{y}.jpg")
cderv commented 4 years ago

Glad it works !