A Dockerfile needs a way to put application files into an image. `COPY` does that: `COPY [source path] [target path]` copies files or directories from the build context into the image filesystem. In `WORKDIR /web-ping` followed by `COPY app.js .`, the dot targets the working directory, so the application file is available there when the container starts. section 3.2
Choose what to copy at each build step. A Java build can copy `pom.xml` first, download Maven dependencies, and then use `COPY . .` to bring in the remaining source before packaging it. If `pom.xml` has not changed, Docker can reuse the dependency step from its layer cache. section 4.2
Copying from another build stage
In a multi-stage build, `COPY --from=builder /usr/src/iotd/target/iotd-service-0.1.0.jar .` takes the compiled JAR from the builder stage and places it in the final stage’s `/app` working directory. The final image starts from an image with the Java runtime rather than the Maven build tools. section 4.2
Avoid `COPY . .` when the image does not need everything in the build context. Copying an unused directory and deleting it with a later `RUN` instruction hides its files from the resulting container filesystem, but the earlier COPY layer still adds to image size. `COPY ./app ./app` selects just the application folder. A `.dockerignore` file is another way to exclude unwanted content from the build context, especially when precise COPY patterns become awkward. section 17.1
Listing 4.2 Dockerfile for building a Java app with Maven
FROM diamol/maven:2e AS builder WORKDIR /usr/src/iotd COPY pom.xml . RUN mvn -B dependency:go-offline COPY . . RUN mvn package # app FROM diamol/openjdk:2e WORKDIR /app COPY --from=builder /usr/src/iotd/target/iotd-service-0.1.0.jar . EXPOSE 80 ENTRYPOINT ["java", "-jar", "/app/iotd-service-0.1.0.jar"]
Follow the three COPY instructions to see how a Maven build separates dependency input, source code, and the finished JAR. section 4.2

