dockerdocker-builddocker-copy

ADD and COPY with existing relative path fails when building a docker image


Env: Windows 10, Docker Desktop (Docker Engine v20.10.6)

Build of a Docker image fails on command COPY (and ADD) when its first argument is a relative path starting with ../../. Error message shows that any path like ../../a/b/c is replaced with /a/b/c and hence cannot be found on the host.

Please, help me to find a way to workaround the problem. In multiple articles and forums I see that Docker can handle relative path properly, but cannot figure out what is wrong in this case.

Project folder structure

project_root
  first
    container
       Dockerfile
  second
    target
       artifact.file

Dockerfile

FROM whatever

RUN addgroup -S apprunner && adduser -S apprunner -G apprunner

COPY ../../second/target/artifact.file /home/apprunner/app.file

USER apprunner:apprunner
WORKDIR /home/apprunner
EXPOSE 8080

ENTRYPOINT blabla

Executing command from project_root

cd first/container
docker build -q -t my_image_name .

get this error

...

#7 [4/5] COPY ../../second/target/artifact.file /home/apprunner/app.file
#7 sha256:fefde24bc79e3e0b7a3ba0bf6754187537780b9c30fa81537cb5aea93ef9331c
#7 ERROR: "/second/target/artifact.file" not found: not found
------
 > [4/5] COPY ../../second/target/artifact.file /home/apprunner/app.file:
------
failed to compute cache key: "/second/target/artifact.file" not found: not found

Cannot find a reason why the relative path is replaced with an absolute path.


Solution

  • The COPY and ADD instructions are relative to the context path passed as last parameter to the command docker build.

    I solved that issue several times by:

    1. copying the out of context file into the context path;
    2. copying to the container image by referencing it from context path;
    3. removing the (temporary) copied file.

    So you will have:

    cd first/container
    cp ../../second/target/artifact.file artifact.file
    docker build -q -t my_image_name .
    rm artifact.file
    

    and

    FROM whatever
    
    RUN addgroup -S apprunner && adduser -S apprunner -G apprunner
    
    COPY artifact.file /home/apprunner/app.file
    
    USER apprunner:apprunner
    WORKDIR /home/apprunner
    EXPOSE 8080
    
    ENTRYPOINT blabla