Dockerfiles中的命令行模板
我正在尝试构建一个Dockerfile,用于为多个基础映像构建我的项目(例如,用于多个体系结构的Ubuntu 17.10)
我想要写一些类似的东西
FROM {{ ARCH }}/ubuntu:17.10 ...
并有建设时间解决ubuntu:17.10
或ppc64le/ubuntu:17.10
。 有没有办法做到这一点?
此外,一个单独的解决方案可能是有两个码头文件,但不知何故将文件的公共部分包括在两个码头文件中。
您可以使用构建参数并使用docker build --build-arg foo=bar
来构建映像。
我的第一个想法是编写一个模板脚本,将您的变量值替换为当时需要的值。 这个值可以在被调用或从环境变量中获取时传递到脚本中。
我特别想使用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()
只是清理值,以确保没有奇怪的空格。 所有这些都被压缩到字典理解中,其中变量key
是环境变量的名称,在这种情况下是模板变量,并且它映射了这个变量的值
args = {key: value.strip() for (key, value) in os.environ.items()}
最后我们有这条线。 template.substitute()
接受一个映射对象,并试图用它的值替换所有的键。 **args
扩展字典。
f.write(template.substitute(**args))