如何使用父映像中的Linux依赖项和环境变量创建Docker多阶段构建?

时间:2018-08-19 14:25:27

标签: docker dockerfile docker-multi-stage-build

我有一个应用程序包,如.bin,它在rhel7-init基础映像上运行。以下是带有父映像和子映像的Dockerfile。

FROM registry.access.redhat.com/rhel7-init:7.3 as base
COPY yum.repos.d/ /etc/yum.repos.d/
RUN yum -y install sudo systemd
RUN yum install https://download.postgresql.org/pub/repos/yum/9.4/redhat/rhel-7-x86_64/pgdg-redhat93-9.4-3.noarch.rpm -y && \
 yum install -y postgresql94
RUN export key=value && \
    installer.bin &> /root/install.log

FROM registry.access.redhat.com/rhel7-init:7.3
COPY --from=base /opt/app/ /opt/app
COPY start_app /root/
RUN chmod +x /root/start_app
ENTRYPOINT [ "/root/start_app" ]

它具有一个以ENTRYPOINT形式给出的启动脚本,该脚本在运行容器时会在运行时进行一些配置。我将安装的目录位置从父映像复制到了新映像。

现在,当我启动容器时,它会显示对父映像中安装的sudo软件包的依赖性。

如何在不增加大小的情况下将已安装的父基础映像的软件包继续到新的基础映像?

我是否还可以保留父基础映像中使用的安装程序中存在的所有env变量?

2 个答案:

答案 0 :(得分:1)

您可以通过写入文件并将其复制到下一个图像来转发父图像的环境变量等。然后在您的入口点以某种方式读取它并导出变量等。但是我会说这有点奇怪。

但是在您的情况下,似乎对变量和包有相当多的依赖性,所以也许根本不进行多阶段操作就更容易了?

答案 1 :(得分:0)

这是一个古老的问题,但我将尝试解决这两个问题。

从父阶段重用Linux依赖项

这应该可以通过定义一个公共基础阶段来实现,在该基础阶段中安装依赖项。示例:

FROM ubuntu as base

RUN apt-get update \
  && DEBIAN_FRONTEND=noninteractive apt-get -qq -y install postgresql

FROM base as stage0
RUN which psql
# psql still here, should print /usr/bin/psql

FROM base as stage1
RUN which psql 
# psql still here, should print /usr/bin/psql

从父阶段重用环境变量

尽管如此,这还是比较棘手的。一些选项包括:

  1. 使用环境变量创建文件,然后使用COPY --from从另一个阶段复制文件
  2. 在基础阶段创建带有环境变量的文件,然后在所有阶段重复使用该文件。
  3. 按照建议的here使用全局 ARG

1)应该是最清晰的,因为与问题中发布的Dockerfile相比,没有太多新内容。这只是一个按需创建并复制到以后阶段的额外文件。

2)也应该很简单,因为它与针对Linux依赖项显示的解决方案非常相似。在基础阶段创建的文件应该在所有FROM base阶段都可用。

3)在上述链接中有很好的解释,但是出于完整性考虑,应该是这样的(更多信息请参考link

ARG my_key=my_value

FROM ubuntu as stage1
ARG my_key
RUN echo $my_key
# should print my_value

FROM ubuntu as stage2
ARG my_key
RUN echo $my_key
# should print my_value

如果您需要将环境变量公开给正在运行的容器,则可以使用ENV并向其提供ARG值。

ARG my_key
ENV key=$my_key
CMD ["sh", "-c", "echo $key"]
# should print my_value