我正在尝试构建一个Dockerfile,为多个基础映像构建我的项目(例如,Ubuntu 17.10用于多种架构)
我希望能够写出类似
的内容FROM {{ ARCH }}/ubuntu:17.10
...
让它在构建时解析为ubuntu:17.10
或ppc64le/ubuntu:17.10
。有没有办法做到这一点?
另外一个单独的解决方案可能是有两个docker文件,但不知何故将文件的公共部分包含在docker文件中。
答案 0 :(得分:1)
您可以使用build argument并使用docker build --build-arg foo=bar
来构建图片。
答案 1 :(得分:1)
我的第一个想法是编写一个模板脚本,将您的变量值替换为当时所需的值。当从环境变量调用或获取时,可以将此值传递给脚本。
我正在考虑使用python的string.Template模块并使用分隔符$
而不是{
,因为{
可能在您的Dockerfile中使用。 $
是string.Template
的默认分隔符。另外,我会用不同的扩展名来命名这个模板文件,因为Docker将无法使用里面的模板化变量来构建它。
假设你的Dockerfile.template
看起来像这样:
FROM $ARCH/ubuntu:17.10
...
然后您可以在会话中设置环境变量ARCH=ppc64le
并运行如下的简短脚本:
import os
import string
with open('Dockerfile.template', 'r') as f:
template = string.Template(f.read())
with open('Dockerfile', 'w') as f:
args = {key: value.strip() for (key, value) in os.environ.items()}
f.write(template.substitute(**args))
这两行读取您的模板文件并创建一个string.Template
对象。 string.Template
的默认分隔符为$
,因此它符合您的模板。
with open('Dockerfile.template', 'r') as f:
template = string.Template(f.read())
这只是让我们创建并写入您的实际Dockerfile
with open('Dockerfile', 'r') as f:
这条奇特的线条是环境变量发挥作用的地方。 os.environ是os的环境变量的映射对象。 os.environ.items()
将每对解包为其各自的键:值元组。 value.strip()
只是清理价值,以确保没有奇怪的whitespacing。所有这些都包含在字典理解中,其中变量key
是环境变量的名称,在本例中是模板化变量,它映射了此变量的值
args = {key: value.strip() for (key, value) in os.environ.items()}
最后我们有这条线。 template.substitute()
接受映射对象并尝试用其值替换所有键。 **args
扩展字典。
f.write(template.substitute(**args))
答案 2 :(得分:0)
官方docker库操作系统的现代标签现在倾向于多体系结构。只需根据体系结构上的FROM ubuntu:17.10
构建就可以获取正确的图像。
例如:
docker run ubuntu:17.10 uname -a
Unable to find image 'ubuntu:17.10' locally
17.10: Pulling from library/ubuntu
c3cef7a7aa54: Pull complete
8cbf0d1d8127: Pull complete
1b5d7d7519b4: Pull complete
855c347561ac: Pull complete
ec1530a7444c: Pull complete
Digest: sha256:3b811ac794645dfaa47408f4333ac6e433858ff16908965c68f63d5d315acf94
Status: Downloaded newer image for ubuntu:17.10
Linux 93a4440468e9 4.4.0-116-generic #140-Ubuntu SMP Mon Feb 12 21:22:24 UTC 2018 ppc64le ppc64le ppc64le GNU/Linux
答案 3 :(得分:0)
TL; DR-不幸的是,Docker不支持此功能。这意味着,您需要自己做这些事情。
有一些专门为此任务编写的库:
dockerfile-template 允许您在Dockerfile
中编写类似的内容:
FROM %%BASE%%:%%TAG%%
...
然后使用给定的值处理此docker-template文件,以生成最终的Dockerfile。但是,它实际上并不支持多行替换,而是使用Javascript编写的(原文如此!)。
另一种解决方案是编写自己的简单模板程序,如@Ricky Barillas建议(如果需要更多功能,也可以使用jinja
之类的现有模板引擎)。
请注意所有此类自制解决方案的缺点是您的Dockertemplate
文件将超出Dockerfile
的语法,因此您将无法再使用Dockerfile linters / validators (仅在最终输出中)。此外,就构建映像而言,它们将不再那么“便携”,因为它不仅需要基础Docker,还需要模板脚本。