我想在应用程序的官方 docker 基础镜像中包含并启用一些自定义插件。
这是目录结构的样子;
.
+-- Dockerfile
+-- plugins
| +-- plugin_1
| +-- plugin_2
| +-- plugin_3
| +-- ...
| +-- plugin_n
如果我需要包含插件 plugin_1、plugin_3、plugin_7 和 plugin_8,Dockerfile 如下所示;
FROM myapp_officialimage
COPY plugins/plugin_1/* /usr/lib/myapp/plugins/
RUN myapp-plugins.sh enable plugin_1
COPY plugins/plugin_3/* /usr/lib/myapp/plugins/
RUN myapp-plugins.sh enable plugin_3
COPY plugins/plugin_7/* /usr/lib/myapp/plugins/
RUN myapp-plugins.sh enable plugin_7
COPY plugins/plugin_8/* /usr/lib/myapp/plugins/
RUN myapp-plugins.sh enable plugin_8
CMD ["myapp-start.sh"]
问题是 , 是否可以迭代/循环列表以消除上面的样板?
例如,像下面这样的 Dockerfile 会更干净,更易于维护;
FROM myapp_officialimage
ENV CUSTOM_PLUGIN_LIST="plugin_1 plugin_3 plugin_7 plugin_8"
for plugin in $CUSTOM_PLUGIN_LIST; \
do \
COPY plugins/$plugin/* /usr/lib/myapp/plugins/ \
RUN myapp-plugins.sh enable $plugin \
done
CMD ["myapp-start.sh"]
最佳答案
在您的情况下,我会准备一个新的插件文件夹以及安装它们的(可能生成或手工制作的)脚本。将真正的插件文件夹添加到 .dockerignore
.然后复制新文件夹并运行安装脚本。这也减少了您在构建开始之前上传到 docker 的上下文的大小。无论如何,您都在手动选择依赖项,因此事先进行工作(在您 build
之前)应该可以正常工作。
在构建系统中,您应该执行以下操作:
collect_plugins.sh # Creates the new plugin folder and install script
docker build <params>
然后这两层可以是:
COPY plugins_selected/ /usr/lib/myapp/plugins/
RUN /usr/lib/myapp/plugins/install.sh
如果您准备好要发送到 docker 的上下文,它将生成
Dockerfile
更简单(一件好事)。我们只是在解决之前的问题build
.通常依赖项是使用包管理器通过网络获取的,或者只是通过 http(s) 下载它们。像您一样将它们复制到构建上下文中不一定是错误的,但它会变得更加尴尬。
我们来看看docker如何处理
Dockerfile
(稍微简化)。当您
build
, docker 会将上下文中的所有文件上传到 docker 引擎(除了 .dockerignore
中提到的路径)并开始处理 Dockerfile
.目的是生成将代表最终图像的文件系统层。当您进行类似
RUN
的操作时, docker 实际上会启动一个容器来执行命令,然后将生成的层添加到图像中。在生产中实际运行的唯一内容是您在 CMD
中指定的内容。和或 ENTRYPOINT
末Dockerfile
.尝试创建尽可能少的图层。
dockerfile best practices guide covers the basics .
关于docker - 在 Dockerfile 中循环/迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45208936/