我有一个应用程序包作为.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 变量?
您可以通过写入文件并将其复制到下一个图像来转发父映像中的环境变量等。然后在您的入口点中以某种方式读取它并导出变量等。但我想说这是有点异国情调的设计。
但是在您的情况下,似乎对变量和包有相当多的依赖性,所以也许根本不使用多阶段更容易?
这是一个老问题,但我会尝试解决这两个问题。
重用父阶段的 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
重用父阶段的环境变量
不过,这有点棘手。一些选项包括:
- 使用环境变量创建文件并使用
COPY --from
从另一个阶段复制文件 - 在基阶段创建一个包含环境变量的文件,并在所有阶段中重复使用该文件。
- 按照此处的建议使用全局
ARG
1(应该是最清楚的,因为与问题中发布的Dockerfile相比,没有什么新东西。它只是一个按需创建并复制到稍后阶段的额外文件。
2(也应该很简单,因为它与Linux依赖项显示的解决方案非常相似。在基本阶段中创建的文件应在所有FROM base
阶段中可用。
3(在提到的链接中有很好的解释,但为了完整起见,应该是这样的(详情请参考链接(:
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