Skip to content

Commit 5c10955

Browse files
copy edit pass
1 parent 5398505 commit 5c10955

File tree

1 file changed

+68
-79
lines changed

1 file changed

+68
-79
lines changed

articles/container-apps/java-containers-intro.md

Lines changed: 68 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,34 @@ author: craigshoemaker
66
ms.service: azure-container-apps
77
ms.custom: devx-track-azurecli, devx-track-extended-java
88
ms.topic: tutorial
9-
ms.date: 03/07/2025
9+
ms.date: 04/08/2025
1010
ms.author: cshoe
11+
ai-usage: ai-generated
1112
---
1213

1314
# Introduction to containers for Java applications
1415

15-
TODO
16+
Containers provide a consistent, portable environment for your Java applications across development, testing, and production stages. This article introduces containerization concepts for Java applications and guides you through creating, debugging, optimizing, and deploying containerized Java applications to Azure Container Apps.
1617

17-
## Understanding containers for Java applications
18+
In this article, you'll learn about:
1819

19-
Containers package applications with their dependencies, ensuring consistency across environments. For Java developers, this means bundling the application, its dependencies, JRE/JDK, and configuration files into a single, portable unit.
20+
- Essential containerization concepts for Java developers
21+
- Setting up your development environment for containerized Java applications
22+
- Creating Dockerfiles optimized for Java workloads
23+
- Configuring local development workflows with containers
24+
- Debugging containerized Java applications
25+
- Optimizing Java containers for production
26+
- Deploying your containerized Java applications to Azure Container Apps
27+
28+
By containerizing your Java applications, you get consistent environments, simplified deployment, efficient resource utilization, and improved scalability—all critical for modern cloud-native applications.
29+
30+
## Containers for Java applications
31+
32+
Containers package applications with their dependencies, ensuring consistency across environments. For Java developers, this means bundling the application, its dependencies, JRE/JDK, and configuration files into a single, portable unit.
2033

2134
Containers solve the "it works on my machine" problem by providing the same runtime environment everywhere.
2235

23-
Containerization differs from virtualization in that containers share the host OS kernel, making them more lightweight and efficient. This approach is beneficial for Java applications, which already run in a virtual machine (JVM). Containerizing Java applications adds minimal overhead while providing significant deployment benefits.
36+
Containerization has key advantages over virtualization that make them ideal for cloud development. In contrast to a virtual machine, a container runs on a server's host OS kernel. This is beneficial for Java applications which already run in a virtual machine (JVM). Containerizing Java applications adds minimal overhead while providing significant deployment benefits.
2437

2538
The container ecosystem includes several key components:
2639

@@ -147,7 +160,7 @@ Containers are meant to execute in various contexts. In this section, you learn
147160

148161
Most Java applications interact with databases, caches, or other services.
149162

150-
Docker Compose is a tool used to define and manage multi-container Docker applications. It allows you to configure your application's services, networks, and volumes using a simple YAML file named `docker-compose.yml`. With Docker Compose, you can start, stop, and manage all the containers in your application as a single unit.
163+
Docker Compose helps you define and manage multi-container Docker applications. It allows you to configure your application's services, networks, and volumes using a simple YAML file named `docker-compose.yml`. With Docker Compose, you can start, stop, and manage all the containers in your application as a single unit.
151164

152165
The following example demonstrates how to configure Docker Compose to prepare a database connection to your application.
153166

@@ -186,7 +199,7 @@ This configuration creates two containers: one for your Java application and one
186199
187200
## Debugging containerized applications
188201
189-
TODO
202+
Debugging Java applications inside containers can be challenging because the code runs in an isolated environment. Standard debugging approaches don't directly apply, but with the right configuration, you can establish a remote debugging connection to containerized Java applications. This section shows you how to configure your containers for debugging, connect your development tools to running containers, and troubleshoot common container-related issues.
190203
191204
### Setting Up Remote Debugging
192205
@@ -223,7 +236,9 @@ ENTRYPOINT ["java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,addre
223236

224237
### Troubleshooting Container Issues
225238

226-
When containers don't behave as expected, use these commands for troubleshooting:
239+
When containers don't behave as expected, you can inspect your app's logs to investigate the issue.
240+
241+
Use the following commands to troubleshoot your app. Before you run these commands, make sure to replace the placeholders surrounded by `<>` with your own values.
227242

228243
```bash
229244
# View logs
@@ -256,11 +271,15 @@ Common issues include:
256271

257272
## Optimizing Java Containers
258273

259-
TODO
274+
Java applications in containers require special consideration for optimal performance. The JVM was designed before containers were common, which can lead to resource allocation issues if not properly configured.
275+
276+
By fine-tuning memory settings, optimizing image size, and configuring garbage collection, you can significantly improve the performance and efficiency of your containerized Java applications. This section covers essential optimizations for Java containers with a focus on memory management, startup time, and resource utilization.
260277

261278
### JVM Memory Configuration in Containers
262279

263-
The JVM doesn't automatically detect container memory limits in Java 8. For Java 9+, container awareness is enabled by default. Configure your JVM to respect container limits:
280+
The JVM doesn't automatically detect container memory limits in Java 8. For Java 9+, container awareness is enabled by default.
281+
282+
Configure your JVM to respect container limits:
264283

265284
```dockerfile
266285
FROM mcr.microsoft.com/java/jre:11-zulu-ubuntu
@@ -279,49 +298,44 @@ Key JVM flags for containerized applications:
279298

280299
## Prepare for production deployment
281300

282-
TODO
301+
Moving containerized Java applications to production requires additional considerations beyond basic functionality.
302+
303+
Production environments demand robust security, reliable monitoring, proper resource allocation, and configuration flexibility.
304+
305+
This section covers the essential practices and configurations needed to prepare your Java containers for production use, with a focus on security, health checks, and configuration management to ensure your applications run reliably in production.
283306

284307
### Security best practices
285308

286309
Secure your containerized Java applications with these practices:
287310

288-
1. Run as nonroot user:
311+
- **Default security context**: Run as non-root user:
289312

290-
```dockerfile
291-
FROM mcr.microsoft.com/java/jre:11-zulu-ubuntu
292-
WORKDIR /app
293-
COPY target/*.jar app.jar
294-
RUN addgroup --system javauser && adduser --system --ingroup javauser javauser
295-
USER javauser
296-
ENTRYPOINT ["java", "-jar", "app.jar"]
297-
```
313+
```dockerfile
314+
FROM mcr.microsoft.com/java/jre:11-zulu-ubuntu
315+
WORKDIR /app
316+
COPY target/*.jar app.jar
317+
RUN addgroup --system javauser && adduser --system --ingroup javauser javauser
318+
USER javauser
319+
ENTRYPOINT ["java", "-jar", "app.jar"]
320+
```
298321

299-
1. Scan images for vulnerabilities:
322+
- **Proactively look for issues**: Scan images for vulnerabilities:
300323

301-
```bash
302-
docker scan myapp:latest
303-
```
324+
```bash
325+
docker scan myapp:latest
326+
```
304327

305-
1. Use up-to-date base images
328+
- **Base image freshness**: Use up-to-date base images.
306329

307-
1. Implement proper secrets management (don't hardcode sensitive data)
330+
- **Secrets management**: Implement proper secrets management (don't hardcode sensitive data)
308331
309-
1. Apply the principle of least privilege
332+
- **Restricted security contexts**: Apply the principle of least privilege
310333
311-
1. Use read-only file systems where possible
334+
- **File system access**: Use read-only file systems where possible
312335
313-
### Health Checks and Monitoring
336+
### Health checks and monitoring
314337
315-
Implement health checks to ensure your application is running correctly:
316-
317-
```dockerfile
318-
FROM mcr.microsoft.com/java/jre:11-zulu-ubuntu
319-
WORKDIR /app
320-
COPY target/*.jar app.jar
321-
EXPOSE 8080
322-
HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost:8080/health || exit 1
323-
ENTRYPOINT ["java", "-jar", "app.jar"]
324-
```
338+
Check application health with [probes](health-probes.md) to ensure your application is running correctly.
325339
326340
For Spring Boot applications, include the Actuator dependency for comprehensive health endpoints:
327341
@@ -332,56 +346,31 @@ For Spring Boot applications, include the Actuator dependency for comprehensive
332346
</dependency>
333347
```
334348
335-
Configure your application to output logs in a format suitable for container environments (JSON format works well).
336-
337-
### Configuration management
338-
339-
Use environment variables for configuration rather than hardcoding values:
340-
341-
```dockerfile
342-
FROM mcr.microsoft.com/java/jre:11-zulu-ubuntu
343-
WORKDIR /app
344-
COPY target/*.jar app.jar
345-
EXPOSE 8080
346-
ENV JAVA_OPTS=""
347-
ENV SPRING_PROFILES_ACTIVE="prod"
348-
ENTRYPOINT java $JAVA_OPTS -jar app.jar
349-
```
350-
351-
Pass configuration settings when running:
352-
353-
```bash
354-
docker run -p 8080:8080 \
355-
-e "SPRING_PROFILES_ACTIVE=prod" \
356-
-e "DB_HOST=my-db-host" \
357-
myapp:latest
358-
```
359-
360-
For more complex configurations, consider using Azure App Configuration or environment variable mapping in Azure Container Apps.
349+
Configure your application to output logs in a format (like JSON) suitable for container environments.
361350
362351
## Deploying to Azure Container Apps
363352
364-
TODO
353+
This section guides you through preparing your Java containers for Azure Container Apps deployment and highlights key configuration considerations.
365354
366355
### Preparing Your Container for Azure
367356
368-
1. Ensure your container listens on the port provided by Azure:
357+
- **Port configuration**: Ensure your container listens on the port provided by Azure:
369358
370-
```dockerfile
371-
FROM mcr.microsoft.com/java/jre:11-zulu-ubuntu
372-
WORKDIR /app
373-
COPY target/*.jar app.jar
374-
ENV PORT=8080
375-
EXPOSE ${PORT}
376-
CMD java -jar app.jar --server.port=${PORT}
377-
```
359+
```dockerfile
360+
FROM mcr.microsoft.com/java/jre:11-zulu-ubuntu
361+
WORKDIR /app
362+
COPY target/*.jar app.jar
363+
ENV PORT=8080
364+
EXPOSE ${PORT}
365+
CMD java -jar app.jar --server.port=${PORT}
366+
```
378367
379-
1. Implement health probes for Azure's liveness and readiness checks
368+
1. **Probe for health**: Implement health probes for Azure's liveness and readiness checks
380369

381-
1. Configure logging to output to `stdout`/`stderr`
370+
1. **Log configuration**: Configure logging to output to `stdout`/`stderr`
382371

383-
1. Set up proper graceful shutdown handling with time out configuration
372+
1. **Plan for the unexpected**: Set up proper graceful shutdown handling with time out configuration
384373

385374
## Related content
386375

387-
TODO
376+
- [Java on Container Apps overview](./java-overview.md)

0 commit comments

Comments
 (0)