You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -107,10 +107,10 @@ Choosing the right base image is crucial. Consider these options:
107
107
108
108
| Description | Name | Remarks |
109
109
|---|---|---|
110
-
|**Microsoft Java development Image**|`mcr.microsoft.com/java/jdk:11-zulu-ubuntu`| Full Java development kit (JDK) and optimized for Azure |
111
-
|**Microsoft Java production Image**|`mcr.microsoft.com/java/jre:11-zulu-ubuntu`| Runtime only and optimized for Azure |
112
-
|**Official OpenJDK development Image**|`openjdk:11-jdk`| Full JDK |
113
-
|**Official OpenJDK production Image**|`openjdk:11-jre`| Runtime only |
110
+
|**Microsoft Java development Image**|`mcr.microsoft.com/java/jdk:21-zulu-ubuntu`| Full Java development kit (JDK) and optimized for Azure |
111
+
|**Microsoft Java production Image**|`mcr.microsoft.com/java/jre:21-zulu-ubuntu`| Runtime only and optimized for Azure |
112
+
|**Official OpenJDK development Image**|`openjdk:21-jdk`| Full JDK |
113
+
|**Official OpenJDK production Image**|`openjdk:21-jre`| Runtime only |
114
114
115
115
For development environments, use a full JDK image. For production, use JRE or distroless images to minimize size and attack surface of your application.
116
116
@@ -121,7 +121,7 @@ The Microsoft Java images come with Azure-specific optimizations and are regular
121
121
The following example shows a simple Dockerfile for a Java application:
For production deployments, use the JRE image to reduce the size and minimize the attack surface of your application:
142
142
143
143
```dockerfile
144
-
FROM mcr.microsoft.com/java/jre:11-zulu-ubuntu
144
+
FROM mcr.microsoft.com/java/jre:21-zulu-ubuntu
145
145
WORKDIR /app
146
146
COPY target/*.jar app.jar
147
147
EXPOSE 8080
@@ -155,27 +155,39 @@ Containers are meant to execute in various contexts. In this section, you learn
155
155
156
156
### Use Docker Compose for multi-container applications
157
157
158
-
Most Java applications interact with databases, caches, or other services.
158
+
Most Java applications interact with databases, caches, or other services. Docker Compose helps you define and orchestrate multi-container applications using a simple YAML configuration file.
159
159
160
-
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.
160
+
#### What is Docker Compose?
161
161
162
-
The following example demonstrates how to configure Docker Compose to prepare a database connection to your application.
162
+
Docker Compose is a tool that:
163
+
- Defines multi-container applications in a single file
> Docker Compose is now integrated as a plugin to the Docker command itself (using `docker compose`) rather than as a separate utility. The preferred configuration filename is `compose.yml` instead of the legacy `docker-compose.yml`.
171
+
172
+
#### Example: Java application with database
173
+
174
+
Here's an example `compose.yml` that configures a Java application with a PostgreSQL database:
163
175
164
176
```yaml
165
177
version: '3.8'
166
178
services:
167
179
app:
168
-
build: .
180
+
build: .# Build from Dockerfile in current directory
- ./target:/app/target# Mount target directory for hot reloads
177
189
depends_on:
178
-
- db
190
+
- db# Ensure database starts first
179
191
180
192
db:
181
193
image: postgres:13
@@ -184,15 +196,84 @@ services:
184
196
- POSTGRES_PASSWORD=postgres
185
197
- POSTGRES_DB=myapp
186
198
ports:
187
-
- "5432:5432"
199
+
- "5432:5432"# Expose PostgreSQL port
188
200
volumes:
189
-
- postgres-data:/var/lib/postgresql/data
201
+
- postgres-data:/var/lib/postgresql/data# Persist database data
190
202
191
203
volumes:
192
-
postgres-data:
204
+
postgres-data:# Named volume for database persistence
193
205
```
194
206
195
-
This configuration creates two containers: one for the Java application and one for a PostgreSQL database. It also sets up networking between them, mounts volumes for persistence, and exposes necessary ports.
207
+
In this example:
208
+
209
+
- Services can reference each other by name (like `db` in the JDBC URL)
210
+
- Docker Compose automatically creates a network for the services
211
+
- The Java application waits for the database to start due to `depends_on`
212
+
- The database data persists across restarts using a named volume
213
+
214
+
#### Common Docker Compose commands
215
+
216
+
Once you've created your `compose.yml` file, manage your application with these commands:
217
+
218
+
```bash
219
+
# Build images without starting containers
220
+
docker compose build
221
+
222
+
# Start all services defined in compose.yml
223
+
docker compose up
224
+
225
+
# Start in detached mode (run in background)
226
+
docker compose up -d
227
+
228
+
# View running containers managed by compose
229
+
docker compose ps
230
+
231
+
# View logs from all containers
232
+
docker compose logs
233
+
234
+
# View logs from a specific service
235
+
docker compose logs app
236
+
237
+
# Stop all services
238
+
docker compose down
239
+
240
+
# Stop and remove volumes (useful for database resets)
241
+
docker compose down -v
242
+
```
243
+
244
+
#### Development workflow
245
+
246
+
A typical Java development workflow with Docker Compose looks like:
247
+
248
+
1. Create `compose.yml` and `Dockerfile`
249
+
2. Run `docker compose up` to start all services
250
+
3. Make changes to your Java code
251
+
4. Rebuild your application (depending on configuration, you might need to restart containers)
252
+
5. Test the changes in the containerized environment
253
+
6. When finished, run `docker compose down`
254
+
255
+
### Running single containers with Docker
256
+
257
+
For simpler scenarios when you don't need multiple interconnected services, you can use the `docker run` command to start individual containers.
258
+
259
+
Here are some common examples for Java applications:
260
+
261
+
```bash
262
+
# Run a Java application JAR directly
263
+
docker run -p 8080:8080 myapp:latest
264
+
265
+
# Run with environment variables
266
+
docker run -p 8080:8080 -e "SPRING_PROFILES_ACTIVE=prod" myapp:latest
267
+
268
+
# Run in detached mode (background)
269
+
docker run -d -p 8080:8080 myapp:latest
270
+
271
+
# Run with a name for easy reference
272
+
docker run -d -p 8080:8080 --name my-java-app myapp:latest
273
+
274
+
# Run with volume mount for persistent data
275
+
docker run -p 8080:8080 -v ./data:/app/data myapp:latest
276
+
```
196
277
197
278
## Debugging containerized applications
198
279
@@ -207,7 +288,7 @@ Debugging containerized Java applications requires exposing a debug port and con
207
288
1. To enable debugging, modify your Dockerfile or container startup command:
208
289
209
290
```dockerfile
210
-
FROM mcr.microsoft.com/java/jdk:11-zulu-ubuntu
291
+
FROM mcr.microsoft.com/java/jdk:21-zulu-ubuntu
211
292
WORKDIR /app
212
293
COPY target/*.jar app.jar
213
294
EXPOSE 8080 5005
@@ -283,16 +364,15 @@ The JVM doesn't automatically detect container memory limits in Java 8. For Java
0 commit comments