Search code examples
spring-bootdockerheroku

Copy failed on heroku when copying target jar


How can I change the below Dockerfile so It would get to copy the jar from correct folder?!

I have this Dockerfile

# Docker multi-stage build

# 1. Building the App with Maven
#FROM maven:3-jdk-11
#FROM openjdk:8-jdk-alpine
FROM maven:3.5.2-jdk-8

# Just echo so we can see, if everything is there :)
RUN ls -l

RUN mvn install
RUN mvn jar:jar

VOLUME /tmp

RUN ls -l
RUN ls -l target/

# Add Spring Boot app.jar to Container
COPY "target/programmingpdfconv-0.0.1-SNAPSHOT.jar" app.jar

RUN ls /*

# Fire up our Spring Boot app by default
CMD [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]

locally ok when building with heroku fails on:

remote: drwxr-xr-x 4 root root       64 Jun  7 16:47 classes
remote: drwxr-xr-x 3 root root       25 Jun  7 16:47 generated-sources
remote: drwxr-xr-x 3 root root       30 Jun  7 16:47 generated-test-sources
remote: drwxr-xr-x 2 root root       28 Jun  7 16:47 maven-archiver
remote: drwxr-xr-x 3 root root       35 Jun  7 16:47 maven-status
remote: -rw-r--r-- 1 root root 19578555 Jun  7 16:47 programmingpdfconv-0.0.1-SNAPSHOT.jar
remote: -rw-r--r-- 1 root root     5664 Jun  7 16:47 programmingpdfconv-0.0.1-SNAPSHOT.jar.original
remote: drwxr-xr-x 2 root root      163 Jun  7 16:47 surefire-reports
remote: drwxr-xr-x 3 root root       17 Jun  7 16:47 test-classes
remote: Removing intermediate container 9b42499c36c9
remote:  ---> 7f7adf538801
remote: Step 10/12 : COPY "target/programmingpdfconv-0.0.1-SNAPSHOT.jar" app.jar
remote: COPY failed: stat /var/lib/docker/tmp/docker-builder05459395/target/programmingpdfconv-0.0.1-SNAPSHOT.jar: no such file or directory
remote: 
remote: Verifying deploy...
remote: 
remote: !   Push rejected to pure-fortress-92268.
remote: 
To https://git.heroku.com/pure-fortress-92268.git
 ! [remote rejected] master -> master (pre-receive hook declined)

So I see the folder to copy from is different on heroku, how can I change the Dockerfile so It would get to copy it from correct folder?! (I tried many things didn't work.)

heroku.yml

build:
  docker:
    web: Dockerfile

Adding the tree structure of the project:

$ tree
.
|-- Dockerfile
|-- Dockerfile.org
|-- Dockerfile.server
|-- README.md
|-- heroku.yml
|-- mvnw
|-- mvnw.cmd
|-- pom.xml
|-- src
|   |-- main
|   |   |-- java
|   |   |   `-- com
|   |   |       `-- tomdog
|   |   |           `-- programmingpdfconv
|   |   |               |-- GreetingController.java
|   |   |               `-- ProgrammingpdfconvApplication.java
|   |   `-- resources
|   |       |-- application.properties
|   |       `-- templates
|   |           |-- greeting.html
|   |           `-- index.html
|   `-- test
|       `-- java
|           `-- com
|               `-- tomdog
|                   `-- programmingpdfconv
|                       `-- ProgrammingpdfconvApplicationTests.java
`-- target
    |-- classes
    |   |-- application.properties
    |   |-- com
    |   |   `-- tomdog
    |   |       `-- programmingpdfconv
    |   |           |-- GreetingController.class
    |   |           `-- ProgrammingpdfconvApplication.class
    |   `-- templates
    |       |-- greeting.html
    |       `-- index.html
    |-- generated-sources
    |   `-- annotations
    |-- generated-test-sources
    |   `-- test-annotations
    |-- maven-archiver
    |   `-- pom.properties
    |-- maven-status
    |   `-- maven-compiler-plugin
    |       |-- compile
    |       |   `-- default-compile
    |       |       |-- createdFiles.lst
    |       |       `-- inputFiles.lst
    |       `-- testCompile
    |           `-- default-testCompile
    |               |-- createdFiles.lst
    |               `-- inputFiles.lst
    |-- programmingpdfconv-0.0.1-SNAPSHOT.jar
    |-- programmingpdfconv-0.0.1-SNAPSHOT.jar.original
    |-- surefire-reports
    |   |-- TEST-com.tomdog.programmingpdfconv.ProgrammingpdfconvApplicationTests.xml
    |   `-- com.tomdog.programmingpdfconv.ProgrammingpdfconvApplicationTests.txt
    `-- test-classes
        `-- com
            `-- tomdog
                `-- programmingpdfconv
                    `-- ProgrammingpdfconvApplicationTests.class

36 directories, 31 files

Solution

  • With COPY instruction, the <src> path must be inside the context of the build, not inside the building container. You cannot use COPY to copy data inside the container. It works locally because you already have the target directory from previous builds. Try to remove target directory and build the image locally, and it should fail this time.

    The solution is to simply replace you COPY instruction with

    RUN cp -a target/programmingpdfconv-0.0.1-SNAPSHOT.jar app.jar
    

    Alternatively, you can reduce the image size significantly if you do it in one step and clean up after that

    # not sure why you need to `install` the package in the local repository?
    RUN mvn install jar:jar \
        && cp -a target/programmingpdfconv-0.0.1-SNAPSHOT.jar app.jar \
        && rm -rf target "$HOME/.m2"
    

    You should also consider excluding the maven build directory target from the docker build context to increase the build performance by adding a .dockerignore file to the root directory.