Docker: In Dockerfile, copy files temporarily, but not for final image

I have a Java service I’d like to package, and the only thing the final docker image needs is the JAR file and a config file. However, I need to run my gradle command first to build the JAR, but I don’t want all the things that gradle uses to be in the result docker image.

Here’s my current DockerFile:

  • Boot2Docker doesn't recognize “sudo”, “tce-load”
  • How do I run pycharm within my docker container?
  • Docker Container Failed to Run
  • Docker hub automated build fails but locally not
  • This site can't be reached docs/docker.github.io
  • Python script to add data to postgres docker container runs multiple times
  • RUN apt-get update && apt-get install -y openjdk-7-jdk
    COPY . /
    RUN ./gradlew shadowJar
    CMD ["java", "-jar", "service/build/libs/service.jar", "server", "service/service.yml"]
    

    You can see I have to COPY everything first so that I can run ./gradlew (otherwise it says the command cannot be found). But in the end, all I need is the service.jar and service.yml files.

    I’m probably missing something, but how I can make everything available during the ./gradlew build step, but only have the result image include the service.jar and service.yml.

  • Kubernetes - Unknown admission plugin: DefaultStorageClass
  • Docker not releasing memory when shutdown, windows 10
  • NLTK is not working in docker
  • jq returns null from curl
  • Get file from private repo into dockerfile
  • Share docker images between hosts with NFS
  • 2 Solutions collect form web for “Docker: In Dockerfile, copy files temporarily, but not for final image”

    Building an image works as follows.

    … The docker build command will use whatever directory contains the Dockerfile as the build context (including all of its subdirectories). The build context will be sent to the Docker daemon before building the image, which means if you use / as the source repository, the entire contents of your hard drive will get sent to the daemon …

    See https://docs.docker.com/reference/builder/

    I see no way to achieve what you want. There are two options:

    1. Having all the build dependencies inside the image and build your JAR file inside the container. That bloats your image.

    2. I would recommend to build your JAR separately and just ADD the executable and config files when they are build. That means all build dependencies must be available on your development environment, but your image is as small as it can be.

    You could do this:

    FROM java:7
    COPY . /sourcecode
    WORKDIR /sourcecode
    RUN ./gradlew shadowJar && rm -rf /sourcecode
    WORKDIR /
    CMD ["java", "-jar", "service/build/libs/service.jar", "server", "service/service.yml"]
    

    This uses the Docker official java image (see repo).

    The RUN line should create your service.jar and then remove all the source code you’ve COPYd before the layer gets created, so the source code will not be part of the final image. I’m assuming gradlew will also copy/install it to /service/build/libs, otherwise you should add that step.

    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.