构建多平台支持的 .NET 容器镜像

构建多平台支持的 .NET 容器镜像

Intro

最近看到有朋友在尝试在 arm 上支持的 docker 镜像

刚好之前对 dotnet-exec 的镜像添加了多平台的支持,之前仅支持 x64 的平台,新增了对于 arm 的支持,于是想分享一下如何针对 Dockerfile 改造以支持多平台,之前有一篇官方博客介绍了多平台的容器支持,可以参考文末的参考链接,希望对大家有所帮助

Sample

多平台构建 Dockerfile 示例

FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:9.0-preview-alpine AS build-env
ARG TARGETARCH
WORKDIR /app
COPY ./src/ ./src/
COPY ./build/ ./build/
COPY ./Directory.Build.props ./
COPY ./Directory.Build.targets ./
COPY ./Directory.Packages.props ./
WORKDIR /app/src/dotnet-exec/
ENV HUSKY=0
RUN dotnet publish -f net9.0 -a $TARGETARCH -o /app/out/

FROM mcr.microsoft.com/dotnet/runtime:9.0-preview-alpine AS final
LABEL Maintainer="WeihanLi"
LABEL Repository="https://github.com/WeihanLi/dotnet-exec"
WORKDIR /app
COPY --from=build-env /app/out/ ./
ENV PATH="/app:${PATH}"
RUN chmod +x /app/dotnet-exec
ENTRYPOINT [ "/app/dotnet-exec" ]
CMD [ "--help" ]

和之前的 Dockerfile相比,主要变化有两点:

  • 指定 sdk 镜像时增加了 --platform=$BUILDPLATFORM,这里 platform 指定的是要拉取镜像的架构,默认是本机的架构,比如 amd64 的架构默认 platform 是 linux/amd64, 我们也可以手动指定 arm64 来构建 arm64 架构的镜像

  • dotnet publish 的时候指定了 -a $TARGETARCH ,对于 platform 是 linux/amd64 的情况,TARGETARCH 会是 amd64

BUILDPLATFORMTARGETARCH 均是 docker build 时的内置变量,详见 docker 文档 https://docs.docker.com/build/building/variables/#multi-platform-build-arguments

我们在使用 docker build  的时候可以指定 platform 参数

docker build -t multi-arch-sample --platform linux/arm64 .

也可以一次指定多个架构

docker buildx build --pull -t aspnetapp -f Dockerfile --platform linux/arm64,linux/arm,linux/amd64 .

Github Action Sample

接着看一个 github action yaml 的示例

name: docker

on:
  workflow_dispatch:
  # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#release
  release:
    types: [published]
  push:
    branches:
      - "main"
    paths:
      - 'Dockerfile'
      - 'Directory.*'
      - 'src/**'
      - 'build/**'
      - '.github/workflows/docker.yml'
env:
  DOCKER_HUB_USERNAME: "weihanli"
  ContainerPlatforms: "linux/amd64,linux/arm64,linux/arm"
jobs:  
  docker-build:
    if: github.repository == 'WeihanLi/dotnet-exec'
    runs-on: ubuntu-latest

    steps:
    - name: Check Out
      uses: actions/checkout@v4

    - name: Set up QEMU
      uses: docker/setup-qemu-action@v3
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v3

    - name: Login to Docker Hub
      uses: docker/login-action@v3
      with:
        username: ${{ env.DOCKER_HUB_USERNAME }}
        password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

    - name: Build and push latest
      id: docker_build_latest
      uses: docker/build-push-action@v5
      with:
        # https://docs.github.com/en/actions/learn-github-actions/contexts#github-context
        context: ./
        file: ./Dockerfile
        push: true
        tags: ${{ env.DOCKER_HUB_USERNAME }}/dotnet-exec:latest
        platforms: ${{ env.ContainerPlatforms }}

这里首先我们需要设置 qemu 以支持模拟多种架构,这样才能够实现支持本地之外的架构构建,其次我们需要设置 docker buildx 以比较方便地构建多平台架构支持镜像,最后在 build 的时候指定需要的 platform

d696a7a43ebde5f7f208a7a38284ce45.png

4b6c1b8bc4db7ffebfa15947d723ca52.png

1a1ca8d73e813715b0dc30d5209b791b.png

References

  • https://docs.docker.com/build/building/multi-platform/

  • https://docs.docker.com/build/building/variables/#multi-platform-build-arguments

  • https://docs.docker.com/reference/dockerfile/#automatic-platform-args-in-the-global-scope

  • https://www.docker.com/blog/faster-multi-platform-builds-dockerfile-cross-compilation-guide/

  • https://devblogs.microsoft.com/dotnet/improving-multiplatform-container-support/

  • https://github.com/dotnet/dotnet-docker/blob/main/samples/aspnetapp/Dockerfile.alpine

  • https://github.com/WeihanLi/dotnet-exec/blob/0.18.1/Dockerfile

  • https://github.com/WeihanLi/dotnet-exec/blob/0.18.1/.github/workflows/docker.yml

  • https://github.com/WeihanLi/dotnet-exec/compare/0.17.0...0.18.0#diff-dd2c0eb6ea5cfc6c4bd4eac30934e2d5746747af48fef6da689e85b752f39557

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值