203 строки
7.3 KiB
Markdown
203 строки
7.3 KiB
Markdown
# Azure Linux
|
|
|
|
[Azure Linux](https://github.com/microsoft/AzureLinux) (previously known as CBL-Mariner) is an MIT-licensed, RPM-based Linux distribution published by Microsoft.
|
|
Azure Linux .NET images are [publicly supported](https://github.com/dotnet/dotnet-docker/discussions/5022) by Microsoft.
|
|
|
|
## Featured Tags
|
|
|
|
* `8.0-cbl-mariner2.0`
|
|
* `docker pull mcr.microsoft.com/dotnet/sdk:8.0-cbl-mariner2.0`
|
|
* `docker pull mcr.microsoft.com/dotnet/aspnet:8.0-cbl-mariner2.0`
|
|
* `docker pull mcr.microsoft.com/dotnet/runtime:8.0-cbl-mariner2.0`
|
|
* `docker pull mcr.microsoft.com/dotnet/runtime-deps:8.0-cbl-mariner2.0`
|
|
|
|
## Azure Linux Distroless
|
|
|
|
Azure Linux distroless .NET images contain only the minimal set of packages .NET needs, with everything else removed.
|
|
General distroless .NET containers documentation is available [here](./distroless.md).
|
|
|
|
Azure Linux distroless .NET images are available for all supported .NET versions in the following image repos:
|
|
|
|
* [`mcr.microsoft.com/dotnet/runtime`](../README.runtime.md)
|
|
* [`mcr.microsoft.com/dotnet/aspnet`](../README.aspnet.md)
|
|
* [`mcr.microsoft.com/dotnet/runtime-deps`](../README.runtime-deps.md) (for self-contained or AOT apps)
|
|
|
|
You can use the following image tags:
|
|
|
|
* `8.0-cbl-mariner2.0-distroless`
|
|
* `6.0-cbl-mariner2.0-distroless`
|
|
|
|
### Installing Additional Packages
|
|
|
|
If your app requires additional packages besides `icu` and `tzdata`, you can follow the same pattern that .NET uses to install the .NET runtime dependencies.
|
|
|
|
#### Azure Linux 3.0 (Preview)
|
|
|
|
```Dockerfile
|
|
FROM mcr.microsoft.com/dotnet/nightly/aspnet:8.0-azurelinux3.0-distroless AS base
|
|
|
|
FROM azurelinuxpreview.azurecr.io/public/azurelinux/base/core:3.0 AS installer
|
|
|
|
RUN tdnf install -y fdupes \
|
|
&& tdnf clean all
|
|
|
|
COPY --from=base / /staging1
|
|
COPY --from=base / /staging2
|
|
|
|
RUN tdnf install -y --releasever=3.0 --installroot /staging2 tzdata \
|
|
&& tdnf clean all --releasever=3.0 --installroot /staging2
|
|
|
|
# Prepare the staging2 directory to be copied to the final stage by removing unnecessary files
|
|
# that will only cause extra image bloat.
|
|
RUN \
|
|
# Remove duplicates from staging2 that exist in staging1
|
|
fdupes /staging1 /staging2 -rdpN \
|
|
\
|
|
# Delete duplicate symlinks
|
|
# Function to find and format symlinks w/o including root dir (format: /path/to/symlink /path/to/target)
|
|
&& getsymlinks() { find $1 -type l -printf '%p %l\n' | sed -n "s/^\\$1\\(.*\\)/\\1/p"; } \
|
|
# Combine set of symlinks between staging1 and staging2
|
|
&& (getsymlinks "/staging1"; getsymlinks "/staging2") \
|
|
# Sort them
|
|
| sort \
|
|
# Find the duplicates
|
|
| uniq -d \
|
|
# Extract just the path to the symlink
|
|
| cut -d' ' -f1 \
|
|
# Prepend the staging2 directory to the paths
|
|
| sed -e 's/^/\/staging2/' \
|
|
# Delete the files
|
|
| xargs rm \
|
|
\
|
|
# General cleanup
|
|
&& rm -rf /staging2/etc/tdnf \
|
|
&& rm -rf /staging2/run/* \
|
|
&& rm -rf /staging2/var/cache/tdnf \
|
|
&& rm -rf /staging2/var/lib/rpm \
|
|
&& rm -rf /staging2/usr/share/doc \
|
|
&& rm -rf /staging2/usr/share/man \
|
|
&& find /staging2 -type d -empty -delete
|
|
|
|
FROM base
|
|
COPY --from=installer /staging2/ /
|
|
```
|
|
|
|
#### Azure Linux 2.0
|
|
|
|
```Dockerfile
|
|
FROM mcr.microsoft.com/dotnet/aspnet:6.0-cbl-mariner2.0-distroless AS base
|
|
|
|
FROM mcr.microsoft.com/cbl-mariner/base/core:2.0 AS installer
|
|
|
|
RUN tdnf install -y fdupes \
|
|
&& tdnf clean all
|
|
|
|
COPY --from=base / /staging1
|
|
COPY --from=base / /staging2
|
|
|
|
RUN tdnf install -y --releasever=2.0 --installroot /staging2 <package-name> \
|
|
&& tdnf clean all --releasever=2.0 --installroot /staging2
|
|
|
|
# Prepare the staging2 directory to be copied to the final stage by removing unnecessary files
|
|
# that will only cause extra image bloat.
|
|
RUN \
|
|
# Remove duplicates from staging2 that exist in staging1
|
|
fdupes /staging1 /staging2 -rdpN \
|
|
\
|
|
# Delete duplicate symlinks
|
|
# Function to find and format symlinks w/o including root dir (format: /path/to/symlink /path/to/target)
|
|
&& getsymlinks() { find $1 -type l -printf '%p %l\n' | sed -n "s/^\\$1\\(.*\\)/\\1/p"; } \
|
|
# Combine set of symlinks between staging1 and staging2
|
|
&& (getsymlinks "/staging1"; getsymlinks "/staging2") \
|
|
# Sort them
|
|
| sort \
|
|
# Find the duplicates
|
|
| uniq -d \
|
|
# Extract just the path to the symlink
|
|
| cut -d' ' -f1 \
|
|
# Prepend the staging2 directory to the paths
|
|
| sed -e 's/^/\/staging2/' \
|
|
# Delete the files
|
|
| xargs rm \
|
|
\
|
|
# General cleanup
|
|
&& rm -rf /staging2/etc/tdnf \
|
|
&& rm -rf /staging2/run/* \
|
|
&& rm -rf /staging2/var/cache/tdnf \
|
|
&& rm -rf /staging2/var/lib/rpm \
|
|
&& rm -rf /staging2/usr/share/doc \
|
|
&& rm -rf /staging2/usr/share/man \
|
|
&& find /staging2/var/log -type f -size +0 -delete \
|
|
&& find /staging2 -type d -empty -delete
|
|
|
|
FROM base
|
|
COPY --from=installer /staging2/ /
|
|
```
|
|
|
|
## Debugging with Container Fast Mode
|
|
|
|
In order to reduce image size and attack surface, Azure Linux .NET Runtime images do not contain the tools required to debug .NET apps using Visual Studio.
|
|
The easiest way to enable local Visual Studio debugging while not modifying the production image is to use [Container Fast Mode](https://learn.microsoft.com/en-us/visualstudio/containers/container-build#debugging).
|
|
|
|
To enable Container Fast Mode debugging without affecting your app's production image, you can create a new stage based off the `base` stage (called `debug` in the example) that contains the debugging tools, and then point the VS Fast Mode tools to that debug stage.
|
|
|
|
Here's an example chart showing the inheritance of the build stages:
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
base --> debug
|
|
base --> final
|
|
build --> publish
|
|
```
|
|
|
|
Here's an example configuration based off of a simple ASP.NET Core app:
|
|
|
|
### *.csproj
|
|
|
|
```diff
|
|
<PropertyGroup>
|
|
...
|
|
+ <DockerfileFastModeStage>debug</DockerfileFastModeStage>
|
|
...
|
|
</PropertyGroup>
|
|
```
|
|
|
|
### Dockerfile
|
|
|
|
```diff
|
|
# Learn about building .NET container images:
|
|
# https://github.com/dotnet/dotnet-docker/blob/main/samples/README.md
|
|
FROM mcr.microsoft.com/dotnet/aspnet:8.0-cbl-mariner2.0 AS base
|
|
- USER $APP_UID
|
|
WORKDIR /app
|
|
EXPOSE 8080
|
|
EXPOSE 8081
|
|
|
|
+ # this stage is used by VS for fast local debugging; it does not appear in the final image
|
|
+ FROM base AS debug
|
|
+ RUN tdnf install -y procps-ng # <-- Install tools needed for debugging (e.g. the `pidof` command)
|
|
|
|
FROM mcr.microsoft.com/dotnet/sdk:8.0-cbl-mariner2.0 AS build
|
|
ARG BUILD_CONFIGURATION=Release
|
|
WORKDIR /src
|
|
COPY ["aspnetapp/aspnetapp.csproj", "aspnetapp/"]
|
|
RUN dotnet restore "./aspnetapp/aspnetapp.csproj"
|
|
COPY . .
|
|
WORKDIR "/src/aspnetapp"
|
|
RUN dotnet build "./aspnetapp.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
|
|
|
FROM build AS publish
|
|
ARG BUILD_CONFIGURATION=Release
|
|
RUN dotnet publish "./aspnetapp.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
|
|
|
FROM base AS final
|
|
WORKDIR /app
|
|
COPY --from=publish /app/publish .
|
|
+ # Make sure non-root user is enabled after the debug stage so that we have permission to install the debug dependencies
|
|
+ USER $APP_UID
|
|
ENTRYPOINT ["dotnet", "aspnetapp.dll"]
|
|
```
|
|
|
|
If this example doesn't work for your scenario, see [Container Tools build properties](https://docs.microsoft.com/en-us/visualstudio/containers/container-msbuild-properties?view=vs-2022) for more information on
|
|
customizing the Fast Mode stage, or setting a custom `DockerDebuggeeKillProgram`.
|