Skip to content

Commit 9374bb9

Browse files
authored
Update containerisation related docs and solutions (microsoft#40)
1 parent 4c1d230 commit 9374bb9

4 files changed

Lines changed: 90 additions & 41 deletions

File tree

‎complete/Dockerfile.dotnet‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ EXPOSE 8080
2525
# Set the environment variables
2626
ENV ASPNETCORE_URLS=http://+:8080
2727
ENV DOTNET_RUNNING_IN_CONTAINER=true
28+
ENV ApiSettings__BaseUrl="${ApiSettings__BaseUrl}"
2829

2930
# Copy the published files from the build stage
3031
COPY --from=publish /app/publish .
3132

3233
# Set the entry point for the container
33-
ENTRYPOINT ["dotnet", "Contoso.BlazorApp.dll"]
34+
ENTRYPOINT ["dotnet", "Contoso.BlazorApp.dll"]

‎complete/Dockerfile.java‎

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,90 @@
1-
# Stage 1: Build the application
2-
FROM mcr.microsoft.com/openjdk/jdk:21-ubuntu AS build
1+
# Multi-stage build for Java Spring Boot application
2+
# Stage 1: Build stage with Microsoft OpenJDK 21
3+
FROM mcr.microsoft.com/openjdk/jdk:21-ubuntu AS builder
34

4-
WORKDIR /app
5+
# Set working directory for build
6+
WORKDIR /workspace
57

6-
# Copy gradle files for dependency resolution
7-
COPY java/socialapp/gradle/ ./gradle/
8-
COPY java/socialapp/gradlew java/socialapp/build.gradle java/socialapp/settings.gradle ./
8+
# Copy Gradle configuration files
9+
COPY java/socialapp/gradle ./gradle
10+
COPY java/socialapp/gradlew .
11+
COPY java/socialapp/gradlew.bat .
12+
COPY java/socialapp/build.gradle .
13+
COPY java/socialapp/settings.gradle .
914

10-
# Give executable permissions to gradlew
15+
# Make gradlew executable
1116
RUN chmod +x ./gradlew
1217

13-
# Download dependencies to cache this layer
18+
# Download dependencies (for better Docker layer caching)
1419
RUN ./gradlew dependencies --no-daemon
1520

1621
# Copy source code
1722
COPY java/socialapp/src ./src
1823

1924
# Build the application
20-
RUN ./gradlew bootJar --no-daemon
25+
RUN ./gradlew build --no-daemon -x test
2126

2227
# Stage 2: Extract JRE from JDK
23-
FROM mcr.microsoft.com/openjdk/jdk:21-ubuntu AS jre-build
28+
FROM mcr.microsoft.com/openjdk/jdk:21-ubuntu AS jre-builder
2429

25-
# Create a custom JRE using jlink that only includes modules needed for the application
30+
# Create a custom JRE using jlink
2631
RUN jlink \
27-
--add-modules java.base,java.compiler,java.desktop,java.instrument,java.management,java.naming,java.prefs,java.rmi,java.security.jgss,java.security.sasl,java.sql,jdk.crypto.ec,jdk.unsupported,jdk.zipfs,jdk.management \
32+
--add-modules java.base,java.desktop,java.instrument,java.management,java.naming,java.net.http,java.security.jgss,java.sql,jdk.unsupported \
2833
--strip-debug \
2934
--no-man-pages \
3035
--no-header-files \
3136
--compress=2 \
32-
--output /jre-minimal
37+
--output /custom-jre
3338

34-
# Stage 3: Create final image
39+
# Stage 3: Runtime stage with custom JRE
3540
FROM ubuntu:22.04
3641

37-
# Set environment variables
38-
ENV JAVA_HOME=/opt/jre-minimal
42+
# Install required packages and clean up
43+
RUN apt-get update && \
44+
apt-get install -y \
45+
ca-certificates \
46+
sqlite3 \
47+
curl \
48+
&& apt-get clean \
49+
&& rm -rf /var/lib/apt/lists/*
50+
51+
# Copy custom JRE from jre-builder stage
52+
COPY --from=jre-builder /custom-jre /opt/java/openjdk
53+
54+
# Set JAVA_HOME and update PATH
55+
ENV JAVA_HOME=/opt/java/openjdk
3956
ENV PATH="${JAVA_HOME}/bin:${PATH}"
4057

41-
# Copy the extracted JRE from the jre-build stage
42-
COPY --from=jre-build /jre-minimal $JAVA_HOME
58+
# Create application user for security
59+
RUN groupadd -r appuser && useradd -r -g appuser appuser
4360

44-
# Copy the built application from the build stage
61+
# Set working directory
4562
WORKDIR /app
46-
COPY --from=build /app/build/libs/*.jar app.jar
4763

48-
# Create a directory for persistent data
49-
RUN mkdir -p /app/data
64+
# Copy the built JAR from builder stage
65+
COPY --from=builder /workspace/build/libs/*.jar app.jar
66+
67+
# Create SQLite database file with proper permissions
68+
RUN touch sns_api.db && \
69+
chown appuser:appuser sns_api.db && \
70+
chmod 664 sns_api.db
5071

51-
# Expose the application port
72+
# Change ownership of the app directory
73+
RUN chown -R appuser:appuser /app
74+
75+
# Switch to non-root user
76+
USER appuser
77+
78+
# Set environment variables for GitHub Codespaces
79+
ENV CODESPACE_NAME="${CODESPACE_NAME}"
80+
ENV GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN="${GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN}"
81+
82+
# Expose port 8080
5283
EXPOSE 8080
5384

54-
# Set the entrypoint command to run the application
55-
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
85+
# Health check
86+
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
87+
CMD curl -f http://localhost:8080/actuator/health || exit 1
88+
89+
# Run the application
90+
ENTRYPOINT ["java", "-jar", "app.jar"]

‎complete/compose.yaml‎

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
version: '3.8'
2+
3+
networks:
4+
contoso:
5+
driver: bridge
6+
17
services:
28
contoso-backend:
39
build:
@@ -9,10 +15,14 @@ services:
915
environment:
1016
- CODESPACE_NAME=${CODESPACE_NAME}
1117
- GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN=${GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN}
12-
volumes:
13-
- ./java/socialapp/sns_api.db:/app/sns_api.db
1418
networks:
1519
- contoso
20+
healthcheck:
21+
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
22+
interval: 30s
23+
timeout: 3s
24+
start_period: 60s
25+
retries: 3
1626

1727
contoso-frontend:
1828
build:
@@ -21,13 +31,9 @@ services:
2131
container_name: contoso-frontend
2232
ports:
2333
- "3030:8080"
24-
depends_on:
25-
- contoso-backend
2634
environment:
27-
- ApiSettings__BaseUrl=http://contoso-backend:8080/api/
35+
- ApiSettings__BaseUrl=http://contoso-backend:8080/api
2836
networks:
2937
- contoso
30-
31-
networks:
32-
contoso:
33-
name: contoso
38+
depends_on:
39+
- contoso-backend

‎docs/05-containerization.md‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,16 @@ Refer to the [README](../README.md) doc for preparation.
7070
```text
7171
I'd like to build a container image of a Java app. Follow the instructions below.
7272

73-
- The Java app is located at `java`.
74-
- Your working directory is the repository root.
7573
- Identify all the steps first, which you're going to do.
74+
- The Java app is located at `java/socialapp`.
75+
- Your working directory is the repository root.
7676
- Create a Dockerfile, `Dockerfile.java`.
7777
- Use Microsoft OpenJDK 21.
7878
- Use multi-stage build approach.
7979
- Extract JRE from JDK.
8080
- Use the target port number of `8080` for the container image.
81+
- Add both environment variables, `CODESPACE_NAME` and `GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN` from the host to the container image.
82+
- Create an SQLite database file, `sns_api.db`, in the container image. DO NOT Copy the file from the host.
8183
```
8284
8385
1. Click the ![the keep button image](https://img.shields.io/badge/keep-blue) button of GitHub Copilot to take the changes.
@@ -101,6 +103,7 @@ Refer to the [README](../README.md) doc for preparation.
101103
Use the container image just built, run a container and verify if the app is running properly.
102104
103105
- Use the host port of `8080`.
106+
- Both `CODESPACE_NAME` and `GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN` values should be the ones from GitHub Codespaces.
104107
```
105108
106109
### Containerize .NET Application
@@ -111,13 +114,14 @@ Refer to the [README](../README.md) doc for preparation.
111114
```text
112115
I'd like to build a container image of a .NET app. Follow the instructions below.
113116
117+
- Identify all the steps first, which you're going to do.
114118
- The .NET app is located at `dotnet`.
115119
- Your working directory is the repository root.
116-
- Identify all the steps first, which you're going to do.
117120
- Create a Dockerfile, `Dockerfile.dotnet`.
118121
- Use .NET 9.
119122
- Use multi-stage build approach.
120123
- Use the target port number of `8080` for the container image.
124+
- Add the environment variable, `ApiSettings__BaseUrl` to the container. It should point to the Java app, `http://localhost:8080/api`.
121125
```
122126

123127
1. Click the ![the keep button image](https://img.shields.io/badge/keep-blue) button of GitHub Copilot to take the changes.
@@ -141,12 +145,13 @@ Refer to the [README](../README.md) doc for preparation.
141145
Use the container image just built, run a container and verify if the app is running properly.
142146
143147
- Use the host port of `3030`.
148+
- Pass the environment variable `ApiSettings__BaseUrl` the value of `http://localhost:8080/api`.
144149
```
145150
146151
1. Make sure that both frontend and backend apps are NOT communicating with each other because they don't know each other yet. Run the prompt like below.
147152
148153
```text
149-
Regardless or not, remove both containers currently running.
154+
Remove both Java and .NET containers and their respective container images.
150155
```
151156
152157
### Orchestrate Containers
@@ -157,22 +162,24 @@ Refer to the [README](../README.md) doc for preparation.
157162
```text
158163
I'd like to create a Docker Compose file. Follow the instructions below.
159164
165+
- Identify all the steps first, which you're going to do.
160166
- Your working directory is the repository root.
161167
- Use `Dockerfile.java` as a backend app.
162168
- Use `Dockerfile.dotnet` as a frontend app.
163169
- Create `compose.yaml` as the Docker Compose file.
164170
- Use `contoso` as the network name.
165171
- Use `contoso-backend` as the container name of the Java app. Its target port is 8080, and host port is 8080.
166172
- Use `contoso-frontend` as the container name of the .NET app. Its target port is 8080, and host port is 3030.
167-
- Mount the volume for the database that the Java app uses, `java/socialapp/sns_api.db`.
173+
- Add both environment variables, `CODESPACE_NAME` and `GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN` from the host to the Java container.
174+
- Add the environment variable, `ApiSettings__BaseUrl` to the .NET container. It should point to the Java app's `/api`.
168175
```
169176
170177
1. Click the ![the keep button image](https://img.shields.io/badge/keep-blue) button of GitHub Copilot to take the changes.
171178
172179
1. Once the `compose.yaml` file is created, run it and verify if both apps are running properly.
173180
174181
```text
175-
Now, run the Docker compose file and verify if the apps are running properly.
182+
Run the Docker compose file and verify if all the apps are running properly.
176183
```
177184
178185
1. Open a web browser and navigate to `http://localhost:3030`, and verify if the apps are up and running properly.

0 commit comments

Comments
 (0)