Skip to content

Commit f158c0d

Browse files
authored
content for Containerize service deployment
1 parent 15fa33a commit f158c0d

File tree

1 file changed

+29
-27
lines changed

1 file changed

+29
-27
lines changed

docs/aac/java-mwa-guide.md

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -417,38 +417,40 @@ In this configuration:
417417
:::column-end:::
418418
:::row-end:::
419419
Containerization means that all dependencies for the app to function are encapsulated in a lightweight image that can be reliably deployed to a wide range of hosts. To containerize deployment, follow these recommendations:
420+
420421
- *Identify domain boundaries.* Start by identifying the domain boundaries within your monolithic application. This helps determine which parts of the application you can extract into separate services.
421-
- *Create docker images.* When creating Docker images for your .NET services, use chiseled base images. These images contain only the minimal set of packages needed for .NET to run, which minimizes both the package size and the attack surface area.
422-
- *Use multi-stage Dockerfiles.* Implement multi-stage Dockerfiles to separate build-time assets from the runtime container image. It helps to keep your production images small and secure.
423-
- *Run as nonroot user.* Run your .NET containers as a nonroot user (via user name or UID, $APP_UID) to align with the principle of least privilege. It limits the potential effects of a compromised container.
422+
- *Create docker images.* When creating Docker images for your Java services, use official OpenJDK base images. These images contain only the minimal set of packages needed for Java to run, which minimizes both the package size and the attack surface area.
423+
- *Use multi-stage Dockerfiles.* Use a multi-stage Dockerfiles to separate build-time assets from the runtime container image. It helps to keep your production images small and secure. You can also use a pre-configured build server and copy the jar file into the container image.
424+
- *Run as nonroot user.* Run your Java containers as a nonroot user (via user name or UID, $APP_UID) to align with the principle of least privilege. It limits the potential effects of a compromised container.
424425
- *Listen on port 8080.* When running as a nonroot user, configure your application to listen on port 8080. It's a common convention for nonroot users.
425426
- *Encapsulate dependencies.* Ensure that all dependencies for the app to function are encapsulated in the Docker container image. Encapsulation allows the app to be reliably deployed to a wide range of hosts.
426427
- *Choose the right base images.* The base image you choose depends on your deployment environment. If you're deploying to Azure Container Apps, for instance, you need to use Linux Docker images.
427-
For example, the reference implementation uses a [multi-stage](https://docs.docker.com/build/building/multi-stage/) build process. The initial stages compile and build the application using a full SDK image (`mcr.microsoft.com/dotnet/sdk:8.0-jammy`). The final runtime image is created from the `chiseled` base image, which excludes the SDK and build artifacts. The service runs as a nonroot user (`USER $APP_UID`) and exposes port 8080. The dependencies required for the application to operate are included within the Docker image, as evidenced by the commands to copy project files and restore packages. The choice of Linux-based images (`mcr.microsoft.com/dotnet/aspnet:8.0-jammy-chiseled`) for the runtime environment for deployment within Azure Container Apps, which requires Linux containers.
428+
429+
The reference implementation demonstrates a Docker build process for containerizing a Java application. This Dockerfile uses a single-stage build with the OpenJDK base image (`mcr.microsoft.com/openjdk/jdk:17-ubuntu`), which provides the necessary Java runtime environment.
430+
431+
The Dockerfile includes the following steps:
432+
1. **Volume Declaration**: A temporary volume (`/tmp`) is defined, allowing for temporary file storage separate from the container's main filesystem.
433+
2. **Copying Artifacts**: The application's JAR file (`email-processor.jar`) is copied into the container, along with the Application Insights agent (`applicationinsights-agent.jar`) for monitoring.
434+
3. **Setting the Entrypoint**: The container is configured to run the application with the Application Insights agent enabled, using `java -javaagent` to monitor the application during runtime.
435+
436+
This Dockerfile keeps the image lean by only including runtime dependencies, suitable for deployment environments like **Azure Container Apps**, which support Linux-based containers.
437+
428438

429439
```dockerfile
430-
# Build in a separate stage to avoid copying the SDK into the final image
431-
FROM mcr.microsoft.com/dotnet/sdk:8.0-jammy AS build
432-
ARG BUILD_CONFIGURATION=Release
433-
WORKDIR /src
434-
# Restore packages
435-
COPY ["Relecloud.TicketRenderer/Relecloud.TicketRenderer.csproj", "Relecloud.TicketRenderer/"]
436-
COPY ["Relecloud.Messaging/Relecloud.Messaging.csproj", "Relecloud.Messaging/"]
437-
COPY ["Relecloud.Models/Relecloud.Models.csproj", "Relecloud.Models/"]
438-
RUN dotnet restore "./Relecloud.TicketRenderer/Relecloud.TicketRenderer.csproj"
439-
# Build and publish
440-
COPY . .
441-
WORKDIR "/src/Relecloud.TicketRenderer"
442-
RUN dotnet publish "./Relecloud.TicketRenderer.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
443-
# Chiseled images contain only the minimal set of packages needed for .NET 8.0
444-
FROM mcr.microsoft.com/dotnet/aspnet:8.0-jammy-chiseled AS final
445-
WORKDIR /app
446-
EXPOSE 8080
447-
# Copy the published app from the build stage
448-
COPY --from=build /app/publish .
449-
# Run as non-root user
450-
USER $APP_UID
451-
ENTRYPOINT ["dotnet", "./Relecloud.TicketRenderer.dll"]
440+
# Use OpenJDK 17 base image on Ubuntu as the foundation
441+
FROM mcr.microsoft.com/openjdk/jdk:17-ubuntu
442+
443+
# Define a volume to allow temporary files to be stored separately from the container's main file system
444+
VOLUME /tmp
445+
446+
# Copy the packaged JAR file into the container
447+
COPY target/email-processor.jar app.jar
448+
449+
# Copy the Application Insights agent for monitoring
450+
COPY target/agent/applicationinsights-agent.jar applicationinsights-agent.jar
451+
452+
# Set the entry point to run the application with the Application Insights agent
453+
ENTRYPOINT ["java", "-javaagent:applicationinsights-agent.jar", "-jar", "/app.jar"]
452454
```
453455

454456
## Deploy the reference implementation
@@ -459,6 +461,6 @@ ENTRYPOINT ["dotnet", "./Relecloud.TicketRenderer.dll"]
459461
*Figure 3. Architecture of the reference implementation. Download a [Visio file](https://arch-center.azureedge.net/modern-web-app-java-1.0.vsdx) of this architecture.*
460462

461463
>[!div class="nextstepaction"]
462-
>[Modern Web App pattern for .NET reference implementation][reference-implementation]
464+
>[Modern Web App pattern for Java reference implementation][reference-implementation]
463465
464466
[reference-implementation]: https://github.com/Azure/modern-web-app-pattern-java

0 commit comments

Comments
 (0)