使用 Dockerfile 构建基于 .NET9 的跨平台基础镜像

官方基础镜像准备

微软官方 dotnet sdk 基础镜像:

bash 复制代码
docker pull mcr.microsoft.com/dotnet/sdk:9.0

拉取 ubuntu 镜像:

bash 复制代码
docker pull ubuntu:24.04

更多资源请参考:

  • dotnet sdk images,https://mcr.microsoft.com/en-us/artifact/mar/dotnet/sdk/tags
  • github docker buildx ,https://github.com/docker/buildx
  • 阿里云开源镜像站,https://developer.aliyun.com/mirror/
  • 微软官方包源,https://packages.microsoft.com/config/

构建私有化基础镜像

此处使用到的相关资源:

  • dotnet sdk 9.0
  • dotnet aspire
  • PowerShell
  • Ubuntu Server 24.04

Ubuntu 24.04 软件源位置调整

Ubuntu 24.04 的软件源位置调整后,需要根据新的文件路径或结构进行修改。

以下是调整方法:

1. 确认源文件路径

注意 Ubuntu 24.04 的源文件路径已从传统的 /etc/apt/sources.list 文件迁移到使用 sources.list.d/ 目录下的单独 .sources 文件。例如:

  • 原路径:/etc/apt/sources.list
  • 新路径:/etc/apt/sources.list.d/ubuntu.sources
2. 修改源地址

在修改 Ubuntu 的源文件之前,建议先进行备份。

bash 复制代码
RUN cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.bak

如果发现软件源位置有调整,可以使用以下命令来替换为阿里云的镜像源:

bash 复制代码
RUN sed -i 's|http://archive.ubuntu.com|https://mirrors.aliyun.com|g' /etc/apt/sources.list.d/ubuntu.sources && \
    sed -i 's|http://security.ubuntu.com|https://mirrors.aliyun.com|g' /etc/apt/sources.list.d/ubuntu.sources
3. 更新包索引

修改完成后,运行以下命令更新包索引:

bash 复制代码
apt update
4. 验证源是否生效

可以通过安装一个测试包来验证新源是否正常工作。

如果系统提示找不到源文件,请检查路径是否正确,并确保你正在编辑的是当前系统实际使用的 .sources 文件。

构建 Ubuntu 基础镜像

制作 .NET 平台的 Ubuntu 基础镜像,完整的 Dockerfile 内容如下:

bash 复制代码
# 使用官方的 Ubuntu 24.04 镜像作为基础镜像
FROM --platform=$TARGETPLATFORM ubuntu:24.04

# 设置环境变量,避免交互式安装时的提示
ENV DEBIAN_FRONTEND=noninteractive

# 创建目录结构
WORKDIR /app

# 备份原始源文件并更换为阿里云的镜像源
RUN cp /etc/apt/sources.list /etc/apt/sources.list.bak && \
    cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.bak && \
    sed -i 's|http://archive.ubuntu.com|https://mirrors.aliyun.com|g' /etc/apt/sources.list && \
    sed -i 's|http://security.ubuntu.com|https://mirrors.aliyun.com|g' /etc/apt/sources.list.d/ubuntu.sources

# 更新包列表并安装常用工具,并立即清理缓存
RUN apt update && \
    apt upgrade -y && \
    apt install -y wget software-properties-common gnupg curl && \
    rm -rf /var/lib/apt/lists/* && \
    apt clean

# 安装 PowerShell 的依赖并清理
RUN apt update && \
    apt install -y --no-install-recommends \
    apt-transport-https \
    ca-certificates && \
    rm -rf /var/lib/apt/lists/* && \
    apt clean

# 添加 Microsoft 包仓库并安装 PowerShell
RUN wget -q https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb && \
    dpkg -i packages-microsoft-prod.deb && \
    rm packages-microsoft-prod.deb && \
    apt update && \
    apt install -y powershell && \
    rm -rf /var/lib/apt/lists/* && \
    apt clean

# 安装 .NET SDK 并清理
RUN wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh && \
    chmod +x dotnet-install.sh && \
    ./dotnet-install.sh -c Current && \
    rm dotnet-install.sh

# 将 .NET CLI 添加到 PATH 环境变量
ENV PATH="/root/.dotnet:${PATH}"

# 安装 .NET Aspire 和 ASP.NET Core 的代码生成器工具并清理
RUN dotnet workload install aspire && \
    dotnet tool install -g dotnet-aspnet-codegenerator && \
    dotnet nuget locals all --clear

# 创建非 root 用户和组(安全处理已存在的情况)
RUN if getent group appgroup > /dev/null; then groupdel appgroup; fi && \
    if getent passwd appuser > /dev/null; then userdel appuser; fi && \
    groupadd -g 1000 appgroup && \
    useradd -u 1000 -g appgroup -m appuser

# 设置工作目录权限
RUN chown -R appuser:appgroup /app

# 切换到非 root 用户
USER appuser

# 设置默认 Shell 为 PowerShell(可选)
SHELL ["pwsh", "-Command"]

# 输出测试信息
CMD ["sh", "-c", "echo 'Ubuntu 镜像源已成功更换为阿里云!PowerShell 和 .NET SDK 已安装。'"]

✅ 优化点说明

  • APT 缓存清理:每次使用 apt install 后都执行 rm -rf /var/lib/apt/lists/*apt clean,以清除包索引和缓存。
  • 临时文件清理:如安装 .NET SDK 后删除了脚本文件 dotnet-install.sh
  • NuGet 缓存清理:使用 dotnet nuget locals all --clear 清除 NuGet 包缓存。

这样可以显著减少最终镜像的体积,同时保持功能不变。

✅ 构建命令

bash 复制代码
docker build --platform linux/amd64 -t dotnet-sdk:ubuntu-24.04 ./

✅ 运行容器并验证安装

bash 复制代码
docker run --rm dotnet-sdk:ubuntu-24.04 pwsh -c "dotnet --info"

我们还可以进入容器内进行调试:

bash 复制代码
docker run -it dotnet-sdk:ubuntu-24.04 pwsh

此处我们就构建了基于 Ubuntu 24.04.NET SDK 基础镜像。


使用示例

如何使用 Dockerfile 构建 .NET 的基础镜像?

✅ 构建基础镜像

要使用提供的 Dockerfile 构建一个基于 amd64 架构的基础镜像,我们可以通过指定 --platform 参数为 linux/amd64 来强制构建特定架构的镜像。

  1. 构建单个平台镜像
bash 复制代码
docker build --platform linux/amd64 -t your-amd64-image-name:tag ./
  1. 使用 buildx 构建多平台镜像

或者我们也可以指定多个目标平台,例如同时构建 amd64arm64

bash 复制代码
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t your-dockerhub-username/image:tag \
  --push \
  ./
📌 参数解释

🔹--platform linux/amd64,linux/arm64:指定目标平台为 amd64(x86_64)arm64(RISC) 架构。

🔹-t your-dockerhub-username/image:tag:为镜像打标签,如 aspire-dotnet-sdk:9.0

🔹 --push 表示构建后推送到远程仓库(需登录 Docker Hub 或私有镜像仓库)。

🔹 如果你不希望推送,可以去掉 --push 并使用 --load 加载本地镜像(但仅限当前平台)。

🔹./:表示当前目录为构建上下文。

说明:使用 docker buildx 实现真正的多平台镜像构建能力。

🧼 构建示例

此处我们构建一个 Linux 环境多平台(amd64,arm64)支持的基础镜像,命令如下:

bash 复制代码
docker buildx build --platform linux/amd64,linux/arm64 -t aspire-dotnet-sdk-amd64:9.0 --load ./

⚠️ 注意事项:

  1. 确保 Docker 支持多平台构建
    • 推荐使用支持 buildxDocker 版本(建议 20.10+)。
    • 若提示 --platform 不被支持,请启用 buildx
  • 启用 buildx 构建器并设置为默认
bash 复制代码
# 创建并使用一个支持多平台的构建器
docker buildx create --use --name mybuilder

# 启动构建器(如果刚创建可能不需要再启动)
docker buildx inspect --bootstrap
  • 此时你应该看到类似输出:

    Name: mybuilder
    Driver: docker-container
    Nodes:
    Name: mybuilder0
    OS/Arch: linux/amd64

docker buildx 使用 docker-container 驱动,支持多平台交叉编译。

  1. 若需推送到镜像仓库 ,请在构建后使用 docker push 命令:
bash 复制代码
docker push your-image-name:tag

🔁 小结

操作 命令
创建 buildx 构建器 docker buildx create --use --name mybuilder
构建并推送多平台镜像 docker buildx build --platform linux/amd64,linux/arm64 -t user/repo:tag --push .
本地加载单平台镜像 docker buildx build --platform linux/amd64 -t local-image:tag --load .
查看多平台镜像信息 docker buildx imagetools inspect user/repo:tag
相关推荐
一个帅气昵称啊1 天前
.Net通过EFCore和仓储模式实现统一数据权限管控并且相关权限配置动态生成
.net·efcore·仓储模式
helloworddm1 天前
CalculateGrainDirectoryPartition
服务器·c#·.net
步步为营DotNet1 天前
深度剖析.NET中HttpClient的请求重试机制:可靠性提升与实践优化
开发语言·php·.net
ChaITSimpleLove1 天前
使用 .net10 构建 AI 友好的 RSS 订阅机器人
人工智能·.net·mcp·ai bot·rss bot
专注VB编程开发20年1 天前
vb.net宿主程序通过统一接口直接调用,命名空间要一致
服务器·前端·.net
ChaITSimpleLove2 天前
基于 .NET Garnet 1.0.91 实现高性能分布式锁(使用 Lua 脚本)
分布式·.net·lua
用户4488466710602 天前
.NET进阶——深入理解线程(2)Thread入门到精通
c#·.net
一个帅气昵称啊2 天前
.Net——AI智能体开发基于 Microsoft Agent Framework 实现第三方聊天历史存储
人工智能·microsoft·.net