我想使用一些控制台输出作为我的基本docker映像的名称。
具体地说,我有一系列依赖的docker构建文件,因此我试图使这一过程自动化。因此,例如,在以下情况下,一个映像derived1
的Dockerfile取决于基础映像base_image_name
:
base_image_name/
Dockerfile
derived1/
Dockerfile
derived2/
Dockerfile
构建基本映像时,它使用${PWD##*/}
从当前文件夹中获取其名称。在这种情况下,基础映像的文件夹称为base_image_name
,因此基础映像称为company:base_image_name
。
然后,在生成派生图像时,它们应该只能够通过向上移动目录并查看该目录名称来找出基本图像的名称。因此,例如,在构建company:derived1
映像时,它应该查找一个目录,看到它称为base_image_name
,并从中推断出它应该使用基础映像company:base_image_name
。
我想将此结构深入几层,所以我想使其自动化。为此,我尝试了几种语法置换
FROM company:$(cd $PWD/../; echo ${PWD##*/})
但我似乎无法正确解决。要了解命令$(cd $PWD/../; echo ${PWD##*/})
的作用,只需在终端中键入该命令即可。
echo $(cd $PWD/../; echo ${PWD##*/})
仅返回上一级目录的名称。但是,当我尝试在Dockerfile中使用它时,出现错误
Error response from daemon: Dockerfile parse error line 1: FROM requires either one or three arguments
有人可以给我提供正确的语法吗?
编辑:
我还尝试使用build-arg
构建派生图像,但这似乎也不起作用:
build.sh:
BASE=$(cd $PWD/../../; echo ${PWD##*/})
echo "BASE="$BASE
docker build --build-arg BASE=${BASE} -t company:"${PWD##*/}" .
Dockerfile看起来像
FROM company:$BASE
具体来说,这会产生构建错误:
BASE=base_image_name
Sending build context to Docker daemon 5.12kB
Step 1/3 : FROM company:$BASE
invalid reference format
因此,似乎docker无法正确解释该arg。
答案 0 :(得分:2)
除某些very limited environment variable expansion外,Dockerfile通常不支持shell语法。
它们确实支持可以从命令行传递的ARG
和an ARG
can be used to define the image FROM
。因此,您可以使用以下命令启动Dockerfile
ARG tag
FROM company:${tag:-latest}
然后使用
构建图像docker build --build-arg tag=$(cd $PWD/../; echo ${PWD##*/}) .
(涉及的内容足以使您将其写入Shell脚本)。
在非常低的级别上,还应该记住docker build
的工作方式是创建当前目录的tar文件,通过HTTP连接将其发送到Docker守护程序,然后在其中运行构建。一旦该过程发生,主机目录名称的任何概念都会丢失。换句话说,即使语法可行,docker build
也没有能力知道Dockerfile位于哪个主机目录中。
答案 1 :(得分:2)
啊哈。找到了。
正如Jonathon指出的那样,似乎您无法轻松地将环境中的内容拖入构建系统。看来您必须使用Docker build-arg
。
解决方案是在终端中评估变量并将其作为build-arg
传递:
build.sh:
BASE=$(cd $PWD/../; echo ${PWD##*/})
echo "BASE="$BASE
docker build --build-arg BASE=${BASE} -t company:"${PWD##*/}" .
然后在派生映像的Dockerfile中:
ARG BASE
FROM company:$BASE
答案 2 :(得分:1)
您正在尝试在bash不会使用的东西中使用bash 命令替换。
[Dockerfile参考[(https://docs.docker.com/engine/reference/builder/)指示FROM
指令支持环境变量替换 。
您需要只在FROM
中使用在Dockerfile外部计算的环境变量,然后将其传递给docker build
。