0
votes

Read:

I have created a simple shiny app using the rstudio template app.r when creating a new shiny web app.

My directory:

doug:~/Projects/test$ pwd
/home/work/Projects/test
doug:~/Projects/test$ ls -l
total 20
-rw-r--r-- 1 work work  178 Sep 24 18:27 docker-compose.yml
-rw-r--r-- 1 work work  240 Sep 24 18:16 Dockerfile
drwxr-xr-x 2 work work 4096 Sep 24 13:55 test_app
-rw-r--r-- 1 work work  205 Sep 24 13:45 test.Rproj

My Docker file:

FROM rocker/shiny-verse

COPY test_app mountpoints/apps/test_app

RUN apt-get update \
    && apt-get upgrade -y
    
WORKDIR mountpoints/apps/test_app

EXPOSE 3838

CMD R --no-save -e 'shiny::runApp("app.R", port = 3838, host = "0.0.0.0")'

My docker-compose file:

version: '3.2'
services:
  test:
    build:
      context: .
      dockerfile: Dockerfile
    restart: always
    image: test:latest
    ports:
      - '80:3838'
    user: 'root'

I built the image:

doug:~/Projects/test$ docker build -t test .
Sending build context to Docker daemon  34.82kB
Step 1/6 : FROM rocker/shiny-verse
 ---> 6ca67ad3f372
Step 2/6 : COPY test_app mountpoints/apps/test_app
 ---> Using cache
 ---> 7d34eee9154b
Step 3/6 : RUN apt-get update     && apt-get upgrade -y
 ---> Using cache
 ---> 6a9f0856291a
Step 4/6 : WORKDIR mountpoints/apps/test_app
 ---> Using cache
 ---> 30897306d02b
Step 5/6 : EXPOSE 3838
 ---> Using cache
 ---> 0affe5f79ba4
Step 6/6 : CMD R --no-save -e 'shiny::runApp("app.R", port = 3838, host = "0.0.0.0")'
 ---> Using cache
 ---> 1ce09f39c2ce
Successfully built 1ce09f39c2ce
Successfully tagged test:latest

I then tried to run with docker-compose:

doug:~/Projects/test$ docker-compose run test

R version 4.0.2 (2020-06-22) -- "Taking Off Again"
Copyright (C) 2020 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> shiny::runApp("app.R", port = 3838, host = "0.0.0.0")
Loading required package: shiny

Listening on http://0.0.0.0:3838

Now, when I try to visit the app at http://0.0.0.0:3838 in my browser I get:

This site can’t be reached 0.0.0.0 refused to connect.

I tried some variations: 127.0.0.1:3838 localhost:3838 127.0.0.1:3838/test_app localhost:3838/test_app

In all cases, I saw the same message and was unable to view my app in the browser.

I tried experimenting with the ports part of the docker-compose file above:

ports:

  • '80:3838'

Tried:

'3838:3838', '127.0.0.1:3838', '3838'

In each case I rebuilt the image and tried again, but I was still unable to view my app in the browser.

How can I run my Shiny app and view it in the browser?

1
The ports first number is the host port, the second number is the container port. When you are connecting from outside of the container (i.e., from your browser), you should connect to the host port number, which is 80 (if your OS's security posture allows docker containers to run services on ports under 1024). So either change your docker-compose.yml to read - '3838:3838' or browse to 127.0.0.1:80 (or just http://127.0.0.1, since :80 is inferred from http://). See docs.docker.com/engine/reference/run/#expose-incoming-ports - r2evans
Hi, thanks for the suggestion. I tried just going to 127.0.0.1 but I have Nextcloud app running there already. So I then tried changing ports per your suggestion to - '3838:3838'. I then ran with docker-compose and tried both 127.0.0.1:3838 and 127.0.0.1:3838 test_app but saw the same error message - Doug Fir
This is docker-compose doing it to you. I ran something similar and could not find it with docker-compose run test, but when I did simply docker run -p 3838:3838 --rm test, I connected to http://localhost:3838 immediately. - r2evans

1 Answers

2
votes

While I know you are intending to use docker-compose, my first step to make sure basic networking was working. I was able to connect with:

docker run -it --rm -p 3838:3838 test

Then I tried basic docker, and I was able to get this to work

docker-compose run -p 3838:3838 test

(Again, the need for -p 3838:3838 ...)

From there, it appears that docker-compose is really meant to start things with up instead. I was also able to see the shiny app when I instead (after stopping the above container) running

docker-compose up -d test

So the difference is between run and up. Reading https://docs.docker.com/compose/reference/run/, I found this:

Commands you use with run start in new containers with configuration defined by that of the service, including volumes, links, and other details. However, there are two important differences.

First, the command passed by run overrides the command defined in the service configuration. For example, if the web service configuration is started with bash, then docker-compose run web python app.py overrides it with python app.py.

The second difference is that the docker-compose run command does not create any of the ports specified in the service configuration. This prevents port collisions with already-open ports. If you do want the service’s ports to be created and mapped to the host, specify the --service-ports flag ...

(emphasis mine)

Which led me to try (and succeed with):

docker-compose run --service-ports test

And with all of those, http://localhost:3838 worked (for me on windows ... should work for others as well, though if not localhost then try 127.0.0.1).


My files, slightly-modified for speed of testing, and because I don't have your test_app:

Dockerfile

FROM rocker/shiny-verse
EXPOSE 3838
CMD R --no-save -e 'library(shiny); runExample("01_hello", port=3838, host="0.0.0.0");'

docker-compose.yml

version: '3.2'
services:
  test:
    build:
      context: .
      dockerfile: Dockerfile
    restart: always
    image: test:latest
    ports:
      - "3838:3838"
    user: 'root'