17

I have a github actions workflow to build a docker image:

name: Backend-Demo Docker Image CI on: push: branches: [ master ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Login to Azure Container Registry run: echo ${{ secrets.REGISTRY_PASSWORD }} | docker login ${{ secrets.LOGIN_SERVER_URL }} -u ${{ secrets.REGISTRY_USERNAME }} --password-stdin - name: Get the version id: vars run: echo ::set-output name=tag::$(echo ${GITHUB_REF:10}) - name: Build the tagged Docker image run: docker build . --file backend/Dockerfile --tag backend-demo/spring-boot:v1.0 

The Dockerfile is:

FROM openjdk:14-alpine MAINTAINER example.com RUN mkdir -p /opt/demo-0.0.1/lib # Setting application source code working directory WORKDIR /opt/demo-0.0.1/ COPY target/demo-0.0.1-SNAPSHOT.jar /opt/demo-0.0.1/lib/demo-0.0.1-SNAPSHOT.jar # ADD target/demo-0.0.1-SNAPSHOT.jar /opt/demo-0.0.1/lib/ RUN sh -c 'touch demo-0.0.1-SNAPSHOT.jar' ENTRYPOINT ["java"] CMD ["-jar", "/opt/demo-0.0.1/lib/demo-0.0.1-SNAPSHOT.jar"] 

But when I execute this workflow I got this error at the COPY instruction:

Step 5/8 : COPY target/demo-0.0.1-SNAPSHOT.jar /opt/demo-0.0.1/lib/demo-0.0.1-SNAPSHOT.jar COPY failed: stat /var/lib/docker/tmp/docker-builder851513197/target/demo-0.0.1-SNAPSHOT.jar: no such file or directory ##[error]Process completed with exit code 1. 

I have been checking and it looks a typical error when the file we have the Dockerfile in a different directory like my instruction:

docker build . --file backend/Dockerfile --tag backend-demo/spring-boot:v1.0

I also don't have .dockerignore file and my Dockerfile is called Dockerfile precisely.

The target/demo-0.0.1-SNAPSHOT.jar file I am trying to copy is present in my github repository Not sure what could be happening with the context, but probably this answer could be a good hint?

3
  • is Dockerfile in same level as target/ directory in your file tree? you can also try with relative path like COPY ./target/demo-0.1.1-SNAPSHOT.jar ... Commented Aug 17, 2020 at 18:10
  • @oli Yes, Dockerfile is at the same level as target directory. I also tried with relative PATH at COPY without success. Commented Aug 17, 2020 at 18:17
  • 1
    As a debugging step you can add RUN ls -l above COPY instruction to see the contents of directory inside image. Commented Aug 17, 2020 at 19:10

3 Answers 3

22

When you run

docker build . --file backend/Dockerfile ... 

The path argument . becomes the context directory. (Docker actually sends itself a copy of this directory tree, which is where the /var/lib/docker/tmp/... path comes from.) The source arguments of COPY and ADD instructions are relative to the context directory, not relative to the Dockerfile.

If your source tree looks like

. +-- backend | \-- Dockerfile \-- target \-- demo-0.0.1-SNAPSHOT.jar 

that matches the Dockerfile you show. But if instead you have

. +-- backend +-- Dockerfile \-- target \-- demo-0.0.1-SNAPSHOT.jar 

you'll get the error you see.

If you don't need to refer to anything outside of the context directory, you can just change what directory you're passing to docker build

COPY target/demo-0.0.1-SNAPSHOT.jar /opt/demo-0.0.1/lib/demo-0.0.1-SNAPSHOT.jar 
docker build backend ... 

Or, if you do have other content you need to copy in, you need to change the COPY paths to be relative to the topmost directory.

COPY backend/target/demo-0.0.1-SNAPSHOT.jar /opt/demo-0.0.1/lib/demo-0.0.1-SNAPSHOT.jar COPY common/config/demo.yml /opt/demo-0.0.1/etc/demo.yml 
docker build . -f backend/Dockerfile ... 
Sign up to request clarification or add additional context in comments.

Comments

1

WORKDIR just tells you from where the other commands will be executed.An important point is WORKDIR works w.r.t docker directory,not to local/git directory.As per your example, WORDIR does not take context to /opt/demo-0.0.1/ , but just creates an empty directory as /opt/demo-0.0.1/ inside the docker. In order to make dockerfile work, you should give full path in COPY command as COPY /opt/demo-0.0.1/target/demo-0.0.1-SNAPSHOT.jar /opt/demo-0.0.1/lib/demo-0.0.1-SNAPSHOT.jar.Make sure Dockerfile is at the same level as /opt directory.

4 Comments

Got it about WORKDIR I think the empty directory /opt/demo-0.0.1/ is created. I don't understand about giving full path at COPY command because is not supposed that the src path at COPY is my file system? I mean I don't have /opt/demo-0-0.1 path in my filesystem. Could you elaborate a little bit more about your answer please?
When you run COPY <src> <dest>, src is w.r.t git repo, so here the context will always be the directory where dockerfile is present, and this context does not change by WORKDIR. So, src should should always contain the full path of the file which we want to copy. And <dest> is set w.r.t to docker container, whose default context is root but can be changed with WORKDIR. New directory will be created if WORKDIR does not exist as above. So <dest> as /opt/demo-0.0.1/lib/demo-0.0.1-SNAPSHOT.jar is equal to WORKDIR /opt/demo-0.0.1/ and COPY src lib/demo-0.0.1-SNAPSHOT.jar
Could you check this gist, please? it is my Dockerfile now, but not sure if the WORKDIR instruction should be before or after COPY
Since you're using an absolute path as the destination for the COPY, it doesn't matter what you set the WORKDIR to.
0

In my case I was trying to build the image without running maven install before, my Dockerfile was like:

FROM amazoncorretto:11 COPY ./target/*.jar /application.jar CMD ["application.jar"] 

And it was failing on the second step (COPY...) because target did not exist, because I did not build the jar before with for example maven install command, so first make sure target exist and contains the latest jar

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.