Bato-Bair Tsyrenov
Bato-Bair Tsyrenov

Reputation: 1194

Docker COPY no such file or directory

Building docker image fails on copy task. No such file or directory. I am using the hello world example from spring

Building from openjdk:8-jdk-alpine

Run echo ${PWD} prints / Run ls prints a set of normal directories (/usr /var etc) but no project files are present

Why is docker not using the WORKING directory?

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=target/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]

Files to copy are prepared by gradle and i can confirm that they are present:

task unpack(type: Copy) {
    dependsOn bootJar
    from(zipTree(tasks.bootJar.outputs.files.singleFile))
    into("build/dependency")
}

I am running

docker build .

docker gradle task

docker {
    name "${project.group}/${bootJar.baseName}"
    copySpec.from(tasks.unpack.outputs).into("dependency")
    buildArgs(['DEPENDENCY': "dependency"])
}

Upvotes: 2

Views: 7329

Answers (4)

I had the same problem. for solving this:

  1. before execute your

docker build

command, just run this to commands in root of your project (where Dockerfile and target exist):

mkdir target/dependency
(cd target/dependency; jar -xf ../*.jar)

or, 2. just add those two command in your .gitlab-ci.yml file (if using gitlab CI/CD pipeline):

docker-build:
  stage: package
  tags:
    - vasci2_shell_runner
  script:
    - mkdir target/dependency
    - (cd target/dependency; jar -xf ../*.jar)
    - docker build -t nexus.css.ir:30005/vas/harim/apc:lastest .

Upvotes: 1

Bjarte Brandt
Bjarte Brandt

Reputation: 4461

Problem

docker build -t springio/gs-spring-boot-docker .
Sending build context to Docker daemon  16.78MB
Step 1/8 : FROM openjdk:8-jdk-alpine
 ---> a3562aa0b991
Step 2/8 : RUN addgroup -S spring && adduser -S spring -G spring
 ---> Using cache
 ---> 5b122a1db135
Step 3/8 : USER spring:spring
 ---> Using cache
 ---> 3bdba2028e42
Step 4/8 : ARG DEPENDENCY=target/dependency
 ---> Using cache
 ---> 616945cc41ed
Step 5/8 : COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY failed: file not found in build context or excluded by .dockerignore: stat target/dependency/BOOT-INF/lib: file does not exist

Fix

mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)

The below folder layout will be created. This is done to explain the layering options for your docker image. It is all explained in Example 3. Dockerfile

   $pwd
   /java-training/workspace/gs-spring-boot-docker/complete
   $tree -L 3 target/dependency
    target/dependency
    ├── BOOT-INF
    │   ├── classes
    │   │   ├── application.yml
    │   │   └── hello
    │   ├── classpath.idx
    │   └── lib
    │       ├── jackson-annotations-2.11.0.jar
    │       ├── jackson-core-2.11.0.jar
    │       ├── jackson-databind-2.11.0.jar
    │       ├── jackson-datatype-jdk8-2.11.0.jar
    │       ├── jackson-datatype-jsr310-2.11.0.jar
    │       ├── jackson-module-parameter-names-2.11.0.jar
    │       ├── jakarta.annotation-api-1.3.5.jar
    │       ├── jakarta.el-3.0.3.jar
    │       ├── jul-to-slf4j-1.7.30.jar
    │       ├── log4j-api-2.13.2.jar
    │       ├── log4j-to-slf4j-2.13.2.jar
    │       ├── logback-classic-1.2.3.jar
    │       ├── logback-core-1.2.3.jar
    │       ├── slf4j-api-1.7.30.jar
    │       ├── snakeyaml-1.26.jar
    │       ├── spring-aop-5.2.6.RELEASE.jar
    │       ├── spring-beans-5.2.6.RELEASE.jar
    │       ├── spring-boot-2.3.0.RELEASE.jar
    │       ├── spring-boot-autoconfigure-2.3.0.RELEASE.jar
    │       ├── spring-boot-starter-2.3.0.RELEASE.jar
    │       ├── spring-boot-starter-json-2.3.0.RELEASE.jar
    │       ├── spring-boot-starter-logging-2.3.0.RELEASE.jar
    │       ├── spring-boot-starter-tomcat-2.3.0.RELEASE.jar
    │       ├── spring-boot-starter-web-2.3.0.RELEASE.jar
    │       ├── spring-context-5.2.6.RELEASE.jar
    │       ├── spring-core-5.2.6.RELEASE.jar
    │       ├── spring-expression-5.2.6.RELEASE.jar
    │       ├── spring-jcl-5.2.6.RELEASE.jar
    │       ├── spring-web-5.2.6.RELEASE.jar
    │       ├── spring-webmvc-5.2.6.RELEASE.jar
    │       ├── tomcat-embed-core-9.0.35.jar
    │       └── tomcat-embed-websocket-9.0.35.jar
    ├── META-INF
    │   ├── MANIFEST.MF
    │   └── maven
    │       └── org.springframework
    └── org
        └── springframework
            └── boot

Now you can build it!

 docker build -t springio/gs-spring-boot-docker .
Sending build context to Docker daemon  33.44MB
Step 1/8 : FROM openjdk:8-jdk-alpine
 ---> a3562aa0b991
Step 2/8 : RUN addgroup -S spring && adduser -S spring -G spring
 ---> Using cache
 ---> 5b122a1db135
Step 3/8 : USER spring:spring
 ---> Using cache
 ---> 3bdba2028e42
Step 4/8 : ARG DEPENDENCY=target/dependency
 ---> Using cache
 ---> 616945cc41ed
Step 5/8 : COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
 ---> Using cache
 ---> 1d1404d8b0e7
Step 6/8 : COPY ${DEPENDENCY}/META-INF /app/META-INF
 ---> Using cache
 ---> ad8c03fa8c4e
Step 7/8 : COPY ${DEPENDENCY}/BOOT-INF/classes /app
 ---> Using cache
 ---> 2aaadf41ccd2
Step 8/8 : ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]
 ---> Using cache
 ---> a21e7f0c88fc
Successfully built a21e7f0c88fc
Successfully tagged springio/gs-spring-boot-docker:latest

Best of luck!

Upvotes: 4

VithuBati
VithuBati

Reputation: 1928

Run this inside your project

mkdir target/dependency
(cd target/dependency; jar -xf ../*.jar)

Upvotes: 1

larsks
larsks

Reputation: 311506

You're getting a "no such file or directory" error, and it looks like that's the truth.

The Dockerfile sets:

ARG DEPENDENCY=target/dependency

And then attempts a COPY operation:

COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib

If you resolve ${DEPENDENCY}, that COPY command look like:

COPY target/dependency/BOOT-INF/lib /app/lib

And there is no target directory in the repository. Maybe this is something you're supposed to create by following the tutorial? From that document:

This Dockerfile has a DEPENDENCY parameter pointing to a directory where we have unpacked the fat jar. If we get that right, it already contains a BOOT-INF/lib directory with the dependency jars in it, and a BOOT-INF/classes directory with the application classes in it. Notice that we are using the application’s own main class hello.Application (this is faster than using the indirection provided by the fat jar launcher).

Upvotes: 1

Related Questions