Skip to content

Commit

Permalink
automated commit
Browse files Browse the repository at this point in the history
Signed-off-by: Public copy <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
github-actions[bot] committed Nov 20, 2024
1 parent b6c3e5f commit db06d60
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 83 deletions.
161 changes: 79 additions & 82 deletions images/maven/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<!--overview:start-->
# Chainguard Image for maven

Minimal image with Maven build system.
Minimal image with the Maven build system.

Chainguard Images are regularly-updated, minimal container images with low-to-zero CVEs.
<!--overview:end-->
Expand All @@ -32,133 +32,130 @@ Be sure to replace the `ORGANIZATION` placeholder with the name used for your or
<!--getting:end-->

<!--body:start-->
## Using Maven
## Compatibility Notes

Chainguard Maven images come with different versions of OpenJDK, ensure you choose the correct image tag for your application needs. In these examples we will use a Chainguard Maven image based on OpenJDK 17.
The Maven Chainguard image was built to work as a drop-in replacement for the official [Maven image on Docker Hub](https://hub.docker.com/_/maven). Like most of Chainguard's images, the Maven image does not operate as the root user and includes only the minimum packages needed to function.

Check the maven version
```
docker run --rm --platform=linux/amd64 cgr.dev/chainguard/maven:openjdk-17 --version
Chainguard Maven images come with different versions of OpenJDK. This means you will need to ensure that you choose the correct image tag for your application needs.

## Getting Started

To illustrate how you can use Chainguard's Maven image, you will need a Java application for the Maven image to build. This overview will use a Spring Boot example application found in [this GitHub repository](https://github.com/chainguard-dev/learning-labs-java).

Clone the repository to your local machine and navigate into the project directory:

```shell
git clone https://github.com/chainguard-dev/learning-labs-java.git
cd learning-labs-java/
```

### Examples
The example's Dockerfile uses the default Maven image from Docker Hub. Overwrite this file with the following command to instead use the Chainguard Maven Image:

```shell
cat > Dockerfile <<EOF
FROM cgr.dev/chainguard/maven
#### SpringBoot
WORKDIR /work
Visit https://start.spring.io
COPY src/ src/
COPY pom.xml pom.xml
Select the following options:
RUN mvn clean package
RUN REPOSITORY=$(mvn help:evaluate -Dexpression=settings.localRepository -q -DforceStdout) && rm -rf ${REPOSITORY}
1. __Project__: select `Maven Project`
2. __Spring Boot__: latest GA version, e.g. `2.7.5`
3. __Project Metadata__: populate your application details
4. __Packaging__: select your packaging. For this demo, we'll use `jar`
5. __Java__: select Java version, e.g. `17` that matches the OpenJDK image version we are building with
6. __Dependencies__: choose your dependencies, e.g. `Spring Web`
7. __Generate__: Hit that generate button!
WORKDIR /app
![Spring Initializr](docs/png/spring_initializr.png)
RUN cp /work/target/java-demo-app-1.0.0.jar .
ENTRYPOINT ["java", "-jar", "java-demo-app-1.0.0.jar"]
EOF
```

Then build an image using this Dockerfile with the following command:

Go to your downloaded zip file, unzip
```sh
mkdir ~/chainguard-sb
cd chainguard-sb
mv ~/Downloads/demo.zip .
unzip demo.zip
cd demo
```shell
docker build -t maven-app .
```

You now have your generated Spring Boot application souce code. Now let's build it.
This command tags the image as `maven-app`. Run this image:

```sh
docker run --platform=linux/amd64 --rm -v ${PWD}:/home/build cgr.dev/chainguard/maven:openjdk-17 clean install
```shell
docker run --rm -p 8080:8080 maven-app
```

Check to see your compiled `jar` file
```sh
find target -name "*.jar"
The app should now be running and you can interact with it by accessing it at [`localhost:8080/hello`](http://localhost:8080/hello), either in your browser or with `curl`, as in the following example:

```shell
curl localhost:8080/hello
```
You should see...
```
target/demo-0.0.1-SNAPSHOT.jar
Hello, World! I love Chainguard!
```

Let's run the application using the Chainguard OpenJDK JRE image. _Note_ there's a few things happening here and this is just for test purposes, see section below for more real world scenarios.
This shows that the application is working as expected. You can stop the container by pressing `CTRL + C` in the terminal where it's running.

Choose the Chainguard OpenJDK JRE image tag that matches your application's Java version selected when generating your Spring Boot application above.

```
docker run --platform=linux/amd64 --rm -p 8080:8080 -v ${PWD}/target:/app/ cgr.dev/chainguard/jre:openjdk-17 -jar /app/demo-0.0.1-SNAPSHOT.jar
```
### Using Chainguard's Maven image in a multi-stage build
The image built in the previous example still includes build tooling and source code that aren't needed in the production image. Using a multi-stage build can reduce the number of dependencies.

Now visit the Spring Boot Application in your browser using the same port mapped in the docker command above.
To try this out, create a new Dockerfile named `Dockerfile.multi-stage`:

e.g http://localhost:8080/
```shell
cat > Dockerfile.multi-stage <<EOF
FROM cgr.dev/chainguard/maven AS builder
![Spring Whitelabel](docs/png/spring_whitelabel.png)
WORKDIR /work
Note this is the expected Spring Whitelabel error page.
COPY src/ src/
COPY pom.xml pom.xml
RUN mvn clean package
RUN REPOSITORY=$(mvn help:evaluate -Dexpression=settings.localRepository -q -DforceStdout) && rm -rf ${REPOSITORY}
#### Multistage Dockerfile
FROM cgr.dev/chainguard/jre AS runner
The steps above are useful to test Chainguard images however, we can now create a multistage Dockerfile that will build a smaller image to run our demo application.
WORKDIR /app
First create a `.dockerignore` file so we don't copy the generated maven `./target` folder from the steps above into the multistage docker build. This helps avoid any permission errors during the build.
COPY --from=builder /work/target/java-demo-app-1.0.0.jar .
```sh
cat <<EOF >>.dockerignore
target/
ENTRYPOINT ["java", "-jar", "java-demo-app-1.0.0.jar"]
EOF
```

Next create the multistage `Dockerfile`
Note that there are two `FROM` lines, the first one creates the `builder` image much as before and the second (named `runner`) copies the built JAR from the builder step into the smaller `cgr.dev/chainguard/jre` image. The result is a container image that only contains the JRE and the built application.

```dockerfile
cat <<EOF >>Dockerfile
FROM cgr.dev/chainguard/maven:openjdk-17
Using this multi-stage Dockerfile, build a new image:

WORKDIR /home/build

COPY . ./
```shell
docker build -f Dockerfile.multi-stage -t maven-app-multi-stage .
```

RUN mvn install
This command tags the image as `maven-app-multi-stage`. Run this image:

FROM cgr.dev/chainguard/jre:openjdk-17
```shell
docker run --rm -p 8080:8080 maven-app-multi-stage
```

COPY --from=0 /home/build/target/demo-*.jar /app/demo.jar
Again, the application will be accessible at [localhost:8080/hello](http://localhost:8080/hello):

CMD ["-jar", "/app/demo.jar"]
EOF
```shell
curl localhost:8080/hello
```

Build your application image
```sh
docker build --platform=linux/amd64 -t my-chainguard-springboot-app .
```

Now run your application
```sh
docker run --platform=linux/amd64 --rm -p 8080:8080 my-chainguard-springboot-app
Hello, World! I love Chainguard!
```
Again visit the Spring Boot Whitelabel page in your browser

e.g. http://localhost:8080/
Once again, press `CTRL + C` to stop the running container.

![Spring Whitelabel](docs/png/spring_whitelabel.png)

### What's inside?

Now let's take a closer look at your newly built image.

Check the size of your image, as this is based on Chainguard images it will only contain the Linux packages required to run your application. The reduces the number of packages that can be affected by CVEs.

```sh
docker images | grep my-chainguard-springboot-app
```
## Documentation and Resources

You can also check for vulnerabilities using your favorite scanner.
* [Learning Lab: Chainguard's Java Container Image](https://www.youtube.com/watch?v=8v8xlFnRHfs)
* [Chainguard Blog: Building minimal and low CVE images for Java](https://www.chainguard.dev/unchained/building-minimal-and-low-cve-images-for-java)
* [Video: Building Minimal Images for Applications with Runtimes](https://edu.chainguard.dev/chainguard/chainguard-images/videos/minimal-runtime-images/)
* [Video: How to Migrate a Java Application to Chainguard Images](https://edu.chainguard.dev/chainguard/chainguard-images/videos/java-images/)
* [Vulnerability Comparison: maven](https://edu.chainguard.dev/chainguard/chainguard-images/vuln-comparison/maven/)
* [Apache Maven Project Site](https://maven.apache.org/)
<!--body:end-->

## Contact Support
Expand Down
2 changes: 1 addition & 1 deletion images/maven/metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ image: cgr.dev/chainguard/maven
logo: https://storage.googleapis.com/chainguard-academy/logos/maven.svg
endoflife: ""
console_summary: ""
short_description: Minimal image with Maven build system.
short_description: Minimal image with the Maven build system.
compatibility_notes: ""
readme_file: README.md
upstream_url: https://maven.apache.org/
Expand Down

0 comments on commit db06d60

Please sign in to comment.