Before filing a bug I would like to ask someone to confirm the weird docker build
behavior I have recently faced with.
Consider we have a simple Dockerfile where we're trying to copy some files into home directory of a non-root user:
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"]
That's what I get when I am trying to build this image:
... 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
Seems like $HOME
is empty. But why? Putting the absolute path to home dir instead of $HOME
is not very convenient.
COPY and ADD are both Dockerfile instructions that serve a similar purpose. They let you copy files from a specific location into a Docker image. COPY takes in a source and destination. It only lets you copy in a local or directory from your host (the machine-building the Docker image) into the Docker image itself.
Docker ADD Command Since the launch of the Docker platform, the ADD instruction has been part of its list of commands. The command copies files/directories to a file system of the specified container. It includes the source you want to copy ( <src> ) followed by the destination where you want to store it ( <dest> ).
There can only be one CMD instruction in a Dockerfile. If you list more than one CMD then only the last CMD will take effect. If CMD is used to provide default arguments for the ENTRYPOINT instruction, both the CMD and ENTRYPOINT instructions should be specified with the JSON array format.
Sometimes you see COPY or ADD being used in a Dockerfile, but 99% of the time you should be using COPY. Here’s why? COPY and ADD are both Dockerfile instructions that serve similar purposes. They let you copy files from a specific location into a Docker image. COPY takes in a src and destination.
Some frequently used instructions in a Dockerfile are RUN, ADD, CMD, ENTRYPOINT, and COPY. If the WORKDIR is not manually created, it gets created automatically during the processing of the instructions.
Docker – WORKDIR Instruction Last Updated : 28 Oct, 2020 WORKDIR instruction is used to set the working directory for all the subsequent Dockerfile instructions. Some frequently used instructions in a Dockerfile are RUN, ADD, CMD, ENTRYPOINT, and COPY.
I don't think this is a bug. $HOME is normally set by the shell I believe and you don't have a shell inside a Dockerfile. You can always ENV HOME /home/aptly and then the above would work. When you use the USER directive, it affects the userid used to start new commands inside the container. So, for example, if you do this:
Here's your problem:
When you use the USER
directive, it affects the userid used to start new commands inside the container. So, for example, if you do this:
FROM ubuntu:utopic RUN useradd -m aptly USER aptly RUN echo $HOME
You get this:
Step 4 : RUN echo $HOME ---> Running in a5111bedf057 /home/aptly
Because the RUN
commands starts a new shell inside a container, which is modified by the preceding USER
directive.
When you use the COPY
directive, you are not starting a process inside the container, and Docker has no way of knowing what (if any) environment variables would be exposed by a shell.
Your best bet is to either set ENV HOME /home/aptly
in your Dockerfile, which will work, or stage your files into a temporary location and then:
RUN cp /skeleton/myfile $HOME/myfile
Also, remember that when you COPY
files in they will be owned by root
; you will need to explicitly chown
them to the appropriate user.
Per the Docker docs, USER
only applies to RUN
, CMD
and 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With