内心充满阳光 發表於 2024-4-29 07:22:00

制作一个能构建 dotnet AOT 的 gitlab runner 的 Debian docker 镜像

<p>我的需求是需要有一个能够构建出 dotnet 的 AOT 包的环境,要求这个环境能解决 glibc 兼容依赖的问题,能打出来 x64 和 arm64 的 AOT 的包,且能够运行 gitlab runner 对接自动构建</p>



<h2 id="需求">需求</h2>
<p>以下是我列举的需求</p>
<ul>
<li>支持制作能在 UOS 系统和麒麟系统上运行的包</li>
<li>支持制作出来的包是 AOT 版本的</li>
<li>可以使用 gitlab runner 对接自动构建</li>
</ul>
<p>开始之前必须说明的是,对于 dotnet 应用来说,如果不需要 AOT 的话,完全可以在 Windows 上构建出其他 Linux 系统和其他平台适用的应用。仅仅只是在 AOT 下,强依赖平台构建时,才有需要在对应的系统平台构建</p>
<h2 id="制作方法">制作方法</h2>
<p>我制作的 docker 的 Dockerfile 是基于 <code>debian:buster-slim</code> 打上负载的</p>
<pre><code>FROM debian:buster-slim
</code></pre>
<p>为了提升一点拉取速度,我换成国内的源,使用的是阿里的源</p>
<pre><code>RUN rm /etc/apt/sources.list
COPY sources.list /etc/apt/sources.list
RUN apt-get update
</code></pre>
<p>这里的 sources.list 的代码是从 debian镜像_debian下载地址_debian安装教程-阿里巴巴开源镜像站 抄的,代码如下</p>
<pre><code>deb http://mirrors.aliyun.com/debian/ buster main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ buster main non-free contrib
deb http://mirrors.aliyun.com/debian-security buster/updates main
deb-src http://mirrors.aliyun.com/debian-security buster/updates main
deb http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib
</code></pre>
<p>为了交叉构建,同时构建出 ARM64 的 AOT 的 dotnet 应用,我根据 Cross-compilation - .NET - Microsoft Learn 的文档安装上必要的负载</p>
<pre><code>RUN dpkg --add-architecture arm64
RUN apt update

RUN apt-get install libicu-dev -y
RUN apt-get install libssl-dev -y
RUN apt-get install wget -y
RUN apt-get install clang llvm -y
RUN apt-get install gcc-aarch64-linux-gnu -y
RUN apt-get install binutils-aarch64-linux-gnu -y
RUN apt-get install zlib1g-dev -y
RUN apt-get install zlib1g-dev:arm64 -y
</code></pre>
<p>为了方便调试和对接 gitlab runner 我还加上了 git 和 vim 工具</p>
<pre><code>RUN apt-get install vim -y
RUN apt-get install git -y

RUN apt-get clean
</code></pre>
<p>到这一步,就完成了 docker image 里面的基础部分了,现在的 Dockerfile 的代码如下</p>
<pre><code>FROM debian:buster-slim
WORKDIR /root

RUN rm /etc/apt/sources.list
COPY sources.list /etc/apt/sources.list
RUN apt-get update

RUN dpkg --add-architecture arm64
RUN apt update

RUN apt-get install libicu-dev -y
RUN apt-get install libssl-dev -y
RUN apt-get install wget -y
RUN apt-get install clang llvm -y
RUN apt-get install gcc-aarch64-linux-gnu -y
RUN apt-get install binutils-aarch64-linux-gnu -y
RUN apt-get install zlib1g-dev -y
RUN apt-get install zlib1g-dev:arm64 -y

RUN apt-get install vim -y
RUN apt-get install git -y

RUN apt-get clean
</code></pre>
<p>接着到 dotnet 官网 下载 dotnet 8 和 dotnet 6 的 sdk 压缩包,本文这里使用的是自己解压缩的方式。换成命令方式安装也可以,只是命令方式拉取的速度可能不如先下载压缩包的方式,且下载压缩包可以方便多次重新构建,在 Dockerfile 不断需要修改时,使用压缩包可以省去多次修改之后的重新构建时的拉取时间</p>

<p><img src="https://img2024.cnblogs.com/blog/1080237/202404/1080237-20240429084614297-1590020418.jpg" alt="" loading="lazy"></p>
<p>本文这里采用的是下载压缩包的方式,下载到 dotnet-sdk-6.0.421-linux-x64.tar.gz 和 dotnet-sdk-8.0.204-linux-x64.tar.gz 这两个压缩包。如果大家下载失败,或者没有网速的话,可以邮件给我,让我用网盘发给你。一般情况下在国内都能拉取成功,因为微软帮忙提供了全球 CDN 了,下载速度在我这里还是很快的。下载 dotnet 6 版本仅仅只是为了让我的构建工具正常工作而已,属于可选项</p>
<p>下载完成 dotnet 的压缩包,即可使用 Dockerfile 的 ADD 命令将压缩包解压缩到 docker image 里的某个文件夹里面,如下面代码</p>
<pre><code>WORKDIR /root
ADD dotnet-sdk-6.0.421-linux-x64.tar.gz ./dotnet
ADD dotnet-sdk-8.0.204-linux-x64.tar.gz ./dotnet
</code></pre>
<p>解压缩完成之后,配置环境变量等,让全局可以使用 dotnet 命令</p>
<pre><code>ENV DOTNET_ROOT="/root/dotnet"
ENV PATH="${PATH}:${DOTNET_ROOT}:${DOTNET_ROOT}/tools"
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
RUN ln -s /root/dotnet/dotnet /usr/bin/dotnet
</code></pre>
<p>完成以上步骤之后,一个特别简单的 dotnet 构建 Dockerfile 已经完成了,接下来一步则是配置 gitlab runner 的步骤。我将参考 gitlab runner 官方安装文档 进行配置,只是过程稍微取巧</p>
<p>先根据 Install GitLab Runner manually on GNU/Linux - GitLab 提供的方法,拉取 GitLab Runner 的二进制压缩包,本文这里是需要下载 Linux x86-64 版本,当前的下载链接是 https://s3.dualstack.us-east-1.amazonaws.com/gitlab-runner-downloads/latest/binaries/gitlab-runner-linux-amd64</p>
<p>下载链接可能会有变更,还请大家重新参考 Install GitLab Runner manually on GNU/Linux - GitLab 文档,找到更新的下载 Linux x86-64 版本的下载地址</p>
<p>完成下载之后,通过 COPY 命令拷贝到 docker image 里</p>
<pre><code>COPY gitlab-runner-linux-amd64 /usr/share/gitlab/gitlab-runner

RUN chmod +x /usr/share/gitlab/gitlab-runner
</code></pre>
<p>完成以上步骤之后需要对 GitLab Runner 进行配置。本文这里采用取巧的方式,即先将 GitLab Runner 运行起来,配置完成之后,存放配置文件,再将配置文件打入到 docker image 里面,后续就只需启动 docker image 即可</p>
<p>具体的步骤是先将当前的 Dockerfile 构建且运行。我这里使用的是 podman 工具,如果大家使用的是 docker desktop 的话,只需将 podman 命令换成 docker 命令即可,其他参数相同</p>
<pre><code>// 先 cd 到 Dockerfile 所在的文件夹,再执行以下命令
podman build -t t1 .
</code></pre>
<p>当前的 Dockerfile 文件的代码如下</p>
<pre><code>FROM debian:buster-slim
WORKDIR /root

RUN rm /etc/apt/sources.list
COPY sources.list /etc/apt/sources.list
RUN apt-get update

RUN dpkg --add-architecture arm64
RUN apt update

RUN apt-get install libicu-dev -y
RUN apt-get install libssl-dev -y
RUN apt-get install wget -y
RUN apt-get install clang llvm -y
RUN apt-get install gcc-aarch64-linux-gnu -y
RUN apt-get install binutils-aarch64-linux-gnu -y
RUN apt-get install zlib1g-dev -y
RUN apt-get install zlib1g-dev:arm64 -y

RUN apt-get install vim -y
RUN apt-get install git -y

RUN apt-get clean

ADD dotnet-sdk-6.0.421-linux-x64.tar.gz ./dotnet
ADD dotnet-sdk-8.0.204-linux-x64.tar.gz ./dotnet
ENV DOTNET_ROOT="/root/dotnet"
ENV PATH="${PATH}:${DOTNET_ROOT}:${DOTNET_ROOT}/tools"
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
RUN ln -s /root/dotnet/dotnet /usr/bin/dotnet

COPY gitlab-runner-linux-amd64 /usr/share/gitlab/gitlab-runner

RUN chmod +x /usr/share/gitlab/gitlab-runner
</code></pre>
<p>再将打包好的 docker image 运行,运行时记得挂载上文件夹,用于将 docker 里面的文件传输到主机</p>
<pre><code>// 提前创建好 C 盘的 lindexi 的 wsl 文件夹,你换成自己的文件夹也可以
podman run -i -t -v /mnt/c/lindexi/wsl:/etc/gitlab-runner t1
</code></pre>
<p>以上代码的 <code>/mnt/c/lindexi/wsl</code> 是我自己的 <code>C:\lindexi\wsl</code> 文件夹,这是我提前建立好的空文件夹。大家换成自己的文件夹也可以,如果用 docker desktop 的话,需要看一下是否运行在 wsl 上,如果不在的话,也许需要换成 Windows 下的路径表示方法,相信这一步难不倒大家的</p>
<p>进入之后,即可使用 <code>/usr/share/gitlab/gitlab-runner</code> 命令进行注册,具体的注册步骤如下</p>
<p>本文使用注册 GitLab 组 作为例子,注册单个项目的步骤也类似,详细请参阅 https://docs.gitlab.com/runner/configuration/ 文档。先进入到 GitLab 的 组 的 Runner 配置界面里面,点击 New group runner 按钮</p>

<p><img src="https://img2024.cnblogs.com/blog/1080237/202404/1080237-20240429084614359-589259633.jpg" alt="" loading="lazy"></p>
<p>点击之后,进入配置界面。由于这是一个特殊的构建方式,我推荐写上 gitlab 的 runner tag 项,我这里写的是 <code>debian-dotnet-docker</code> 标记。这里的标记需要和 git 的 tag 区分哦,这是两个完全不相同的东西</p>

<p><img src="https://img2024.cnblogs.com/blog/1080237/202404/1080237-20240429084614247-218896635.jpg" alt="" loading="lazy"></p>
<p>点击 Create runner 按钮,即可进入到创建配置命令界面,拷贝其配置命令参数,如我这里的是</p>
<pre><code class="language-csharp">gitlab-runner register
--url https://gitlab.lindexi.com
--token glrt-HbCpfssbPSFqR_xVtxLX
</code></pre>
<p>于是我在运行起来的 docker 命令行里面输入以下命令用于注册</p>
<pre><code>/usr/share/gitlab/gitlab-runner register --url https://gitlab.lindexi.com --token glrt-HbCpfssbPSFqR_xVtxLX
</code></pre>
<p>输入之后,一路都是回车下一步,除了执行命令部分可选使用 shell 之外。完成之后再使用 <code>/usr/share/gitlab/gitlab-runner run</code> 命令运行起来试试,如果能够运行成功,且在 gitlab 的 runner 页面里面能够看到运行起来的 runner 则证明成功。否则还请自行调试哈,我也不熟悉</p>
<p>完成之后即可愉快退出 docker 环境,此时即可在挂载到 <code>/etc/gitlab-runner</code> 的文件夹里面,即本文的 <code>C:\lindexi\wsl</code> 文件夹里面看到配置文件,一般是 <code>config.toml</code> 文件</p>
<p>在上述步骤完成之后,咱可以取出来挂载的文件夹,如我这里的 <code>C:\lindexi\wsl</code> 文件夹,将其拷贝到 Dockerfile 文件所在的文件夹里面,用于编写 Dockerfile 拷贝到 <code>/etc/gitlab-runner</code> 文件夹里面,如此制作出来的 docker image 将会带上已经注册的 gitlab runner 信息</p>
<pre><code>COPY wsl /etc/gitlab-runner
</code></pre>
<p>接着再执行安装命令,以及设置入口为 gitlab-runner run 即可</p>
<pre><code>RUN /usr/share/gitlab/gitlab-runner install --user=root --working-directory=/root/.local/share/gitlab

ENTRYPOINT ["/usr/share/gitlab/gitlab-runner", "run"]
</code></pre>
<p>完成以后的 Dockerfile 文件如下</p>
<pre><code>FROM debian:buster-slim
WORKDIR /root

RUN rm /etc/apt/sources.list
COPY sources.list /etc/apt/sources.list
RUN apt-get update

RUN dpkg --add-architecture arm64
RUN apt update

RUN apt-get install libicu-dev -y
RUN apt-get install libssl-dev -y
RUN apt-get install wget -y
RUN apt-get install clang llvm -y
RUN apt-get install gcc-aarch64-linux-gnu -y
RUN apt-get install binutils-aarch64-linux-gnu -y
RUN apt-get install zlib1g-dev -y
RUN apt-get install zlib1g-dev:arm64 -y

RUN apt-get install vim -y
RUN apt-get install git -y

RUN apt-get clean

ADD dotnet-sdk-6.0.421-linux-x64.tar.gz ./dotnet
ADD dotnet-sdk-8.0.204-linux-x64.tar.gz ./dotnet
ENV DOTNET_ROOT="/root/dotnet"
ENV PATH="${PATH}:${DOTNET_ROOT}:${DOTNET_ROOT}/tools"
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
RUN ln -s /root/dotnet/dotnet /usr/bin/dotnet

COPY gitlab-runner-linux-amd64 /usr/share/gitlab/gitlab-runner

RUN chmod +x /usr/share/gitlab/gitlab-runner

COPY wsl /etc/gitlab-runner

RUN /usr/share/gitlab/gitlab-runner install --user=root --working-directory=/root/.local/share/gitlab

ENTRYPOINT ["/usr/share/gitlab/gitlab-runner", "run"]

RUN mkdir /root/build
WORKDIR /root/build
</code></pre>
<p>尝试构建此 Dockerfile 文件</p>
<pre><code>// 先 cd 到 Dockerfile 所在的文件夹,再执行以下命令
podman build -t t1 .
</code></pre>
<p>接着挂载到后台运行</p>
<pre><code>podman container run -v nuget_global:/root/.nuget/packages -v nuget_cache:/root/.local/share/NuGet -v gitlabrunner:/root/.local/share/gitlab -d t1
</code></pre>
<p>以上命令的 <code>-v nuget_global:/root/.nuget/packages -v nuget_cache:/root/.local/share/NuGet -v gitlabrunner:/root/.local/share/gitlab</code> 属于可选的参数,用来挂载 nuget 缓存等内容,解决 docker 每次重启都会丢失缓存文件,提升重启 docker 之后的构建速度,减少重复拉取 nuget 包</p>
<p>完成以上步骤之后,就已经完成了制作一个能构建 dotnet AOT 的 gitlab ruuner 的 Debian docker 镜像</p>
<p>可以尝试在自己的项目里面,编写 <code>.gitlab-ci.yml</code> 文件,指定到这个运行起来的 docker image 上运行,以下是我的测试使用的 <code>.gitlab-ci.yml</code> 文件代码</p>
<pre><code class="language-yml">stages:
- build

BuildLinuxX64InDocker:
stage: build
script:
    - 'dotnet run publish -p:PublishAot=true -c Release -r linux-x64'
tags:
    - docker-uos

BuildLinuxArm64InDocker:
stage: build
script:
    - 'dotnet run publish -p:PublishAot=true -c Release -r linux-arm64'
tags:
    - docker-uos
</code></pre>
<p>如果能够构建成功,且构建出 linux-x64 和 linux-arm64 的 dotnet 可执行文件,则表示成功。否则还请自行根据输出的错误信息修复</p>
<h2 id="踩坑记录">踩坑记录</h2>
<h3 id="为什么不在-wsl-里面构建">为什么不在 WSL 里面构建</h3>
<p>核心原因是 WSL 里面的 glibc 版本过于新,使用 <code>ldd --version</code> 命令可以看到的输出如下</p>
<pre><code>ldd (GNU libc) 2.36
</code></pre>
<p>而麒麟的 Desktop-V10-SP1 版本的 glibc 是 2.31 版本,更惨的 UOS 20.1050.11068.102 版本的 glibc 是 2.28 版本,都低于 WSL 里面的版本</p>
<p>这就意味着在 WSL 里面构建出来的应用将无法在以上的两个系统上运行</p>
<p>这就是为什么使用 <code>debian:buster-slim</code> 的原因。当前我拉取的 <code>debian:buster-slim</code> 的 docker image id 是 6d0d34a48ee1 的版本。通过 <code>cat /etc/debian_version</code> 可以看到在此版本里面带的是 debian 10.13 版本</p>
<p>再通过 <code>ldd --version</code> 命令行获取的 glibc 版本信息,可以看到带的是 2.28 版本,刚好与 UOS 20.1050.11068.102 版本的 glibc 版本相同,低于麒麟的 Desktop-V10-SP1 的 glibc 版本</p>
<p>因此在此 <code>debian:buster-slim</code> 里面 AOT 构建出来的包可以同时在 UOS 20.1050.11068.102 和麒麟的 Desktop-V10-SP1 版本运行</p>
<h3 id="debian-buster-backports-release-does-not-have-a-release-file">debian buster-backports Release does not have a Release file</h3>
<p>开始国内源使用了阿里的,结果遇到以下错误内容</p>
<pre><code>E: The repository 'http://mirrors.aliyun.com/debian buster-backports Release' does not have a Release file.
Error: building at STEP "RUN apt update": while running runtime: exit status 100
</code></pre>
<p>重新参考了 替换docker容器默认的debian镜像 - OrcHome 博客,结果依然配置失败。核心原因是配置的版本不正确</p>
<p>我当前使用的是 debian 是 10.13 版本,需要根据 debian镜像_debian下载地址_debian安装教程-阿里巴巴开源镜像站 教程文档,更新对应的 <code>debian 10.x (buster)</code> 的配置</p>
<p>我是如何知道 debian 版本的,我通过运行镜像,输入 <code>cat /etc/debian_version</code> 命令获取到版本</p>
<h3 id="no-system-certificates-available">No system certificates available</h3>
<p>完成配置阿里的源,遇到以下的错误内容</p>
<pre><code>W: https://mirrors.aliyun.com/debian/dists/buster/InRelease: No system certificates available. Try installing ca-certificates.
</code></pre>
<p>原因是 ca-certificates 没有提前安装,可以在切换为国内源之前,安装好。安装方法可参阅 修复 Debian 安装 dotnet 失败 depends on ca-certificates</p>
<p>由于我这里不需要关注安全性问题,更简单的方法是将 https 全部更换为 http 即可</p>
<h3 id="安装-dotnet-tool-失败">安装 dotnet tool 失败</h3>
<p>执行任何的 dotnet tool install 都会提示如下错误</p>
<pre><code>Unhandled exception: System.IO.FileNotFoundException: Unable to find the specified file.
   at Interop.Sys.GetCwdHelper(Byte* ptr, Int32 bufferSize)
   at Interop.Sys.GetCwd()
   at Microsoft.DotNet.Cli.ToolPackage.ToolPackageDownloader..ctor(IToolPackageStore store, String runtimeJsonPathForTests)
   at Microsoft.DotNet.ToolPackage.ToolPackageFactory.CreateToolPackageStoresAndDownloader(Nullable`1 nonGlobalLocation, IEnumerable`1 additionalRestoreArguments)
   at Microsoft.DotNet.Tools.Tool.Update.ToolUpdateLocalCommand..ctor(ParseResult parseResult, IToolPackageDownloader toolPackageDownloader, IToolManifestFinder toolManifestFinder, IToolManifestEditor toolManifestEditor, ILocalToolsResolverCache localToolsResolverCache, IReporter reporter)
   at Microsoft.DotNet.Tools.Tool.Update.ToolUpdateCommand..ctor(ParseResult result, IReporter reporter, ToolUpdateGlobalOrToolPathCommand toolUpdateGlobalOrToolPathCommand, ToolUpdateLocalCommand toolUpdateLocalCommand)
   at Microsoft.DotNet.Cli.ToolUpdateCommandParser.&lt;&gt;c.&lt;ConstructCommand&gt;b__14_0(ParseResult parseResult)
   at System.CommandLine.Invocation.InvocationPipeline.Invoke(ParseResult parseResult)
   at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, TimeSpan startupTime, ITelemetry telemetryClient)
</code></pre>
<p>暂时没有找到可用方法,只能绕路</p>
<p>我在 windows 下将所需工具下载下来,然后通过拷贝进入的方式即可完全安装</p>
<p>当然,在本文例子里面,我没有加上我所使用的工具</p>
<h3 id="在-gitlab-构建脚本找不到-dotnet-命令">在 gitlab 构建脚本找不到 dotnet 命令</h3>
<p>在命令行里面,可以使用 dotnet 命令,但是在 <code>.gitlab-ci.yml</code> 文件里面编写的脚本找不到 dotnet 命令</p>
<p>加上如下配置到 Dockerfile 即可</p>
<pre><code>RUN ln -s /root/dotnet/dotnet /usr/bin/dotnet
</code></pre>
<p>以上命令是对 dotnet 建立链接,如此即可让全局可以使用 dotnet 命令</p>
<h3 id="为什么使用-podman-工具">为什么使用 podman 工具</h3>
<p>原因是在 windows 下的 docker desktop 是收费的,于是我用平替的 podman 工具</p>
<h3 id="还原速度过慢">还原速度过慢</h3>
<p>由于 docker 本身是不带持久化存储文件,只有通过挂载本机存储的方式,才能让 docker 里面的文件持久化存放</p>
<p>还原速度过慢的问题,是因为初始化时没有任何的 NuGet 缓存,导致需要大量拉取,从而导致拉取过慢</p>
<p>根据 How to manage the global packages, cache, temp folders in NuGet - Microsoft Learn 官方文档说明,获取到默认的缓存路径,使用如下命令将缓存路径挂载到本机</p>
<pre><code>-v nuget_global:/root/.nuget/packages -v nuget_cache:/root/.local/share/NuGet
</code></pre>
<p>我这里挂载写的是相对路径,如 <code>nuget_global</code> 等路径,相对路径在 podman 下将会存放到 wsl 里面,详细请看 在 windows 上运行的 podman 默认的挂载相对路径是什么</p>
<h3 id="为什么代码仓库路径不挂载">为什么代码仓库路径不挂载</h3>
<p>如上述还原速度过慢原因,由于 docker 本身是不带持久化存储文件,只有通过挂载本机存储的方式,才能让 docker 里面的文件持久化存放。有些伙伴认为将代码仓库路径也进行本机挂载,可以减少拉取代码仓库的时间。实际上这么做可能带来的后果是开启多 docker 容器时,出现构建过程中的相互影响问题</p>
<p>拉取代码仓库时,大部分时间都是拉取内网的,且只影响容器的重启后的首次拉取。因此挂在代码仓库不是必要的</p>
<p>挂载代码仓库可能受到 Windows 自带杀毒影响,导致 llvm-objcopy 这一步失败,大概的错误信息如下</p>
<pre><code>llvm-objcopy: failed to open xx.dbg Input/output error.

/root/.nuget/packages/microsoft.dotnet.ilcompiler/8.0.4/build/Microsoft.NETCore.Native.targets(379,5): error MSB3073: The command ""llvm-objcopy" --only-keep-debug xx xx exited with code 1.
</code></pre>
<p>解决方法是要么不挂载,要么在 Windows 自带杀毒加白名单</p>
<h3 id="如何使用交叉编译">如何使用交叉编译</h3>
<p>由于我缺少 ARM64 的机器,或者准确来说我缺少一台可以撑住构建的有性能的 ARM64 的机器,我期望能够在原有的 linux-x64 机器上构建出 ARM64 的应用。于是我就需要使用到交叉编译技术,通过此技术我就可以在 linux-x64 的机器上构建出 linux-arm64 的应用</p>
<p>参考 Cross-compilation - .NET - Microsoft Learn 的文档安装上必要的负载,如下面的 docker 代码,即可在 debian 的 x64 系统上构建出 ARM64 的 dotnet 的 AOT 应用</p>
<pre><code>RUN dpkg --add-architecture arm64
RUN apt update

RUN apt-get install libicu-dev -y
RUN apt-get install libssl-dev -y
RUN apt-get install wget -y
RUN apt-get install clang llvm -y
RUN apt-get install gcc-aarch64-linux-gnu -y
RUN apt-get install binutils-aarch64-linux-gnu -y
RUN apt-get install zlib1g-dev -y
RUN apt-get install zlib1g-dev:arm64 -y
</code></pre>
<p>在进行 dotnet 发布时,将在 dotnet 里面自动根据 -r 参数自动执行交叉编译,如下面命令</p>
<pre><code>dotnet publish -p:PublishAot=true -c Release -r linux-arm64
</code></pre>
<p>相关文档请看 runtime/docs/workflow/building/libraries/cross-building.md at main · dotnet/runtime 和 runtime/docs/workflow/building/coreclr/cross-building.md at main · dotnet/runtime</p>
<h3 id="为什么不使用-gitlab-runner-start-命令">为什么不使用 gitlab-runner start 命令</h3>
<p>因为实际测试 gitlab-runner start 之后没有真的执行,如下面代码</p>
<pre><code>RUN /usr/share/gitlab/gitlab-runner start
</code></pre>
<p>添加之后运行 docker image 也不会有 gitlab runner 上线</p>
<p>如果换成下面的代码,则启动 docker image 之后立刻退出</p>
<pre><code>ENTRYPOINT ["/usr/share/gitlab/gitlab-runner", "start"]
</code></pre>
<p>实际测试只有以下代码符合预期</p>
<pre><code>ENTRYPOINT ["/usr/share/gitlab/gitlab-runner", "run"]
</code></pre>
<h3 id="找不到-runner-机器或找错">找不到 runner 机器或找错</h3>
<p>先调查是否 dotnet 配置 Gitlab 的 CI 找不到 Runner 或找错的可能原因 提及的问题</p>
<p>排除之后,记得查看是否带上了 <code>tags</code> 和 runner 在 gitlab 上配置正确且相同的</p>
<h3 id="参考文档">参考文档</h3>
<ul>
<li>https://github.com/dotnet/runtime/blob/main/src/coreclr/nativeaot/docs/compiling.md#cross-architecture-compilation</li>
<li>dotnet publish command - .NET CLI - Microsoft Learn</li>
<li>.NET Runtime Identifier (RID) catalog - .NET - Microsoft Learn</li>
<li>Cross-compilation - .NET - Microsoft Learn</li>
<li>Prepare .NET libraries for trimming - .NET - Microsoft Learn</li>
<li>How to manage the global packages, cache, temp folders in NuGet - Microsoft Learn</li>
<li>https://dotnet.microsoft.com/zh-cn/download/dotnet/8.0</li>
<li>Troubleshooting GitLab Runner - GitLab</li>
<li>docker Debian Buster 国内常用镜像源</li>
<li>docker - What is the difference between CMD and ENTRYPOINT in a Dockerfile? - Stack Overflow</li>
<li>How to fix 'buster-backports' no longer has a Release file - nixCraft</li>
<li>替换docker容器默认的debian镜像 - OrcHome</li>
<li>debian镜像_debian下载地址_debian安装教程-阿里巴巴开源镜像站</li>
<li>Configure GitLab Runner - GitLab</li>
<li>Install GitLab Runner - GitLab</li>
<li>Gitlab runner setup with podman - GitLab CI/CD - GitLab Forum</li>
<li>Registering runners - GitLab</li>
<li>Install GitLab Runner manually on GNU/Linux - GitLab</li>
<li>GitLab Runner bleeding edge releases - GitLab</li>
<li>NuGet pack and restore as MSBuild targets - Microsoft Learn</li>
<li>/usr/bin/dotnet: 没有那个文件或目录-CSDN博客</li>
<li>在 Linux ARM 系统上安装 .Net - 快乐就在你的心 的个人博客</li>
<li>dotnet 配置 Gitlab 的 Runner 做 CI 自动构建</li>
<li>dotnet 配置 Gitlab 的 CI 找不到 Runner 或找错的可能原因</li>
</ul>


</div>
<div id="MySignature" role="contentinfo">
    <p>博客园博客只做备份,博客发布就不再更新,如果想看最新博客,请访问 https://blog.lindexi.com/</p>

<p>如图片看不见,请在浏览器开启不安全http内容兼容</p>

<img alt="知识共享许可协议" style="border-width: 0" src="https://licensebuttons.net/l/by-nc-sa/4.0/88x31.png"><br>本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名[林德熙](https://www.cnblogs.com/lindexi)(包含链接:https://www.cnblogs.com/lindexi ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我[联系](mailto:lindexi_gd@163.com)。<br><br>
来源:https://www.cnblogs.com/lindexi/p/18164886
頁: [1]
查看完整版本: 制作一个能构建 dotnet AOT 的 gitlab runner 的 Debian docker 镜像