通过 FROM 从不同的本地目录导入 Dockerfile

Import Dockerfile from different local directory via FROM

我想创建一个多阶段构建过程,而每个 docker 文件都嵌套在它们自己的本地目录中,并为每个 Docker 文件添加了相应的依赖项。有没有办法从本地的不同目录导入 Docker 文件,而我可以使用 Docker 的 FROM 命令导入它,以在构建中创建多个阶段?

如果没有,我是否可以 ADD 将另一个暂存的 Docker 文件放入当前 Docker 文件,然后在 docker 中使用 FROM ]容器,在FROM中添加使用后删除?

也许我以错误的方式考虑多阶段构建。

或者我可以简单地 运行 FROM {path/to/docker/locally} 吗?这对我不起作用。

Is there a way to import a Docker file from a different directory locally whereas I am able to import it with Docker's FROM command, to create several stages in a build?

没有。 FROM指令仅用于导入pre-built个镜像,不能用于导入Dockerfile。

If not, would I be able to ADD the other staged Docker file's into the current Docker file?

没有。 ADD 指令只能将构建上下文(通常是当前工作目录) 中的文件 复制到容器中。你不能 ADD ../something /something.

Or can I simply run FROM {path/to/docker/locally}?

没有。但是一种对你有用的方法是,首先构建另一个图像,假设它的名字是 first-image:latest,然后你可以使用 COPY 指令从该图像复制文件:

COPY --from=first-image:latest /some/file /some/file

如果我对问题的理解正确,那么你想要实现的是构建一个图像,然后使用相同的图像并在其之上构建一些东西(下一个 »stage«)。

Docker 支持此概念,但不通过导入另一个 Docker 文件。

Docker 个文件和它们所在的目录应该是 self-contained,i。 e.构建映像所需的唯一内容就是这些目录内容。因此,您无法从其他目录加载其他 Docker 文件。

要走的路是构建一个基本图像,例如。 G。 myappimage,使用 Docker 文件 myappimage/Dockerfile。构建完成后,您可以在另一个 Docker 文件(例如 mytestingimage/Dockerfile)中引用此基础图像,使用 FROM myappimagemyappimage

然后,mytestingimagemyappimage 完全相同,但通过您的 ADD 和其他命令添加了额外的层。

如果你使用Docker 20.10+,你可以这样做:

# syntax = edrevo/dockerfile-plus

INCLUDE+ {path/to/docker/locally}

RUN ...

INCLUDE+ 指令由 Docker 文件的第一行导入。您可以在 https://github.com/edrevo/dockerfile-plus

阅读更多关于 dockerfile-plus 的信息

到目前为止,我找到的最佳解决方案是使用 Dockerfile stages

将所有这些放在一个单一的 Dockerfile:

FROM php:8.1-fpm AS base

RUN apt-get update && apt-get install -y \
    libzip-dev libonig-dev \
    libwebp-dev # ...

RUN docker-php-ext-install zip mbstring pdo pdo_mysql gd bcmath sockets opcache soap gmp intl

# Worker
FROM base AS worker
RUN apt install -y supervisor 

# CLI
FROM base AS cli
RUN apt-get install -yq git unzip
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

然后你可以在docker-compose.yml中使用它:

services:
  worker:
    build:
      context: php
      dockerfile: Dockerfile
      target: worker

  cli:
    build:
      context: php
      dockerfile: Dockerfile
      target: cli

这将使容器构建更高效,base 将只构建一次。 您也可以使用 base 本身作为目标。