Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions content/manuals/dhi/migration/examples/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
134 changes: 134 additions & 0 deletions content/manuals/dhi/migration/examples/dotnet.md
Original file line number Diff line number Diff line change
@@ -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 >}}
154 changes: 154 additions & 0 deletions content/manuals/dhi/migration/examples/java.md
Original file line number Diff line number Diff line change
@@ -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 >}}