diff --git a/content/manuals/dhi/migration/examples/_index.md b/content/manuals/dhi/migration/examples/_index.md index a1f86e2cfaa..fb35a8c58d3 100644 --- a/content/manuals/dhi/migration/examples/_index.md +++ b/content/manuals/dhi/migration/examples/_index.md @@ -17,6 +17,14 @@ params: description: Learn how to migrate Node.js applications to Docker Hardened Images with practical examples and best practices. icon: code-bracket link: /dhi/migration/examples/node/ + - title: .NET + description: Learn how to migrate .NET applications to Docker Hardened Images with practical examples and best practices. + icon: code-bracket + link: /dhi/migration/examples/dotnet/ + - title: Java + description: Learn how to migrate Java applications to Docker Hardened Images with practical examples and best practices. + icon: code-bracket + link: /dhi/migration/examples/java/ --- This section provides detailed migration examples for common programming languages and frameworks. diff --git a/content/manuals/dhi/migration/examples/dotnet.md b/content/manuals/dhi/migration/examples/dotnet.md new file mode 100644 index 00000000000..0f2f9716f52 --- /dev/null +++ b/content/manuals/dhi/migration/examples/dotnet.md @@ -0,0 +1,134 @@ +--- +title: .NET +description: Migrate a .NET application to Docker Hardened Images +weight: 40 +keywords: dotnet, .net, csharp, aspnet, migration, dhi +--- + +> **Acknowledgment** +> +> Docker would like to thank [Naga Santhosh Reddy Vootukuri](https://github.com/sunnynagavo) for his contribution to this guide. + +This example shows how to migrate a .NET application to Docker Hardened Images. + +The following examples show Dockerfiles before and after migration to Docker +Hardened Images. Each example includes four variations: + +- Before (Wolfi): A sample Dockerfile using Wolfi distribution images, before migrating to DHI +- Before (DOI): A sample Dockerfile using Docker Official Images, before migrating to DHI +- After (multi-stage): A sample Dockerfile after migrating to DHI with multi-stage builds (recommended for minimal, secure images) +- After (single-stage): A sample Dockerfile after migrating to DHI with single-stage builds (simpler but results in a larger image with a broader attack surface) + +> [!NOTE] +> +> Multi-stage builds are recommended for most use cases. Single-stage builds are +> supported for simplicity, but come with tradeoffs in size and security. +> +> You must authenticate to `dhi.io` before you can pull Docker Hardened Images. +> Use your Docker ID credentials (the same username and password you use for +> Docker Hub). If you don't have a Docker account, [create +> one](../../../accounts/create-account.md) for free. +> +> Run `docker login dhi.io` to authenticate. + +{{< tabs >}} +{{< tab name="Before (Wolfi)" >}} + +```dockerfile +#syntax=docker/dockerfile:1 + +FROM cgr.dev/chainguard/dotnet-sdk:latest-dev AS builder + +WORKDIR /src +COPY . ./ + +# Install any additional packages if needed using apk +# RUN apk add --no-cache git + +RUN dotnet restore +RUN dotnet publish -c Release -o /src/out --no-restore + +FROM cgr.dev/chainguard/aspnet-runtime:latest + +WORKDIR /app +COPY --from=builder /src/out ./ + +ENTRYPOINT ["dotnet", "app.dll"] +``` + +{{< /tab >}} +{{< tab name="Before (DOI)" >}} + +```dockerfile +#syntax=docker/dockerfile:1 + +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS builder + +WORKDIR /src +COPY . ./ + +# Install any additional packages if needed using apt +# RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/* + +RUN dotnet restore +RUN dotnet publish -c Release -o /app --no-restore + +FROM mcr.microsoft.com/dotnet/aspnet:8.0 + +WORKDIR /app +COPY --from=builder /app ./ + +ENTRYPOINT ["dotnet", "app.dll"] +``` + +{{< /tab >}} +{{< tab name="After (multi-stage)" >}} + +```dockerfile +#syntax=docker/dockerfile:1 + +# === Build stage: Restore, build, and publish the .NET application === +FROM dhi.io/dotnet:8-sdk-alpine3.22 AS builder + +WORKDIR /src +COPY . ./ + +# Install any additional packages if needed using apk +# RUN apk add --no-cache git + +RUN dotnet restore +RUN dotnet publish -c Release -o /app --no-restore + +# === Final stage: Create minimal runtime image === +FROM dhi.io/aspnetcore:8-alpine3.22 + +WORKDIR /app +COPY --from=builder /app ./ + +ENTRYPOINT ["dotnet", "app.dll"] +``` + +{{< /tab >}} +{{< tab name="After (single-stage)" >}} + +```dockerfile +#syntax=docker/dockerfile:1 + +FROM dhi.io/dotnet:8-sdk-alpine3.22 + +WORKDIR /src +COPY . ./ + +# Install any additional packages if needed using apk +# RUN apk add --no-cache git + +RUN dotnet restore +RUN dotnet publish -c Release -o /app --no-restore + +WORKDIR /app + +ENTRYPOINT ["dotnet", "/app/app.dll"] +``` + +{{< /tab >}} +{{< /tabs >}} diff --git a/content/manuals/dhi/migration/examples/java.md b/content/manuals/dhi/migration/examples/java.md new file mode 100644 index 00000000000..e6ab388b359 --- /dev/null +++ b/content/manuals/dhi/migration/examples/java.md @@ -0,0 +1,154 @@ +--- +title: Java +description: Migrate a Java application to Docker Hardened Images +weight: 50 +keywords: java, jvm, jdk, jre, maven, migration, dhi +--- + +> **Acknowledgment** +> +> Docker would like to thank [Naga Santhosh Reddy Vootukuri](https://github.com/sunnynagavo) for his contribution to this guide. + +This example shows how to migrate a Java application to Docker Hardened Images. + +The following examples show Dockerfiles before and after migration to Docker +Hardened Images. Each example includes five variations: + +- Before (Ubuntu): A sample Dockerfile using Ubuntu-based images, before migrating to DHI +- Before (Wolfi): A sample Dockerfile using Wolfi distribution images, before migrating to DHI +- Before (DOI): A sample Dockerfile using Docker Official Images, before migrating to DHI +- After (multi-stage): A sample Dockerfile after migrating to DHI with multi-stage builds (recommended for minimal, secure images) +- After (single-stage): A sample Dockerfile after migrating to DHI with single-stage builds (simpler but results in a larger image with a broader attack surface) + +> [!NOTE] +> +> Multi-stage builds are recommended for most use cases. Single-stage builds are +> supported for simplicity, but come with tradeoffs in size and security. +> +> You must authenticate to `dhi.io` before you can pull Docker Hardened Images. +> Use your Docker ID credentials (the same username and password you use for +> Docker Hub). If you don't have a Docker account, [create +> one](../../../accounts/create-account.md) for free. +> +> Run `docker login dhi.io` to authenticate. + +{{< tabs >}} +{{< tab name="Before (Ubuntu)" >}} + +```dockerfile +#syntax=docker/dockerfile:1 + +FROM ubuntu:24.04 AS builder + +WORKDIR /app +COPY . ./ + +RUN apt-get update && apt-get install -y default-jdk maven --no-install-recommends && rm -rf /var/lib/apt/lists/* + +RUN mvn -B package -DskipTests + +FROM ubuntu:24.04 + +RUN apt-get update && apt-get install -y default-jre --no-install-recommends && rm -rf /var/lib/apt/lists/* + +WORKDIR /app +COPY --from=builder /app/target/app.jar /app/app.jar + +ENTRYPOINT ["java", "-jar", "/app/app.jar"] +``` + +{{< /tab >}} +{{< tab name="Before (Wolfi)" >}} + +```dockerfile +#syntax=docker/dockerfile:1 + +FROM cgr.dev/chainguard/maven:latest-dev AS builder + +WORKDIR /app +COPY . ./ + +# Install any additional packages if needed using apk +# RUN apk add --no-cache git + +RUN mvn -B package -DskipTests + +FROM cgr.dev/chainguard/jre:latest + +WORKDIR /app +COPY --from=builder /app/target/app.jar /app/app.jar + +ENTRYPOINT ["java", "-jar", "/app/app.jar"] +``` + +{{< /tab >}} +{{< tab name="Before (DOI)" >}} + +```dockerfile +#syntax=docker/dockerfile:1 + +FROM maven:3.9-eclipse-temurin-21 AS builder + +WORKDIR /app +COPY . ./ + +# Install any additional packages if needed using apt +# RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/* + +RUN mvn -B package -DskipTests + +FROM eclipse-temurin:21-jre + +WORKDIR /app +COPY --from=builder /app/target/app.jar /app/app.jar + +ENTRYPOINT ["java", "-jar", "/app/app.jar"] +``` + +{{< /tab >}} +{{< tab name="After (multi-stage)" >}} + +```dockerfile +#syntax=docker/dockerfile:1 + +# === Build stage: Compile and package the Java application with Maven === +FROM dhi.io/maven:3-jdk21-alpine3.22-dev AS builder + +WORKDIR /app +COPY . ./ + +# Install any additional packages if needed using apk +# RUN apk add --no-cache git + +RUN mvn -B package -DskipTests + +# === Final stage: Create minimal runtime image === +FROM dhi.io/eclipse-temurin:21-alpine3.22 + +WORKDIR /app +COPY --from=builder /app/target/app.jar /app/app.jar + +ENTRYPOINT ["java", "-jar", "/app/app.jar"] +``` + +{{< /tab >}} +{{< tab name="After (single-stage)" >}} + +```dockerfile +#syntax=docker/dockerfile:1 + +FROM dhi.io/maven:3-jdk21-alpine3.22-dev + +WORKDIR /app +COPY . ./ + +# Install any additional packages if needed using apk +# RUN apk add --no-cache git + +RUN mvn -B package -DskipTests + +ENTRYPOINT ["java", "-jar", "/app/target/app.jar"] +``` + +{{< /tab >}} +{{< /tabs >}}