Skip to content

Commit d1c7777

Browse files
dhi: add ubuntu migration (#23963)
<!--Delete sections as needed --> ## Description Added general Ubuntu to Debian DHI migration. - https://deploy-preview-23963--docsdocker.netlify.app/dhi/migration/migrate-from-ubuntu/ - https://deploy-preview-23963--docsdocker.netlify.app/dhi/migration/examples/go/ - https://deploy-preview-23963--docsdocker.netlify.app/dhi/migration/examples/python/ - https://deploy-preview-23963--docsdocker.netlify.app/dhi/migration/examples/node/ The tabbed comparison in the language examples is getting a bit wonky, although still correct. A lot of tabs, and it randomly picks alpine/debian as the final dhi image, whereas wolfi is probably going to alpine and ubuntu is probably going to debian. Will look at this in a followup. ## Related issues or tickets ENGDOCS-3142 ## Reviews <!-- Notes for reviewers here --> <!-- List applicable reviews (optionally @tag reviewers) --> - [ ] Technical review - [ ] Editorial review - [ ] Product review --------- Signed-off-by: Craig Osterhout <craig.osterhout@docker.com>
1 parent 3355f97 commit d1c7777

5 files changed

Lines changed: 220 additions & 3 deletions

File tree

content/manuals/dhi/migration/_index.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ params:
1515
description: Manual migration guide for moving from Docker Official Images (Alpine or Debian-based) to Docker Hardened Images.
1616
icon: code
1717
link: /dhi/migration/migrate-from-doi/
18+
- title: Migrate from Ubuntu
19+
description: Manual migration guide for transitioning from Ubuntu-based images to Docker Hardened Images.
20+
icon: upgrade
21+
link: /dhi/migration/migrate-from-ubuntu/
1822
- title: Migrate from Wolfi
1923
description: Manual migration guide for transitioning from Wolfi-based images to Docker Hardened Images.
2024
icon: transform

content/manuals/dhi/migration/examples/go.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ keywords: go, golang, migration, dhi
88
This example shows how to migrate a Go application to Docker Hardened Images.
99

1010
The following examples show Dockerfiles before and after migration to Docker
11-
Hardened Images. Each example includes four variations:
11+
Hardened Images. Each example includes five variations:
1212

13+
- Before (Ubuntu): A sample Dockerfile using Ubuntu-based images, before migrating to DHI
1314
- Before (Wolfi): A sample Dockerfile using Wolfi distribution images, before migrating to DHI
1415
- Before (DOI): A sample Dockerfile using Docker Official Images, before migrating to DHI
1516
- After (multi-stage): A sample Dockerfile after migrating to DHI with multi-stage builds (recommended for minimal, secure images)
@@ -28,6 +29,25 @@ Hardened Images. Each example includes four variations:
2829
> Run `docker login dhi.io` to authenticate.
2930
3031
{{< tabs >}}
32+
{{< tab name="Before (Ubuntu)" >}}
33+
34+
```dockerfile
35+
#syntax=docker/dockerfile:1
36+
37+
FROM ubuntu/go:1.22-24.04
38+
39+
WORKDIR /app
40+
ADD . ./
41+
42+
# Install any additional packages if needed using apt
43+
# RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
44+
45+
RUN CGO_ENABLED=0 GOOS=linux go build -a -ldflags="-s -w" --installsuffix cgo -o main .
46+
47+
ENTRYPOINT ["/app/main"]
48+
```
49+
50+
{{< /tab >}}
3151
{{< tab name="Before (Wolfi)" >}}
3252

3353
```dockerfile

content/manuals/dhi/migration/examples/node.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ keywords: nodejs, node, migration, dhi
88
This example shows how to migrate a Node.js application to Docker Hardened Images.
99

1010
The following examples show Dockerfiles before and after migration to Docker
11-
Hardened Images. Each example includes four variations:
11+
Hardened Images. Each example includes five variations:
1212

13+
- Before (Ubuntu): A sample Dockerfile using Ubuntu-based images, before migrating to DHI
1314
- Before (Wolfi): A sample Dockerfile using Wolfi distribution images, before migrating to DHI
1415
- Before (DOI): A sample Dockerfile using Docker Official Images, before migrating to DHI
1516
- After (multi-stage): A sample Dockerfile after migrating to DHI with multi-stage builds (recommended for minimal, secure images)
@@ -28,6 +29,24 @@ Hardened Images. Each example includes four variations:
2829
> Run `docker login dhi.io` to authenticate.
2930
3031
{{< tabs >}}
32+
{{< tab name="Before (Ubuntu)" >}}
33+
34+
```dockerfile
35+
#syntax=docker/dockerfile:1
36+
37+
FROM ubuntu/node:18-24.04_edge
38+
WORKDIR /usr/src/app
39+
40+
COPY package*.json ./
41+
42+
RUN npm install
43+
44+
COPY . .
45+
46+
CMD ["node", "index.js"]
47+
```
48+
49+
{{< /tab >}}
3150
{{< tab name="Before (Wolfi)" >}}
3251

3352
```dockerfile

content/manuals/dhi/migration/examples/python.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ keywords: python, migration, dhi
88
This example shows how to migrate a Python application to Docker Hardened Images.
99

1010
The following examples show Dockerfiles before and after migration to Docker
11-
Hardened Images. Each example includes four variations:
11+
Hardened Images. Each example includes five variations:
1212

13+
- Before (Ubuntu): A sample Dockerfile using Ubuntu-based images, before migrating to DHI
1314
- Before (Wolfi): A sample Dockerfile using Wolfi distribution images, before migrating to DHI
1415
- Before (DOI): A sample Dockerfile using Docker Official Images, before migrating to DHI
1516
- After (multi-stage): A sample Dockerfile after migrating to DHI with multi-stage builds (recommended for minimal, secure images)
@@ -24,6 +25,39 @@ Hardened Images. Each example includes four variations:
2425
> Run `docker login dhi.io` to authenticate.
2526
2627
{{< tabs >}}
28+
{{< tab name="Before (Ubuntu)" >}}
29+
30+
```dockerfile
31+
#syntax=docker/dockerfile:1
32+
33+
FROM ubuntu/python:3.13-24.04_stable AS builder
34+
35+
ENV LANG=C.UTF-8
36+
ENV PYTHONDONTWRITEBYTECODE=1
37+
ENV PYTHONUNBUFFERED=1
38+
ENV PATH="/app/venv/bin:$PATH"
39+
40+
WORKDIR /app
41+
42+
RUN python -m venv /app/venv
43+
COPY requirements.txt .
44+
45+
RUN pip install --no-cache-dir -r requirements.txt
46+
47+
FROM ubuntu/python:3.13-24.04_stable
48+
49+
WORKDIR /app
50+
51+
ENV PYTHONUNBUFFERED=1
52+
ENV PATH="/app/venv/bin:$PATH"
53+
54+
COPY app.py ./
55+
COPY --from=builder /app/venv /app/venv
56+
57+
ENTRYPOINT [ "python", "/app/app.py" ]
58+
```
59+
60+
{{< /tab >}}
2761
{{< tab name="Before (Wolfi)" >}}
2862

2963
```dockerfile
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
---
2+
title: Migrate from Ubuntu
3+
description: Step-by-step guide to migrate from Ubuntu-based images to Docker Hardened Images
4+
weight: 25
5+
keywords: ubuntu, migration, dhi, debian, docker hardened images
6+
---
7+
8+
Docker Hardened Images (DHI) come in [Alpine-based and Debian-based
9+
variants](../explore/available.md). When migrating from an Ubuntu-based image,
10+
you should migrate to the Debian-based DHI variant, as both Ubuntu and Debian
11+
share the same package management system (APT) and underlying architecture,
12+
making migration straightforward.
13+
14+
This guide helps you migrate from an existing Ubuntu-based image to DHI.
15+
16+
## Key differences
17+
18+
When migrating from Ubuntu-based images to DHI Debian, be aware of these key differences:
19+
20+
| Item | Ubuntu-based images | Docker Hardened Images |
21+
|:-------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
22+
| Package management | Varies by image. Some include APT package manager, others don't | Package managers generally only available in images with a `dev` tag. Runtime images don't contain package managers. Use multi-stage builds and copy necessary artifacts from the build stage to the runtime stage. |
23+
| Non-root user | Varies by image. Some run as root, others as non-root | Runtime variants run as the non-root user by default. Ensure that necessary files and directories are accessible to the non-root user. |
24+
| Multi-stage build | Recommended | Recommended. Use images with a `dev` or `sdk` tags for build stages and non-dev images for runtime. |
25+
| Ports | Can bind to privileged ports (under 1024) when running as root | Run as a non-root user by default. Applications can't bind to privileged ports (under 1024) when running in Kubernetes or in Docker Engine versions older than 20.10. Configure your application to listen on port 1025 and up inside the container. |
26+
| Entry point | Varies by image | May have different entry points than Ubuntu-based images. Inspect entry points and update your Dockerfile if necessary. |
27+
| Shell | Varies by image. Some include a shell, others don't | Runtime images don't contain a shell. Use `dev` images in build stages to run shell commands and then copy artifacts to the runtime stage. |
28+
| Package repositories | Uses Ubuntu package repositories | Uses Debian package repositories. Most packages have similar names, but some may differ. |
29+
30+
## Migration steps
31+
32+
### Step 1: Update the base image in your Dockerfile
33+
34+
Update the base image in your application's Dockerfile to a hardened image. This
35+
is typically going to be an image tagged as `dev` or `sdk` because it has the tools
36+
needed to install packages and dependencies.
37+
38+
The following example diff snippet from a Dockerfile shows the old Ubuntu-based image
39+
replaced by the new DHI Debian image.
40+
41+
> [!NOTE]
42+
>
43+
> You must authenticate to `dhi.io` before you can pull Docker Hardened Images.
44+
> Use your Docker ID credentials (the same username and password you use for
45+
> Docker Hub). If you don't have a Docker account, [create
46+
> one](../../accounts/create-account.md) for free.
47+
>
48+
> Run `docker login dhi.io` to authenticate.
49+
50+
51+
```diff
52+
- ## Original Ubuntu-based image
53+
- FROM ubuntu/go:1.22-24.04
54+
55+
+ ## Updated to use hardened Debian-based image
56+
+ FROM dhi.io/golang:1-debian13-dev
57+
```
58+
59+
To find the right tag, explore the available tags in the [DHI
60+
Catalog](https://hub.docker.com/hardened-images/catalog/).
61+
62+
### Step 2: Update package installation commands
63+
64+
Since Ubuntu and Debian both use APT for package management, most package
65+
installation commands remain similar. However, you need to ensure that package
66+
installations only occur in `dev` or `sdk` images, as runtime images don't
67+
contain package managers.
68+
69+
```diff
70+
- ## Ubuntu: Installing packages
71+
- FROM ubuntu/go:1.22-24.04
72+
- RUN apt-get update && apt-get install -y \
73+
- git \
74+
- && rm -rf /var/lib/apt/lists/*
75+
76+
+ ## DHI: Use a language-specific dev image with package manager
77+
+ FROM dhi.io/golang:1-debian13-dev
78+
+ RUN apt-get update && apt-get install -y \
79+
+ git \
80+
+ && rm -rf /var/lib/apt/lists/*
81+
```
82+
83+
Most Ubuntu packages are available in Debian with the same names. If you
84+
encounter missing packages, you can search for equivalent packages using the
85+
[Debian package search](https://packages.debian.org/) website.
86+
87+
### Step 3: Update the runtime image in your Dockerfile
88+
89+
> [!NOTE]
90+
>
91+
> Multi-stage builds are recommended to keep your final image minimal and
92+
> secure. Single-stage builds are supported, but they include the full `dev` image
93+
> and therefore result in a larger image with a broader attack surface.
94+
95+
To ensure that your final image is as minimal as possible, you should use a
96+
[multi-stage build](/manuals/build/building/multi-stage.md). All stages in your
97+
Dockerfile should use a hardened image. While intermediary stages will typically
98+
use images tagged as `dev` or `sdk`, your final runtime stage should use a runtime image.
99+
100+
Utilize the build stage to install dependencies and prepare your application,
101+
then copy the resulting artifacts to the final runtime stage. This ensures that
102+
your final image is minimal and secure.
103+
104+
The following example shows a multi-stage Dockerfile migrating from Ubuntu to DHI Debian:
105+
106+
```dockerfile
107+
# Build stage
108+
FROM dhi.io/golang:1-debian13-dev AS builder
109+
WORKDIR /app
110+
111+
# Install system dependencies (only available in dev images)
112+
RUN apt-get update && apt-get install -y \
113+
git \
114+
&& rm -rf /var/lib/apt/lists/*
115+
116+
# Copy application files
117+
COPY go.mod go.sum ./
118+
RUN go mod download
119+
120+
COPY . .
121+
RUN CGO_ENABLED=0 GOOS=linux go build -a -ldflags="-s -w" -o main .
122+
123+
# Runtime stage
124+
FROM dhi.io/golang:1-debian13
125+
WORKDIR /app
126+
127+
# Copy compiled binary from builder
128+
COPY --from=builder /app/main /app/main
129+
130+
# Run the application
131+
ENTRYPOINT ["/app/main"]
132+
```
133+
134+
## Language-specific examples
135+
136+
See the examples section for language-specific migration examples:
137+
138+
- [Go](examples/go.md)
139+
- [Python](examples/python.md)
140+
- [Node.js](examples/node.md)

0 commit comments

Comments
 (0)