#r #docker #package #dockerfile #install.packages
#r #docker #пакет #dockerfile #install.packages
Вопрос:
Я создал два образа Docker, один из которых — мой образ rstudio, а другой — образ cron для запуска моих cronjobs (R-скриптов).
Я создаю другие изображения (блестящие и т. Д.), Которым понадобятся точно такие же пакеты R, Чем образ cron и образ rstudio.
Поэтому я хотел бы иметь один единственный файл, в котором я мог бы перечислить все пакеты R, которые понадобятся для моих разных изображений. Структура моих папок следующая:
├── cron
│ ├── crontab
│ └── Dockerfile
├── rstudio
│ └── Dockerfile
├── r_packages.txt
В качестве примера, для файла Dockerfile моего образа rstudio я попробовал следующее:
FROM rocker/tidyverse:3.6.1
## Create directories
RUN mkdir -p /rstudio
RUN mkdir -p /rscripts
RUN cat /home/ec2-user/r_packages.txt
с содержимым r_packages.txt как следует:
R -e "install.packages(c('writexl','readxl','rjson','httr','rvest','DBI','RPostgres','stringr','xlsx','knitr','kableExtra','devtools','RSelenium'))"
Но я получаю следующую ошибку:
cat: /home/ec2-user/r_packages.txt : Нет такого файла или каталога
Поскольку я предполагаю r_packages.txt
, что он должен находиться в том же каталоге, что и мой файл Dockerfile rstudio, но я хочу, чтобы мои r_packages были доступны для ВСЕХ моих изображений, как я могу этого добиться?
Комментарии:
1. Вы также можете запустить cron с хоста и вызвать R внутри контейнера rstudio. Используйте что-то вроде
docker container exec -u rstudio -it mycontainer Rscript /path/to/script.R
. Таким образом, вам нужен только один набор пакетов.
Ответ №1:
Вам нужно запустить команду сборки из каталога вашего проекта, а не там, где находятся ваши файлы Dockerfile. Причина этого в том, что Docker использует концепцию контекста, которая похожа на рабочий каталог. Docker builder не может получить доступ к файлам за пределами (выше) контекстного каталога, но он может просматривать подкаталоги. При изменении контекста из каталога с файлом Dockerfile необходимо указать используемый файл Dockerfile. Например, чтобы создать образ cron, вы должны запустить:
docker build -t cron_image_tag -f cron/Dockerfile /directory/with/r_packages.txt
Чтобы исправить cat: /home/ec2-user/r_packages.txt: No such file or directory
ошибку, вам нужно сделать еще одну вещь. При использовании вы RUN
запускаете эту команду внутри контейнера сборки. В контейнере не будет r_packages.txt
файла, если вы явно не добавите его. Измените свой файл Dockerfile на this, чтобы исправить это:
FROM rocker/tidyverse:3.6.1
COPY r_packages.txt /r_packages.txt
RUN cat /r_packages.txt
Ответ №2:
Из документации Dockerfile
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.
По умолчанию контекст — это место, где находится файл Dockerfile. Поэтому, когда вы создаете любой свой Dockerfile из того места, где он находится, указанный вами файл выходит за рамки (он находится в папке ниже контекста).
Чтобы решить эту проблему, создайте свой файл dockerfile из папки, содержащей ваш r_packages.txt
, и сообщите команде сборки docker, где находится ваш файл Dockerfile, используя параметр командной строки -f
.
docker build -f cron/Dockerfile
ПРИМЕЧАНИЕ: вам нужно будет изменить путь COPY
к файлам, добавив папку, содержащую ваш файл Dockerfile (здесь cron для вашего образа cron), поскольку контекст изменился ( COPY cron/crontab /somewehere
я думаю, для вашего образа cron)