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 docs,USER
仅适用于 RUN
、CMD
和 ENTRYPOINT
。
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.
在提交错误之前,我想请某人确认我最近遇到的奇怪 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 docs,USER
仅适用于 RUN
、CMD
和 ENTRYPOINT
。
The
USER
instruction sets the user name (or UID) and optionally the user group (or GID) to use when running the image and for anyRUN
,CMD
andENTRYPOINT
instructions that follow it in the Dockerfile.