扩展本地Dockerfile

扩展本地Dockerfile,docker,Docker,我正在尝试将一个Dockerfile建立在另一个本地文件的基础上 $ ls -lR total 0 -rw-r--r-- 1 me me 42 14 avr 10:42 Dockerfile drwxr-xr-x 3 me me 42 14 avr 10:42 prod ./prod: total 0 -rw-r--r-- 1 me me 42 14 avr 10:42 Dockerfile $ cat prod/Dockerfil

我正在尝试将一个
Dockerfile
建立在另一个本地文件的基础上

$ ls -lR
total 0
-rw-r--r--  1 me     me      42 14 avr 10:42 Dockerfile
drwxr-xr-x  3 me     me      42 14 avr 10:42 prod

./prod:
total 0
-rw-r--r--  1 me     me      42 14 avr 10:42 Dockerfile

$ cat prod/Dockerfile
FROM ../Dockerfile
...

$ docker build - < prod/Dockerfile
$ls-lR
总数0
-rw-r--r--1 me me 42 14 avr 10:42 Dockerfile
drwxr-xr-x 3 me 42 14 avr 10:42产品
/产品:
总数0
-rw-r--r--1 me me 42 14 avr 10:42 Dockerfile
$cat prod/Dockerfile
来自../Dockerfile
...
$docker构建-
无法处理Dockerfile:无法分析存储库信息:存储库名称组件必须匹配“a-z0-9(?:[。]a-z0-9)*”

我知道,
中的
需要图像,而不是路径

如何从
prod/Dockerfile
扩展
Dockerfile

Dockerfile不扩展Dockerfile而是图像,from
行的
不是“include”语句

因此,如果要“扩展”另一个Dockerfile,则需要将原始Dockerfile构建为映像,并扩展该映像

比如,

Dockerfile1:

FROM alpine
RUN echo "foo" > /bar
Dockerfile2:

FROM myimage
RUN echo "bar" > /baz
构建第一个Dockerfile(因为它被称为
Dockerfile1
,使用
-f
选项作为docker默认查找名为
Dockerfile
)的文件,并将其标记为
myimage

docker build -f Dockerfile1 -t myimage .

# Sending build context to Docker daemon 3.072 kB
# Step 1 : FROM alpine
#  ---> d7a513a663c1
# Step 2 : RUN echo "foo" > /bar
#  ---> Running in d3a3e5a18594
#  ---> a42129418da3
# Removing intermediate container d3a3e5a18594
# Successfully built a42129418da3
然后构建第二个Dockerfile,它扩展了刚刚构建的映像。我们将生成的图像标记为“myextendedimage”

要检查结果,请从图像运行容器,并验证两个文件(
/bar
/baz
)都在图像中

docker run -it --rm myextendedimage sh -c "ls -la ba*"

# -rw-r--r--    1 root     root             4 Apr 14 10:18 bar
# -rw-r--r--    1 root     root             4 Apr 14 10:19 baz

我建议阅读,它解释了如何使用图像和容器

我为此编写了简单的bash脚本。它的工作方式如下: 示例结构:

|
|_Dockerfile(base)
|_prod
  |_Dockerfile(extended)
Dockerfile(扩展):

运行脚本:

./script.sh prod
它将基本dockerfile与扩展和生成合并文件合并。 脚本:

#/bin/bash
fromLine=$(头-n 1$1/Dockerfile)
read-一个fromLineArray重新排序器
码头工人
docker构建-
看看
多阶段构建,它可以帮助您


    • 我使用的是条件句:

      Dockerfile 仅在本地版本上安装
      sudo

      建造
      #生产
      码头工人建造\
      -这不是我的形象\
      --构建arg应用程序\u环境='prod'\
      .
      #本地的
      码头工人建造\
      -这不是我的形象\
      .
      
      Docker Compose
      如果使用Docker 20.10+,则可以执行以下操作:

      # syntax = edrevo/dockerfile-plus
      
      INCLUDE+ ../Dockerfile
      
      RUN ...
      

      INCLUDE+
      指令由Dockerfile中的第一行导入。您可以在

      上阅读有关dockerfile plus的更多信息,谢谢,我知道
中的
需要图像,而不是
dockerfile
路径(正如我在问题中所说的)。我想知道如何扩展
Dockerfile
以提高环境配置的可维护性。但我现在有了我的答案:不,你不能:)哦,孩子,哈哈,在你的问题中完全错过了这一点;是的,这是不可能的(至少目前不可能),除非你使用一个外部工具/脚本来完成这项工作。是的,我开始考虑保持我的Dockerfiles不变,并用于我的不同环境。这取决于你需要改变什么;在大多数情况下,配置不应该是映像的一部分,而是在运行时传递的内容(通过环境变量、绑定装载配置文件或类似confd的内容)。在某些情况下,你可能想要建立一个不同的形象;还可以考虑使用构建时参数(
ARG
),这对配置docker环境很有用。要配置docker环境,请使用
docker compose
。它旨在构建多容器系统,但也提供了一种配置环境变量等的简单方法。如果需要为每个容器自定义配置文件,请使用卷来存储配置文件,或者在容器启动时添加bash脚本来配置您的环境。这是一个想法,我会给它一个tryDockerfile不应该扩展dockerfile而是图片@Auzias是关于精确扩展dockerfile的问题。我同意这是个坏主意,因为它使层缓存变得无用。我的脚本只是合并了两个DockerFile。我只是证明了这是可能的。缓存仍然应该被使用,因为它是基于文件的内容(将是相同的)哪个文件的内容?在我看来,多阶段构建太具体了,采取了错误的方式:它允许在大多数情况下需要附加指令时,将指令预先附加到Dockerfile。一般来说,这将更为通用,以允许类似于“来自xxx的<代码>作为我的\u容器”
,并进一步在“来自我的\u容器的<代码>文件中”
,以便可以单独处理指令。
./script.sh prod
#!/bin/bash
fromLine=$(head -n 1 $1/Dockerfile)
read -a fromLineArray <<< $fromLine
extPath=${fromLineArray[1]}
tail -n +2 "$1/Dockerfile" > strippedDocker
cat $1/$extPath strippedDocker > resDocker
rm strippedDocker
docker build - < resDocker
rm resDocker
FROM ubuntu:latest

ARG APP_ENVIRONMENT=local

RUN apt-get update && bash -c "set -ex ; \
  apt-get install -y $([ ${APP_ENVIRONMENT} = local ] \
    && echo 'curl sudo' \
    || echo 'curl' \
  )"

CMD bash -c "set -ex ; \
  [ ${APP_ENVIRONMENT} = local ] \
    && { app debug ; exit $? ; } \
    || { app start ; exit $? ; } \
  "
version: "3.7"

services:

  app:
    build:
      context: .
      args:
        APP_ENVIRONMENT: "${APP_ENVIRONMENT:-local}"
# syntax = edrevo/dockerfile-plus

INCLUDE+ ../Dockerfile

RUN ...