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

DockerDockerfile

Docker Problem Overview


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.

Docker Solutions


Solution 1 - Docker

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.

Solution 2 - Docker

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 any RUN, CMD and ENTRYPOINT instructions that follow it in the Dockerfile.

Solution 3 - Docker

you need to use the absolute path.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVitaly IsaevView Question on Stackoverflow
Solution 1 - DockerlarsksView Answer on Stackoverflow
Solution 2 - Dockergo2nullView Answer on Stackoverflow
Solution 3 - DockerengineerView Answer on Stackoverflow