【问题标题】:Dockerfile: $HOME is not working with ADD/COPY instructionsDockerfile:$HOME 不适用于 ADD/COPY 指令
【发布时间】:2015-05-12 00:53:38
【问题描述】:

在提交错误之前,我想请人确认我最近遇到的奇怪的docker build 行为。

假设我们有一个简单的 Dockerfile,我们试图将一些文件复制到非 root 用户的主目录中:

FROM ubuntu:utopic

ENV DEBIAN_FRONTEND=noninteractive

RUN sed -i.bak 's/http:\/\/archive.ubuntu.com\/ubuntu\//mirror:\/\/mirrors.ubuntu.com\/mirrors.txt\//g' /etc/apt/sources.list
RUN echo "deb http://repo.aptly.info/ squeeze main" >> /etc/apt/sources.list.d/_aptly.list
RUN apt-key adv --keyserver keys.gnupg.net --recv-keys e083a3782a194991
RUN apt-get update
RUN apt-get install -y aptly

RUN useradd -m aptly
RUN echo aptly:aptly | chpasswd

USER aptly
COPY ./.aptly.conf $HOME/.aptly.conf

COPY ./public.key $HOME/public.key
COPY ./signing.key $HOME/signing.key
RUN gpg --import $HOME/public.key $HOME/signing.key

RUN aptly repo create -comment='MAILPAAS components' -distribution=utopic -component=main mailpaas
CMD ["/usr/bin/aptly", "api", "serve"]

这就是我尝试构建此图像时得到的结果:

    ...    
    Step 10 : USER aptly
     ---> Running in 8639f826420b
     ---> 3242919b2976
    Removing intermediate container 8639f826420b
    Step 11 : COPY ./.aptly.conf $HOME/.aptly.conf
     ---> bbda6e5b92df
    Removing intermediate container 1313b12ca6c6
    Step 12 : COPY ./public.key $HOME/public.key
     ---> 9a701a78d10d
    Removing intermediate container 3a6e40b8593a
    Step 13 : COPY ./signing.key $HOME/signing.key
     ---> 3d4eb847abe8
    Removing intermediate container 5ed8cf52b810
    Step 14 : RUN gpg --import $HOME/public.key $HOME/signing.key
     ---> Running in 6e481ec97f74
    gpg: directory `/home/aptly/.gnupg' created
    gpg: new configuration file `/home/aptly/.gnupg/gpg.conf' created
    gpg: WARNING: options in `/home/aptly/.gnupg/gpg.conf' are not yet active during this run
    gpg: keyring `/home/aptly/.gnupg/secring.gpg' created
    gpg: keyring `/home/aptly/.gnupg/pubring.gpg' created
    gpg: can't open `/home/aptly/public.key': No such file or directory
    gpg: can't open `/home/aptly/signing.key': No such file or directory
    gpg: Total number processed: 0

好像$HOME 是空的。但为什么?将绝对路径放到主目录而不是$HOME 不是很方便。

【问题讨论】:

  • 我不认为这是一个错误。我相信 $HOME 通常由 shell 设置,而 Dockerfile 中没有 shell。你总是可以ENV HOME /home/aptly 然后上面的就可以了。

标签: docker dockerfile


【解决方案1】:

这是你的问题:

当您使用 USER 指令时,它会影响用于在容器内启动新命令的用户 ID。因此,例如,如果您这样做:

FROM ubuntu:utopic
RUN useradd -m aptly
USER aptly
RUN echo $HOME

你明白了:

Step 4 : RUN echo $HOME
 ---> Running in a5111bedf057
/home/aptly

因为RUN 命令在容器内启动了一个新的shell,它由前面的USER 指令修改。

当您使用COPY 指令时,您并没有在容器内启动进程,并且 Docker 无法知道 shell 会公开哪些(如果有)环境变量。

您最好的选择是在您的 Dockerfile 中设置 ENV HOME /home/aptly,这将起作用,或者将您的文件暂存到一个临时位置,然后:

RUN cp /skeleton/myfile $HOME/myfile

另外,请记住,当您在其中COPY 文件时,它们将归root 所有;您需要将它们明确地chown 发送给相应的用户。

【讨论】:

  • 感谢您的发现! ENV 的单独重新定义救了我的命!
【解决方案2】:

根据Docker docsUSER 仅适用于RUNCMDENTRYPOINT

USER 指令设置运行映像时使用的用户名(或 UID)和可选的用户组(或 GID),以及后面的任何 RUNCMDENTRYPOINT 指令Dockerfile。

【讨论】:

    【解决方案3】:

    你需要使用绝对路径。

    【讨论】:

    • 如果使用 docker-compose 构建,即使绝对路径也可能与 docker-compose.yml 中的上下文相关
    • 这实际上是我必须做的。
    猜你喜欢
    • 2019-02-16
    • 2019-12-10
    • 1970-01-01
    • 1970-01-01
    • 2017-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多