[英]dotnet publish with new implicit dockerfile feature using NuGet Microsoft.NET.Build.Containers fails in GitLab cicd
I am trying out the new NuGet package Microsoft.NET.Build.Containers which allows building docker image with do.net publish .我正在试用新的 NuGet package Microsoft.NET.Build.Containers ,它允许使用do.net publish构建 docker 图像。
Microsoft Docs: https://learn.microsoft.com/en-us/do.net/core/docker/publish-as-container?view=vs-2022微软文档: https://learn.microsoft.com/en-us/do.net/core/docker/publish-as-container?view=vs-2022
It works fine on local machine pushing out an image locally as it should but fails in GitLab cicd.它在本地机器上工作正常,可以在本地推送图像,但在 GitLab cicd 中失败。
Project (added following to a sln file):项目(添加到 sln 文件中):
# create a new project and move to its directory
dotnet new mvc -n my-awesome-container-app
cd my-awesome-container-app
# add a reference to a (temporary) package that creates the container
dotnet add package Microsoft.NET.Build.Containers
# publish your project for linux-x64
dotnet publish --os linux --arch x64 -c Release -p:PublishProfile=DefaultContainer
# run your app using the new container
docker run -it --rm -p 5010:80 my-awesome-container-app:1.0.0
Cicd pipeline: CICD管道:
image: mcr.microsoft.com/dotnet/sdk:7.0
stages: # List of stages for jobs, and their order of execution
- publish
build-job: # This job runs in the build stage, which runs first.
stage: publish
script:
- dotnet publish --os linux --arch x64 --configuration Release -p:PublishProfile=DefaultContainer
The error produced (omitted repo):产生的错误(省略回购):
MSBuild version 17.4.1+9a89d02ff for .NET
Determining projects to restore...
Restored /builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj (in 827 ms).
my-awesome-container-app -> /builds/.../dotnetpublishdockerimage/my-awesome-container-app/bin/Release/net7.0/linux-x64/my-awesome-container-app.dll
my-awesome-container-app -> /builds/.../dotnetpublishdockerimage/my-awesome-container-app/bin/Release/net7.0/linux-x64/publish/
Building image 'my-awesome-container-app' with tags 1.0.0 on top of base image mcr.microsoft.com/dotnet/aspnet:7.0
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018: The "CreateNewImage" task failed unexpectedly. [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018: System.AggregateException: One or more errors occurred. (An error occurred trying to start process 'docker' with working directory '/builds/.../dotnetpublishdockerimage/my-awesome-container-app'. No such file or directory) [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018: ---> System.ComponentModel.Win32Exception (2): An error occurred trying to start process 'docker' with working directory '/builds/.../dotnetpublishdockerimage/my-awesome-container-app'. No such file or directory [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018: at System.Diagnostics.Process.ForkAndExecProcess(ProcessStartInfo startInfo, String resolvedFilename, String[] argv, String[] envp, String cwd, Boolean setCredentials, UInt32 userId, UInt32 groupId, UInt32[] groups, Int32& stdinFd, Int32& stdoutFd, Int32& stderrFd, Boolean usesTerminal, Boolean throwOnNoExec) [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018: at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo) [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018: at System.Diagnostics.Process.Start(ProcessStartInfo startInfo) [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018: at Microsoft.NET.Build.Containers.LocalDocker.Load(Image x, String name, String tag, String baseName) in D:\a\_work\1\s\Microsoft.NET.Build.Containers\LocalDocker.cs:line 19 [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018: --- End of inner exception stack trace --- [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018: at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018: at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018: at System.Threading.Tasks.Task.Wait() [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018: at Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Execute() in D:\a\_work\1\s\Microsoft.NET.Build.Containers\CreateNewImage.cs:line 243 [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018: at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute() [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018: at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask) [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
Searching for a possible solution I came across and article for it for GitHub actions and it also works there.在寻找可能的解决方案时,我遇到了 GitHub 操作文章,它也适用于此。 Also the example in there I have used for this questions project.
还有我在这个问题项目中使用的例子。
Article: https://devblogs.microsoft.com/do.net/announcing-builtin-container-support-for-the-do.net-sdk/文章: https://devblogs.microsoft.com/do.net/announcing-builtin-container-support-for-the-do.net-sdk/
Also the GitLab runner is using Docker executor. GitLab 跑步者也使用 Docker 执行者。 Perhaps it doesn't work inside a container.
也许它在容器内不起作用。 The article for GitHub shows ubuntu-latest but I do not know if it is running in a container underneath or not.
GitHub 的文章显示 ubuntu-latest 但我不知道它是否在下面的容器中运行。
Anyone know what is going on and have a solution?任何人都知道发生了什么并有解决方案?
Looking further into it I found the issue and a solution as well.进一步研究我发现了问题和解决方案。
There are 2 problems here.这里有两个问题。
To deal with the first problem there are a couple of changes needed.要处理第一个问题,需要进行一些更改。
First add dnid as a service in cicd:首先在cicd中添加dnid作为服务:
services:
- docker:dind
Nex assign the docker host variable:接下来分配 docker 主机变量:
variables:
DOCKER_HOST: tcp://docker:2375/
And finally to enable privileged mode on docker runner (config.toml):最后在 docker runner (config.toml) 上启用特权模式:
[[runners]]
...
[runners.docker]
...
privileged = true
...
Restart of docker runner may be required.可能需要重启 docker runner。
There can also be an issue with tls. tls 也可能存在问题。 It can be ignored (although not advised for privileged mode) by adding empty certs dir to cicd:
可以通过将空证书目录添加到 cicd 来忽略它(尽管不建议特权模式):
variables:
DOCKER_TLS_CERTDIR: ""
The deal with the second problem an alternative is to use the image 'docker' which provides dind support.处理第二个问题的另一种方法是使用提供 dind 支持的图像“docker”。 From this there are 2 options:
由此有 2 个选项:
before_script:
- apk add dotnet7-sdk
Official docs: https://learn.microsoft.com/en-us/do.net/core/install/linux-alpine官方文档: https://learn.microsoft.com/en-us/do.net/core/install/linux-alpine
There may be other more elegant ways to solve this but it will do as a workaround.可能有其他更优雅的方法来解决这个问题,但它会作为一种解决方法。
A sample cicd pipeline including publishing to registry:示例 cicd 管道,包括发布到注册表:
stages:
- publish
variables:
DOCKER_HOST: tcp://docker:2375/
DOCKER_TLS_CERTDIR: ""
services:
- docker:dind
docker_test:
stage: publish
image: docker
before_script:
- apk add dotnet7-sdk
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- dotnet publish --os linux --arch x64 --configuration Release -p:PublishProfile=DefaultContainer
- IMAGE_ID=$(docker images --format='{{.ID}}' | head -1)
- docker tag $IMAGE_ID $CI_REGISTRY_IMAGE/my-image:1.0.0
- docker push $CI_REGISTRY_IMAGE/my-image:1.0.0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.