Skip to content

Commit 6aa3d33

Browse files
authored
[main] Add documentation for installing additional slices on Ubuntu Chiseled images (#6275)
1 parent a42f018 commit 6aa3d33

File tree

1 file changed

+68
-1
lines changed

1 file changed

+68
-1
lines changed

documentation/ubuntu-chiseled.md

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,71 @@ Please see our sample Dockerfiles for examples on how to use Ubuntu Chiseled .NE
3030
* [releasesapi](../samples/releasesapi/Dockerfile.ubuntu-chiseled) (and [icu version](../samples/releasesapi/Dockerfile.ubuntu-chiseled-icu))
3131
* [releasesapp](../samples/releasesapp/Dockerfile.chiseled)
3232

33-
If your app's Dockerfile doesn't install any additional Linux packages or depend on any shell scripts for setup, Ubuntu Chiseled images could be a drop-in replacement for our full Ubuntu or Debian images.
33+
If your app's Dockerfile doesn't depend on any shell scripts for setup, Ubuntu Chiseled images could be a drop-in replacement for our full Ubuntu or Debian images.
34+
35+
## How do I install additional packages on Chiseled images?
36+
37+
> [!IMPORTANT]
38+
> Installing additional packages requires the presence of the [Chisel manifest](https://github.com/dotnet/dotnet-docker/issues/6135), which is currently only available in **.NET 10+** images.
39+
40+
[Chisel](https://github.com/canonical/chisel) is built on the idea of package slices.
41+
Slices are basically subsets of packages, with their own content and set of dependencies to other internal and external slices.
42+
Chisel relies on a [database of slices](https://github.com/canonical/chisel-releases) that are indexed per Ubuntu release.
43+
You can only install packages that are available as slices.
44+
45+
First, acquire `chisel` and `chisel-wrapper`.
46+
`chisel-wrapper` (from [rocks-toolbox](https://github.com/canonical/rocks-toolbox/)) is used to generate a dpkg status file documenting which packages are installed, which is used by many vulnerability scanning tools.
47+
48+
```Dockerfile
49+
FROM mcr.microsoft.com/dotnet/nightly/sdk:10.0-preview-noble AS chisel
50+
51+
# Docker build arg documentation: https://docs.docker.com/build/building/variables/
52+
ARG BASE_IMAGE="mcr.microsoft.com/dotnet/nightly/runtime-deps:10.0-preview-noble-chiseled"
53+
# Find the latest chisel releases: https://github.com/canonical/chisel/releases
54+
ARG CHISEL_VERSION="v1.X.X"
55+
# Find the latest chisel-wrapper releases: https://github.com/canonical/rocks-toolbox/releases
56+
ARG CHISEL_WRAPPER_VERSION="v1.X.X"
57+
58+
# Install chisel's dependencies
59+
RUN apt-get update \
60+
&& apt-get install -y --no-install-recommends \
61+
file \
62+
&& rm -rf /var/lib/apt/lists/*
63+
64+
# Install chisel and chisel-wrapper
65+
RUN chisel_url=https://github.com/canonical/chisel/releases/download/v${CHISEL_VERSION}/chisel_v${CHISEL_VERSION}_linux_amd64.tar.gz \
66+
&& curl -fSLOJ ${chisel_url} \
67+
&& curl -fSL ${chisel_url}.sha384 | sha384sum -c - \
68+
&& tar -xzf chisel_v${CHISEL_VERSION}_linux_amd64.tar.gz -C /usr/bin/ chisel \
69+
&& curl -fSL --output /usr/bin/chisel-wrapper https://raw.githubusercontent.com/canonical/rocks-toolbox/${CHISEL_WRAPPER_VERSION}/chisel-wrapper \
70+
&& chmod 755 /usr/bin/chisel-wrapper
71+
```
72+
73+
Then, copy over the filesystem from your desired base image and use `chisel` and `chisel-wrapper` to install additional slices.
74+
See [canonical/chisel-releases](https://github.com/canonical/chisel-releases) for available slices.
75+
76+
```Dockerfile
77+
COPY --from=$BASE_IMAGE / /rootfs/
78+
79+
RUN chisel-wrapper --generate-dpkg-status /new-dpkg-status -- \
80+
--release ubuntu-24.04 --root /rootfs/ \
81+
libicu74_libs \
82+
tzdata-legacy_zoneinfo \
83+
tzdata_zoneinfo \
84+
&& cat /new-dpkg-status >> /rootfs/var/lib/dpkg/status
85+
```
86+
87+
Finally, copy the new root filesystem into a scratch base image for your final (runtime) layer.
88+
89+
```Dockerfile
90+
FROM scratch AS final
91+
COPY --link --from=chisel /rootfs /
92+
WORKDIR /app
93+
COPY --link --from=build /app .
94+
USER $APP_UID
95+
ENTRYPOINT ["./app"]
96+
```
97+
98+
Copying the entire filesystem into the final `FROM scratch` layer results in a perfectly space- and layer-efficient installation of the additional slices.
99+
However, it's important to note that this pattern does not allow any layer sharing with your chosen .NET base image - the first `COPY` instruction in the final stage is essentially creating a completely new base image layer.
100+
Keep this in mind when creating your Dockerfiles - for example, you may find it beneficial to share layers between multiple .NET images running in the same Kubernetes cluster.

0 commit comments

Comments
 (0)