guides: update java language guide (#20335)

* update java language guide

Signed-off-by: Craig Osterhout <craig.osterhout@docker.com>

* fix typo

Signed-off-by: Craig Osterhout <craig.osterhout@docker.com>

* Update content/language/java/run-tests.md

Co-authored-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>

---------

Signed-off-by: Craig Osterhout <craig.osterhout@docker.com>
Co-authored-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
This commit is contained in:
Craig Osterhout 2024-07-10 08:34:57 -07:00 committed by GitHub
parent d03964971a
commit 3a99e84975
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 221 additions and 18 deletions

View File

@ -32,11 +32,17 @@ The sample application is a Spring Boot application built using Maven. For more
## Initialize Docker assets
Now that you have an application, you can use `docker init` to create the
necessary Docker assets to containerize your application. Inside the
`spring-petclinic` directory, run the `docker init` command in a terminal.
`docker init` provides some default configuration, but you'll need to answer a
few questions about your application. Use the answers in the following example in order to follow along with this guide.
Now that you have an application, you can create the necessary Docker assets to
containerize your application. You can use Docker Desktop's built-in Docker Init
feature to help streamline the process, or you can manually create the assets.
{{< tabs >}}
{{< tab name="Use Docker Init" >}}
Inside the `spring-petclinic` directory, run the `docker init` command. `docker
init` provides some default configuration, but you'll need to answer a few
questions about your application. Refer to the following example to answer the
prompts from `docker init` and use the same answers for your prompts.
The sample application already contains Docker assets. You'll be prompted to overwrite the existing Docker assets. To continue with this guide, select `y` to overwrite them.
@ -67,17 +73,214 @@ exists, so `docker init` overwrites that file rather than creating a new
directory. Both names are supported, but Compose prefers the canonical
`compose.yaml`.
You should now have the following three new files in your `spring-petclinic`
{{< /tab >}}
{{< tab name="Manually create assets" >}}
If you don't have Docker Desktop installed or prefer creating the assets
manually, you can create the following files in your project directory.
Create a file named `Dockerfile` with the following contents.
```dockerfile {collapse=true,title=Dockerfile}
# syntax=docker/dockerfile:1
# Comments are provided throughout this file to help you get started.
# If you need more help, visit the Dockerfile reference guide at
# https://docs.docker.com/go/dockerfile-reference/
# Want to help us make this template better? Share your feedback here: https://forms.gle/ybq9Krt8jtBL3iCk7
################################################################################
# Create a stage for resolving and downloading dependencies.
FROM eclipse-temurin:17-jdk-jammy as deps
WORKDIR /build
# Copy the mvnw wrapper with executable permissions.
COPY --chmod=0755 mvnw mvnw
COPY .mvn/ .mvn/
# Download dependencies as a separate step to take advantage of Docker's caching.
# Leverage a cache mount to /root/.m2 so that subsequent builds don't have to
# re-download packages.
RUN --mount=type=bind,source=pom.xml,target=pom.xml \
--mount=type=cache,target=/root/.m2 ./mvnw dependency:go-offline -DskipTests
################################################################################
# Create a stage for building the application based on the stage with downloaded dependencies.
# This Dockerfile is optimized for Java applications that output an uber jar, which includes
# all the dependencies needed to run your app inside a JVM. If your app doesn't output an uber
# jar and instead relies on an application server like Apache Tomcat, you'll need to update this
# stage with the correct filename of your package and update the base image of the "final" stage
# use the relevant app server, e.g., using tomcat (https://hub.docker.com/_/tomcat/) as a base image.
FROM deps as package
WORKDIR /build
COPY ./src src/
RUN --mount=type=bind,source=pom.xml,target=pom.xml \
--mount=type=cache,target=/root/.m2 \
./mvnw package -DskipTests && \
mv target/$(./mvnw help:evaluate -Dexpression=project.artifactId -q -DforceStdout)-$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout).jar target/app.jar
################################################################################
# Create a stage for extracting the application into separate layers.
# Take advantage of Spring Boot's layer tools and Docker's caching by extracting
# the packaged application into separate layers that can be copied into the final stage.
# See Spring's docs for reference:
# https://docs.spring.io/spring-boot/docs/current/reference/html/container-images.html
FROM package as extract
WORKDIR /build
RUN java -Djarmode=layertools -jar target/app.jar extract --destination target/extracted
################################################################################
# Create a new stage for running the application that contains the minimal
# runtime dependencies for the application. This often uses a different base
# image from the install or build stage where the necessary files are copied
# from the install stage.
#
# The example below uses eclipse-turmin's JRE image as the foundation for running the app.
# By specifying the "17-jre-jammy" tag, it will also use whatever happens to be the
# most recent version of that tag when you build your Dockerfile.
# If reproducability is important, consider using a specific digest SHA, like
# eclipse-temurin@sha256:99cede493dfd88720b610eb8077c8688d3cca50003d76d1d539b0efc8cca72b4.
FROM eclipse-temurin:17-jre-jammy AS final
# Create a non-privileged user that the app will run under.
# See https://docs.docker.com/go/dockerfile-user-best-practices/
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
USER appuser
# Copy the executable from the "package" stage.
COPY --from=extract build/target/extracted/dependencies/ ./
COPY --from=extract build/target/extracted/spring-boot-loader/ ./
COPY --from=extract build/target/extracted/snapshot-dependencies/ ./
COPY --from=extract build/target/extracted/application/ ./
EXPOSE 8080
ENTRYPOINT [ "java", "org.springframework.boot.loader.launch.JarLauncher" ]
```
The sample already contains a Compose file. Overwrite this file to follow along with the guide. Update the`docker-compose.yaml` with the following contents.
```yaml {collapse=true,title=docker-compose.yaml}
# Comments are provided throughout this file to help you get started.
# If you need more help, visit the Docker Compose reference guide at
# https://docs.docker.com/go/compose-spec-reference/
# Here the instructions define your application as a service called "server".
# This service is built from the Dockerfile in the current directory.
# You can add other services your application may depend on here, such as a
# database or a cache. For examples, see the Awesome Compose repository:
# https://github.com/docker/awesome-compose
services:
server:
build:
context: .
ports:
- 8080:8080
# The commented out section below is an example of how to define a PostgreSQL
# database that your application can use. `depends_on` tells Docker Compose to
# start the database before your application. The `db-data` volume persists the
# database data between container restarts. The `db-password` secret is used
# to set the database password. You must create `db/password.txt` and add
# a password of your choosing to it before running `docker-compose up`.
# depends_on:
# db:
# condition: service_healthy
# db:
# image: postgres
# restart: always
# user: postgres
# secrets:
# - db-password
# volumes:
# - db-data:/var/lib/postgresql/data
# environment:
# - POSTGRES_DB=example
# - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
# expose:
# - 5432
# healthcheck:
# test: [ "CMD", "pg_isready" ]
# interval: 10s
# timeout: 5s
# retries: 5
# volumes:
# db-data:
# secrets:
# db-password:
# file: db/password.txt
```
Create a file named `.dockerignore` with the following contents.
```text {collapse=true,title=".dockerignore"}
# Include any files or directories that you don't want to be copied to your
# container here (e.g., local build artifacts, temporary files, etc.).
#
# For more help, visit the .dockerignore file reference guide at
# https://docs.docker.com/go/build-context-dockerignore/
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/.next
**/.cache
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/charts
**/docker-compose*
**/compose.y*ml
**/target
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
**/vendor
LICENSE
README.md
```
{{< /tab >}}
{{< /tabs >}}
You should now have the following three files in your `spring-petclinic`
directory.
- [Dockerfile](/reference/dockerfile/)
- [.dockerignore](/reference/dockerfile/#dockerignore-file)
- [docker-compose.yaml](../../compose/compose-file/_index.md)
You can open the files in a code or text editor, then read the comments to learn
more about the instructions, or visit the links in the previous list.
## Run the application
Inside the `spring-petclinic` directory, run the following command in a

View File

@ -22,7 +22,7 @@ for the application you containerized in the previous section. This includes:
You can use containers to set up local services, like a database. In this section, you'll update the `docker-compose.yaml` file to define a database service and a volume to persist data. Also, this particular application uses a system property to define the database type, so you'll need to update the `Dockerfile` to pass in the system property when starting the app.
In the cloned repository's directory, open the `docker-compose.yaml` file in an IDE or text editor. `docker init` added an example database service, but it'll require a few changes for your unique app.
In the cloned repository's directory, open the `docker-compose.yaml` file in an IDE or text editor. Your Compose file has an example database service, but it'll require a few changes for your unique app.
In the `docker-compose.yaml` file, you need to do the following:
- Uncomment all of the database instructions. You'll now use a database service
@ -41,7 +41,7 @@ In the `docker-compose.yaml` file, you need to do the following:
overrides the default value defined in
`spring-petclinic/src/main/resources/application-postgres.properties`.
The following is the updated `compose.yaml` file. All comments have been removed.
The following is the updated `docker-compose.yaml` file. All comments have been removed.
```yaml {hl_lines="7-29"}
services:
@ -113,7 +113,7 @@ as a development image.
Replace the contents of your Dockerfile with the following.
```dockerfile {hl_lines="22-28"}
```dockerfile {hl_lines="22-29"}
# syntax=docker/dockerfile:1
FROM eclipse-temurin:17-jdk-jammy as deps
@ -141,7 +141,8 @@ RUN cp -r /build/target/extracted/dependencies/. ./
RUN cp -r /build/target/extracted/spring-boot-loader/. ./
RUN cp -r /build/target/extracted/snapshot-dependencies/. ./
RUN cp -r /build/target/extracted/application/. ./
CMD [ "java", "-Dspring.profiles.active=postgres", "-Dspring-boot.run.jvmArguments='-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000'", "org.springframework.boot.loader.launch.JarLauncher" ]
ENV JAVA_TOOL_OPTIONS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000
CMD [ "java", "-Dspring.profiles.active=postgres", "org.springframework.boot.loader.launch.JarLauncher" ]
FROM eclipse-temurin:17-jre-jammy AS final
ARG UID=10001
@ -170,9 +171,7 @@ In the `Dockerfile` you added a new stage labeled `development` based on the `ex
The current Compose file doesn't start your development container. To do that, you must update your Compose file to target the development stage. Also, update the port mapping of the server service to provide access for the debugger.
Open the `petclinic` in your IDE or a text editor and create a new file named
`docker-compose.dev.yml`. Copy and paste the following instructions into the
file.
Open the `docker-compose.yaml` and add the following instructions into the file.
```yaml {hl_lines=["5","8"]}
services:

View File

@ -56,7 +56,8 @@ RUN cp -r /build/target/extracted/dependencies/. ./
RUN cp -r /build/target/extracted/spring-boot-loader/. ./
RUN cp -r /build/target/extracted/snapshot-dependencies/. ./
RUN cp -r /build/target/extracted/application/. ./
CMD [ "java", "-Dspring.profiles.active=postgres", "-Dspring-boot.run.jvmArguments='-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000'", "org.springframework.boot.loader.launch.JarLauncher" ]
ENV JAVA_TOOL_OPTIONS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000"
CMD [ "java", "-Dspring.profiles.active=postgres", "org.springframework.boot.loader.launch.JarLauncher" ]
FROM eclipse-temurin:17-jre-jammy AS final
ARG UID=10001