Search code examples
rdockerpackagedockerfileinstall.packages

One R packages file for multiple Dockerfiles


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?


Solution

  • 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