5

I have built two Docker images one is my rstudio image and the other is a cron image to run my cronjobs (R scripts).
I am building other images (Shiny etc.) that will need the exact same R packages than the cron image and the rstudio image.
So I would like to have one single file where I can list all the R packages that will be needed for my different images. The stucture of my folders are the following:

├── cron
│   ├── crontab
│   └── Dockerfile
├── rstudio
│   └── Dockerfile
├── r_packages.txt

As an example, for the Dockerfile of my rstudio image I tried the following:

FROM rocker/tidyverse:3.6.1

## Create directories
RUN mkdir -p /rstudio
RUN mkdir -p /rscripts

RUN cat /home/ec2-user/r_packages.txt

with the content of r_packages.txt as follow:

R -e "install.packages(c('writexl','readxl','rjson','httr','rvest','DBI','RPostgres','stringr','xlsx','knitr','kableExtra','devtools','RSelenium'))"

But I get the following error:

cat: /home/ec2-user/r_packages.txt: No such file or directory

Because I assume the r_packages.txt should be in the same directory as my rstudio Dockerfile but I want my r_packages available for ALL my images, how can I achieve that?

ML_Enthousiast
  • 1,147
  • 1
  • 15
  • 39
  • You can also run cron from the host and have it call R inside the rstudio container. Use something like `docker container exec -u rstudio -it mycontainer Rscript /path/to/script.R`. This way you only need one set of packages. – Michael Dewar Dec 01 '20 at 02:50

2 Answers2

2

You need to run build command from the directory of your project, not where your Dockerfiles are. The reason for that is that Docker uses a concept of context, which is similar to a working directory. Docker builder cannot access files outside (above) the context directory, but it can look down into subdirectories. When you change the context from the directory with a Dockerfile, you have to specify the Dockerfile to use. For example to build the cron image you have to run:

docker build -t cron_image_tag -f cron/Dockerfile /directory/with/r_packages.txt

To fix the cat: /home/ec2-user/r_packages.txt: No such file or directory error you have to do one more thing. When you use RUN, you run that command inside the building container. The container won't have the r_packages.txt file unless you explicitly add it. Change your Dockerfile to this to fix this:

FROM rocker/tidyverse:3.6.1

COPY r_packages.txt /r_packages.txt
RUN cat /r_packages.txt
anemyte
  • 17,618
  • 1
  • 24
  • 45
0

From Dockerfile documentation

The COPY instruction copies new files or directories from <src> and adds them to the filesystem of the container at the path <dest>.

Multiple <src> resources may be specified but the paths of files and directories will be interpreted as relative to the source of the context of the build.

By default context is where the Dockerfile is. So when you build any of your Dockerfile from where it is, the file you mention is out of scope (it is in a folder below context).

To solve this build your dockerfile from the folder containing your r_packages.txt and tell the docker build command where your Dockerfile is using command line parameter -f.

docker build -f cron/Dockerfile

NB: You'll have to change path of files to COPY by prepending the folder containing your Dockerfile (here cron for your cron image) as context has changed (COPY cron/crontab /somewehere I guess for you cron image)

Billy34
  • 1,777
  • 11
  • 11