Start learning free

LESSON 151 OF 173 · BACKEND: SHIPPING IT

Install Before You Copy in Java

Practice

The base image has Java and Maven, but nothing of the shop. COPY copies files from the shop's folder on your computer, where you run docker build, into the image: COPY source destination. A . as the destination is the image's current folder, /app thanks to WORKDIR. RUN runs a command inside the image while it is being built, and keeps what the command changed. mvn dependency:go-offline downloads every package listed in pom.xml, and mvn package compiles the code in src and packs the shop into one jar file in target.

Each line of a Dockerfile makes a layer, a saved change to the image, and Docker keeps the layers in a cache. On the next build it reuses a layer, CACHED, as long as the line and the files it copies have not changed. From the first line that changed, every line runs again. So the order matters: what changes rarely goes at the top, what changes often at the bottom.

Here is the same idea for a program built on Node.js: its package list, package.json, is copied and installed first, and the code last.

static String[] dockerfile = {
    "FROM node:22-slim",
    "WORKDIR /srv",
    "COPY package.json .",
    "RUN npm install",
    "COPY . .",
};

The check builds your image, then changes ShopApplication.java in src and builds again. When your lines are right, it prints:

$ docker build -t shop .
[1/7] FROM maven:3.9-eclipse-temurin-21
[2/7] WORKDIR /app
[3/7] ENV SERVER_PORT=8000
[4/7] COPY pom.xml .: copies pom.xml into /app
[5/7] RUN mvn dependency:go-offline: downloads Spring Boot 3.3.5 (web and JDBC), sqlite-jdbc 3.46.1.3 and the packages they need
[6/7] COPY . .: copies src, pom.xml, Dockerfile into /app
[7/7] RUN mvn package: compiles the shop and packs it into /app/target/shop.jar
In the image: /app/pom.xml, /app/src, /app/Dockerfile, /app/target/shop.jar
You change ShopApplication.java in src and build again:
[1/7] FROM maven:3.9-eclipse-temurin-21: CACHED
[2/7] WORKDIR /app: CACHED
[3/7] ENV SERVER_PORT=8000: CACHED
[4/7] COPY pom.xml .: CACHED
[5/7] RUN mvn dependency:go-offline: CACHED
[6/7] COPY . .: runs again, src changed
[7/7] RUN mvn package: runs again, because a line above it ran again
mvn dependency:go-offline was CACHED: a change to the code does not download the packages again

Your task: after the three lines of the base, add four lines to the array dockerfile: copy pom.xml into the current folder, download the packages with mvn dependency:go-offline, copy the whole shop folder into the current folder, then compile and pack the shop with mvn package. A change to the code must leave the download CACHED.


Assignment
Follow the Coding Tutorial to add the COPY, RUN, COPY and RUN lines to the shop's Dockerfile, in that order.


Hint
In COPY source destination, a dot as the source means everything in the shop's folder, and a dot as the destination means /app. Maven can only read pom.xml once a line above it has copied the file in.


STEP 1 OF 4
    Ctrl + Enter to check

    Ship Dockerfile Install in Java

    Keep going with Java1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free