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:

  • Boot2Docke init: boot2docker init error in run: Failed to initialize machine “boot2docker-vm”: exit status 1
  • Docker Compose 3 controlling resources (memory, cpu)
  • kubectl: Error from server: No SSH tunnels currently open
  • Docker Running the Java -JAR file to create Cassandra KeySpaces. But its not creating
  • How can I use an ephemeral volume for a Docker container using an official MySQL image with docker-compose?
  • Schedule a container with docker swarm using gpu memory as a constraint
  • 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.

  • Host to container volume mapping using Ansible not working
  • Where should a dockerized web application store uploaded files?
  • Unable to get Maven version from /usr/share/maven/bin/mvn Could not find system variable
  • How to run read command inside a Dockerfile?
  • How can I load the docker images before the service starts?
  • cron on a docker container for laravel not working
  • 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.