Dockerfile:$HOME 无法使用 ADD/COPY 指令

Dockerfile: $HOME is not working with ADD/COPY instructions

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

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

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 不是很方便。

这是你的问题:

当您使用 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.

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

RUN cp /skeleton/myfile $HOME/myfile

此外,请记住,当您 COPY 中的文件时,它们将归 root 所有;您需要将它们明确地 chown 给适当的用户。

您需要使用绝对路径。

根据 Docker docsUSER 仅适用于 RUNCMDENTRYPOINT

The USER instruction sets the user name (or UID) and optionally the user group (or GID) to use when running the image and for any RUN, CMD and ENTRYPOINT instructions that follow it in the Dockerfile.