多个 Dockerfile 的一个 R 包文件

One R packages file for multiple Dockerfiles

我制作了 两张 Docker 图片,一张是我的 rstudio 图像,另一个是 cron 图像到 运行 我的 cronjobs(R 脚本).
我正在构建其他图像(Shiny 等),它们需要与 cron 图像和 rstudio 图像完全相同的 R 包。
所以我想要一个文件,我可以在其中列出 所有 R 包 我的不同图像将需要这些包。 我的文件夹结构如下:

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

例如,对于我的 rstudio 的 Dockerfile 图片我尝试了以下方法:

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: No such file or directory

因为我假设 r_packages.txt 应该与我的 rstudio Docker 文件位于同一目录中,但是我希望我的 r_packages 可用于 ALL 我的图像,我该如何实现?

来自 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 时,您提到的文件超出范围(它位于上下文下方的文件夹中)。

要解决此问题,请从包含您的 r_packages.txt 的文件夹构建您的 docker 文件,并告诉 docker 构建命令您的 Dockerfile 使用命令行参数 -f 的位置。

docker build -f cron/Dockerfile

注意:您必须将文件路径更改为 COPY,方法是在包含您的 Dockerfile 的文件夹(此处为您的 cron 映像的 cron)之前添加内容,因为上下文已更改 (COPY cron/crontab /somewehere 我猜你的 cron 映像)

您需要从项目目录 运行 构建命令,而不是 Docker 文件所在的目录。原因是 Docker 使用了上下文的概念,类似于工作目录。 Docker 构建器无法访问上下文目录之外(上方)的文件,但它可以向下查看子目录。当您使用 Docker 文件从目录更改上下文时,您必须指定要使用的 Docker 文件。例如,要构建 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 文件,除非您明确添加它。将您的 Docker 文件更改为此文件以解决此问题:

FROM rocker/tidyverse:3.6.1

COPY r_packages.txt /r_packages.txt
RUN cat /r_packages.txt