在Raspberry Pi(ARM32)上的Docker中构建,运行和测试.NET Core和ASP.NET Core 2.1

2023-05-16

I love me some Raspberry Pi. They are great little learning machines and are super fun for kids to play with. Even if those kids are adults and they build a 6 node Kubernetes Raspberry Pi Cluster.

我爱我一些Raspberry Pi。 它们是很棒的小型学习机,非常适合孩子们玩耍。 即使这些孩子是成年人,他们也会建立一个6节点的Kubernetes Raspberry Pi Cluster 。

Open source .NET Core runs basically everywhere - Windows, Mac, and a dozen Linuxes. However, there is an SDK (that compiles and builds) and a Runtime (that does the actual running of your app). In the past, the .NET Core SDK (to be clear, the ability to "dotnet build") wasn't supported on ARMv7/ARMv8 chips like the Raspberry Pi. Now it is.

开源.NET Core基本上可在所有地方运行-Windows,Mac和十几个Linux。 但是,有一个SDK(用于编译和构建)和一个Runtime(用于实际运行您的应用)。 过去,像Raspberry Pi这样的ARMv7 / ARMv8芯片不支持.NET Core SDK(显然,“ dotnet构建”功能)。 现在它是。

.NET Core is now supported on Linux ARM32 distros, like Raspbian and Ubuntu!

.NET Core现在在RaspbianUbuntu等Linux ARM32发行版中受支持

Note: .NET Core 2.1 is supported on Raspberry Pi 2+. It isn’t supported on the Pi Zero or other devices that use an ARMv6 chip. .NET Core requires ARMv7 or ARMv8 chips, like the ARM Cortex-A53. Folks on the Azure IoT Edge team use the .NET Core Bionic ARM32 Docker images to support developers writing C# with Edge devices.

注意: Raspberry Pi 2+支持.NET Core 2.1。 Pi Zero或其他使用ARMv6芯片的设备不支持此功能。 .NET Core需要ARMv7或ARMv8芯片,例如ARM Cortex-A53 。 Azure IoT Edge团队的人们使用.NET Core仿生ARM32 Docker映像来支持开发人员使用Edge设备编写C# 。

There's two ways to run .NET Core on a Raspberry Pi.

有两种方法可以在Raspberry Pi上运行.NET Core。

One, use Docker. This is literally the fastest and easiest way to get .NET Core up and running on a Pi. It sounds crazy but Raspberry Pis are brilliant little Docker container capable systems. You can do it in minutes, truly. You can install Docker quickly on a Raspberry Pi with just:

一,使用Docker 实际上,这是在Pi上启动并运行.NET Core的最快,最简单的方法。 听起来很疯狂,但是Raspberry Pis是出色的支持Docker容器的小系统。 您可以在几分钟内真正做到这一点。 您可以使用以下命令在Raspberry Pi上快速安装Docker:

curl -sSL https://get.docker.com | sh
sudo usermod -aG docker pi

After installing Docker you'll want to log in and out. You might want to try a quick sample to make sure .NET Core runs! You can explore the available Docker tags at https://hub.docker.com/r/microsoft/dotnet/tags/ and you can read about the .NET Core Docker samples here https://github.com/dotnet/dotnet-docker/tree/master/samples/dotnetapp

安装Docker之后,您需要登录和注销。 您可能想尝试一个快速示例,以确保.NET Core能够运行! 你可以在浏览可用的泊坞窗标签https://hub.docker.com/r/microsoft/dotnet/tags/ ,你可以在这里阅读有关.NET核心泊坞样品https://github.com/dotnet/dotnet-码头工人/树/大师/样品/ dotnetapp

Now I can just docker run and then pass in "dotnet --info" to find out about dotnet on my Pi.

现在,我可以泊坞窗运行,然后传入“ dotnet --info”以在Pi上找到有关dotnet的信息。

pi@raspberrypi:~ $ docker run --rm -it microsoft/dotnet:2.1-sdk dotnet --info
.NET Core SDK (reflecting any global.json):
Version: 2.1.300-rc1-008673
Commit: f5e3ddbe73

Runtime Environment:
OS Name: debian
OS Version: 9
OS Platform: Linux
RID: debian.9-x86
Base Path: /usr/share/dotnet/sdk/2.1.300-rc1-008673/

Host (useful for support):
Version: 2.1.0-rc1
Commit: eb9bc92051

.NET Core SDKs installed:
2.1.300-rc1-008673 [/usr/share/dotnet/sdk]

.NET Core runtimes installed:
Microsoft.NETCore.App 2.1.0-rc1 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
https://aka.ms/dotnet-download

This is super cool. There I'm on the Raspberry Pi (RPi) and I just ask for the dotnet:2.1-sdk and because they are using "multiarch" docker files, Docker does the right thing and it just works. If you want to use .NET Core on ARM32 with Docker, you can use any of the following tags.

这太酷了。 我在Raspberry Pi(RPi)上,我只要求dotnet:2.1-sdk,因为它们使用的是“ multiarch” docker文件,所以Docker做正确的事情,并且可以正常工作。 如果要在带Docker的ARM32上使用.NET Core ,则可以使用以下任何标记。

Note: The first three tags are multi-arch and bionic is Ubuntu 18.04. The codename stretch is Debian 9. So I'm using 2.1-sdk and it's working on my RPi, but I can be specific if I'd prefer.

注意:前三个标签是多体系结构 仿生是Ubuntu 18.04。 代号Stretch是Debian9。所以我使用的是2.1-sdk,并且可以在我的RPi上使用,但是我可以具体说明。

  • 2.1-sdk

    2.1 SDK
  • 2.1-runtime

    2.1运行时
  • 2.1-aspnetcore-runtime

    2.1-aspnetcore-运行时
  • 2.1-sdk-stretch-arm32v7

    2.1-sdk-stretch-arm32v7
  • 2.1-runtime-stretch-slim-arm32v7

    2.1-运行时伸展-slim-arm32v7
  • 2.1-aspnetcore-runtime-stretch-slim-arm32v7

    2.1-aspnetcore-runtime-stretch-slim-arm32v7
  • 2.1-sdk-bionic-arm32v7

    2.1-sdk-bionic-arm32v7
  • 2.1-runtime-bionic-arm32v7

    2.1运行时仿生arm32v7
  • 2.1-aspnetcore-runtime-bionic-arm32v7

    2.1-aspnetcore-runtime-bionic-arm32v7

Try one in minutes like this:

在几分钟之内尝试如下操作:

docker run --rm microsoft/dotnet-samples:dotnetapp

Here it is downloading the images...

在这里下载图片...

In previous versions of .NET Core's Dockerfiles it would fail if you were running an x64 image on ARM:

在.NET Core的早期版本的Dockerfile中,如果在ARM上运行x64映像,它将失败:

standard_init_linux.go:190: exec user process caused "exec format error"

Different processors! But with multiarch per https://github.com/dotnet/announcements/issues/14 Kendra from Microsoft it just works with 2.1.

不同的处理器! 但是,对于来自Microsoft的https://github.com/dotnet/announcements/issues/14 Kendra的多体系结构,它仅适用于2.1。

Docker has a multi-arch feature that microsoft/dotnet-nightly recently started utilizing. The plan is to port this to the official microsoft/dotnet repo shortly. The multi-arch feature allows a single tag to be used across multiple machine configurations. Without this feature each architecture/OS/platform requires a unique tag. For example, the microsoft/dotnet:1.0-runtime tag is based on Debian and microsoft/dotnet:1.0-runtime-nanoserver if based on Nano Server. With multi-arch there will be one common microsoft/dotnet:1.0-runtime tag. If you pull that tag from a Linux container environment you will get the Debian based image whereas if you pull that tag from a Windows container environment you will get the Nano Server based image. This helps provide tag uniformity across Docker environments thus eliminating confusion.

Docker具有Microsoft / dotnet-nightly最近开始使用的多架构功能。 计划是不久将其移植到正式的Microsoft / dotnet存储库。 多体系结构功能允许在多个机器配置中使用单个标签。 没有此功能,每个架构/ OS /平台都需要唯一的标签。 例如,microsoft / dotnet:1.0-runtime标签基于Debian,而microsoft / dotnet:1.0-runtime-nanoserver基于Nano Server。 对于多体系结构,将有一个常见的microsoft / dotnet:1.0-runtime标签。 如果从Linux容器环境中提取该标签,则将获得基于Debian的映像,而如果从Windows容器环境中提取该标签,则将得到基于Nano Server的映像。 这有助于在整个Docker环境中提供标签统一性,从而消除混乱。

In these examples above I can:

在以上这些示例中,我可以:

  • Run a preconfigured app within a Docker image like:

    在Docker映像中运行预配置的应用程序,例如:

    • docker run --rm microsoft/dotnet-samples:dotnetapp

      docker运行--rm microsoft / dotnet-samples:dotnetapp
  • Run dotnet commands within the SDK image like:

    在SDK映像中运行dotnet命令,例如:

    • docker run --rm -it microsoft/dotnet:2.1-sdk dotnet --info

      docker运行--rm -it microsoft / dotnet:2.1-sdk dotnet --info
  • Run an interactive terminal within the SDK image like:

    在SDK映像中运行交互式终端,例如:

    • docker run --rm -it microsoft/dotnet:2.1-sdk

      泊坞窗运行--rm -it microsoft / dotnet:2.1-sdk

As a quick example, here I'll jump into a container and new up a quick console app and run it, just to prove I can. This work will be thrown away when I exit the container.

作为一个简单的例子,在这里我将跳入一个容器并新建一个快速控制台应用程序并运行它,以证明我可以。 当我退出容器时,这项工作将被丢弃。

pi@raspberrypi:~ $ docker run --rm -it microsoft/dotnet:2.1-sdk
root@063f3c50c88a:/# ls
bin boot dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
root@063f3c50c88a:/# cd ~
root@063f3c50c88a:~# mkdir mytest
root@063f3c50c88a:~# cd mytest/
root@063f3c50c88a:~/mytest# dotnet new console
The template "Console Application" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on /root/mytest/mytest.csproj...
Restoring packages for /root/mytest/mytest.csproj...
Installing Microsoft.NETCore.DotNetAppHost 2.1.0-rc1.
Installing Microsoft.NETCore.DotNetHostResolver 2.1.0-rc1.
Installing NETStandard.Library 2.0.3.
Installing Microsoft.NETCore.DotNetHostPolicy 2.1.0-rc1.
Installing Microsoft.NETCore.App 2.1.0-rc1.
Installing Microsoft.NETCore.Platforms 2.1.0-rc1.
Installing Microsoft.NETCore.Targets 2.1.0-rc1.
Generating MSBuild file /root/mytest/obj/mytest.csproj.nuget.g.props.
Generating MSBuild file /root/mytest/obj/mytest.csproj.nuget.g.targets.
Restore completed in 15.8 sec for /root/mytest/mytest.csproj.

Restore succeeded.
root@063f3c50c88a:~/mytest# dotnet run
Hello World!
root@063f3c50c88a:~/mytest# dotnet exec bin/Debug/netcoreapp2.1/mytest.dll
Hello World!

If you try it yourself, you'll note that "dotnet run" isn't very fast. That's because it does a restore, build, and run. Compilation isn't super quick on these tiny devices. You'll want to do as little work as possible. Rather than a "dotnet run" all the time, I'll do a "dotnet build" then a "dotnet exec" which is very fast.

如果您自己尝试,您会注意到“ dotnet run”不是很快。 这是因为它可以还原,构建和运行。 在这些小型设备上编译不是超级快。 您将需要做的工作尽可能少。 我将始终执行“ dotnet构建”,然后执行“ dotnet exec”,而不是一直运行“ dotnet”。

If you're doing to do Docker and .NET Core, I can't stress enough how useful the resources are over at https://github.com/dotnet/dotnet-docker.

如果您正在做Docker和.NET Core,我无法在https://github.com/dotnet/dotnet-docker上过分强调资源的实用性

使用Docker构建.NET Core应用 (Building .NET Core Apps with Docker)

  • .NET Core Docker Sample - This sample builds, tests, and runs the sample. It includes and builds multiple projects.

    .NET Core Docker示例-此示例构建,测试和运行该示例。 它包括并构建多个项目。

  • ASP.NET Core Docker Sample - This sample demonstrates using Docker with an ASP.NET Core Web App.

    ASP.NET Core Docker示例-该示例演示了将Docker与ASP.NET Core Web App一起使用。

在容器中开发.NET Core应用 (Develop .NET Core Apps in a Container)

  • Develop .NET Core Applications - This sample shows how to develop, build and test .NET Core applications with Docker without the need to install the .NET Core SDK.

    开发.NET Core应用程序-此示例演示如何使用Docker开发,构建和测试.NET Core应用程序,而无需安装.NET Core SDK。

  • Develop ASP.NET Core Applications - This sample shows how to develop and test ASP.NET Core applications with Docker without the need to install the .NET Core SDK.

    开发ASP.NET Core应用程序-此示例演示如何使用Docker开发和测试ASP.NET Core应用程序,而无需安装.NET Core SDK。

优化容器尺寸 (Optimizing Container Size)

  • .NET Core Alpine Docker Sample - This sample builds, tests, and runs an application using Alpine.

    .NET Core Alpine Docker示例-该示例使用Alpine构建,测试和运行应用程序。

  • .NET Core self-contained Sample - This sample builds and runs an application as a self-contained application.

    .NET Core自包含示例-此示例构建并运行应用程序为自包含应用程序。

ARM32 /树莓派 (ARM32 / Raspberry Pi)

  • .NET Core ARM32 Docker Sample - This sample builds and runs an application with Debian on ARM32 (works on Raspberry Pi).

    .NET Core ARM32 Docker示例-该示例在ARM32上使用Debian构建并运行一个应用程序(在Raspberry Pi上运行)。

  • ASP.NET Core ARM32 Docker Sample - This sample builds and runs an ASP.NET Core application with Debian on ARM32 (works on Raspberry Pi).

    ASP.NET Core ARM32 Docker样本-该样本在ARM32上使用Debian构建并运行ASP.NET Core应用程序(在Raspberry Pi上运行)。

I found the samples to be super useful...be sure to dig into the Dockerfiles themselves as it'll give you a ton of insight into how to structure your own files. Being able to do Multistage Dockerfiles is crucial when building on a small device like a RPi. You want to do as little work as possible and let Docker cache as many layers with its internal "smarts." If you're not thoughtful about this, you'll end up wasting 10x the time building image layers every build.

我发现示例非常有用...请务必深入研究Dockerfile本身,因为它将使您对如何构建自己的文件有很多了解。 在像RPi这样的小型设备上进行构建时,能够执行多阶段Dockerfile至关重要。 您想要做的工作尽可能少,让Docker使用其内部“智能”缓存尽可能多的层。 如果您对此一无所知,最终将浪费10倍的时间来构建每个构建图像层。

通过测试对真正的ASP.NET Core网站进行Docker打包! (Dockerizing a real ASP.NET Core Site with tests!)

Can I take my podcast site and Dockerize it and build/test/run it on a Raspberry Pi? YES.

我可以带播客站点并对其进行Dockerize并在Raspberry Pi上构建/测试/运行它吗? 是。

FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /app

# copy csproj and restore as distinct layers
COPY *.sln .
COPY hanselminutes.core/*.csproj ./hanselminutes.core/
COPY hanselminutes.core.tests/*.csproj ./hanselminutes.core.tests/
RUN dotnet restore

# copy everything else and build app
COPY . .
WORKDIR /app/hanselminutes.core
RUN dotnet build


FROM build AS testrunner
WORKDIR /app/hanselminutes.core.tests
ENTRYPOINT ["dotnet", "test", "--logger:trx"]


FROM build AS test
WORKDIR /app/hanselminutes.core.tests
RUN dotnet test


FROM build AS publish
WORKDIR /app/hanselminutes.core
RUN dotnet publish -c Release -o out


FROM microsoft/dotnet:2.1-aspnetcore-runtime AS runtime
WORKDIR /app
COPY --from=publish /app/hanselminutes.core/out ./
ENTRYPOINT ["dotnet", "hanselminutes.core.dll"]

Love it. Now I can "docker build ." on my Raspberry Pi. It will restore, test, and build. If the tests fail, the Docker build will fail.

爱它。 现在我可以“ docker build”了。 在我的Raspberry Pi上。 它将还原,测试和构建。 如果测试失败,则Docker构建将失败。

See how there's an extra section up there called "testrunner" and then after it is "test?" That testrunner section is a no-op. It sets an ENTRYPOINT but it is never used...yet. The ENTRYPOINT is an implicit run if it is the last line in the Dockerfile. That's there so I can "Run up to it" if I want to.

看看那里还有一个名为“ testrunner”的额外部分,然后是“ test”吗? 该testrunner部分是禁止操作的。 它设置了一个ENTRYPOINT,但从未使用过... 如果ENTRYPOINT是Dockerfile中的最后一行,则它是隐式运行 在那里,所以我可以根据需要“运行”。

I can just build and run like this:

我可以像这样构建和运行:

docker build -t podcast .
docker run --rm -it -p 8000:80 podcast

NOTE/GOTCHA: Note that the "runtime" image is microsoft/dotnet:2.1-aspnetcore-runtime, not microsoft/dotnet:2.1-runtime. That aspnetcore one pre-includes the binaries I need for running an ASP.NET app, that way I can just include a single reference to "<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.0-rc1-final" />" in my csproj. If didn't use the aspnetcore-runtime base image, I'd need to manually pull in all the ASP.NET Core packages that I want. Using the base image might make the resulting image files larger, but it's a balance between convenience and size. It's up to you. You can manually include just the packages you need, or pull in the "Microsoft.AspNetCore.App" meta-package for convenience. My resulting "podcast" image ended up 205megs, so not to bad, but of course if I wanted I could trim in a number of ways.

注意/ GOTCHA:请注意,“运行时”映像是microsoft / dotnet:2.1-aspnetcore-runtime,而不是microsoft / dotnet:2.1-runtime。 该aspnetcore预先包含了运行ASP.NET应用程序所需的二进制文件,这样,我可以仅包含对“ <PackageReference Include =” Microsoft.AspNetCore.App“ Version =” 2.1.0-rc1-final我的csproj中的“ />”。 如果不使用aspnetcore-runtime基本映像,则需要手动提取所需的所有ASP.NET Core程序包。 使用基本图像可能会使生成的图像文件更大,但这是方便和大小之间的平衡。 由你决定。 您可以手动仅包含所需的程序包,或者为了方便起见插入“ Microsoft.AspNetCore.App”元程序包。 我生成的“播客”图像最终达到205兆,所以还不错,但是当然,如​​果我希望可以采用多种方式进行修整。

Or, if I JUST want test results from Docker, I can do this! That means I can run the tests in the Docker container, mount a volume between the Linux container and (theoretical) Window host, and then open the .trx resulting file in Visual Studio!

或者,如果我只是想要Docker的测试结果,我可以做到! 这意味着我可以在Docker容器中运行测试,在Linux容器和(理论上)Window主机之间安装一个卷,然后在Visual Studio中打开.trx结果文件!

docker build --pull --target testrunner -t podcast:test .
docker run --rm -v D:\github\hanselminutes-core\TestResults:/app/hanselminutes.core.tests/TestResults podcast:test

Check it out! These are the test results from the tests that ran within the Linux Container:

看看这个! 这些是Linux容器中运行的测试的测试结果:

Here's the result. I've now got my Podcast website running in Docker on an ARM32 Raspberry Pi 3 with just an hours' work (writing the Dockerfile)!

这是结果。 现在,我的Podcast网站在ARM32 Raspberry Pi 3上的Docker中运行,只需一个小时的工作(编写Dockerfile)!

Second - did you make it this far down? - You can just install the .NET Core 2.1 SDK "on the metal." No Docker, just get the tar.gz and set it up. Looking at the RPi ARM32v7 Dockerfile, I can install it on the metal like this. Note I'm getting the .NET Core SDK *and* the ASP.NET Core shared runtime. In the final release build you will just get the SDK and it'll include everything, including ASP.NET.

其次-您是否做到了这么低? -您可以仅在金属上安装.NET Core 2.1 SDK。 没有Docker,只需获取tar.gz并进行设置即可。 查看RPi ARM32v7 Dockerfile ,我可以像这样将其安装在金属上。 注意我正在获取.NET Core SDK *和* ASP.NET Core共享运行时。 在最终版本中,您将仅获得SDK,它将包含所有内容,包括ASP.NET。

$ sudo apt-get -y update
$ sudo apt-get -y install libunwind8 gettext
$ wget https://dotnetcli.blob.core.windows.net/dotnet/Sdk/2.1.300-rc1-008673/dotnet-sdk-2.1.300-rc1-008673-linux-arm.tar.gz
$ wget https://dotnetcli.blob.core.windows.net/dotnet/aspnetcore/Runtime/2.1.0-rc1-final/aspnetcore-runtime-2.1.0-rc1-final-linux-arm.tar.gz
$ sudo mkdir /opt/dotnet
$ sudo tar -xvf dotnet-sdk-2.1.300-rc1-008673-linux-arm.tar.gz -C /opt/dotnet/
$ sudo tar -xvf aspnetcore-runtime-2.1.0-rc1-final-linux-arm.tar.gz -C /opt/dotnet/
$ sudo ln -s /opt/dotnet/dotnet /usr/local/bin
$ dotnet --info

Cross-platform for the win!

跨平台取胜!

Sponsor: Check out JetBrains Rider: a cross-platform .NET IDE. Edit, refactor, test and debug ASP.NET, .NET Framework, .NET Core, Xamarin or Unity applications. Learn more and download a 30-day trial!

赞助商:查看JetBrains Rider:一个跨平台的.NET IDE 。 编辑,重构,测试和调试ASP.NET,.NET Framework,.NET Core,Xamarin或Unity应用程序。 了解更多信息并下载30天试用版!

翻译自: https://www.hanselman.com/blog/building-running-and-testing-net-core-and-aspnet-core-21-in-docker-on-a-raspberry-pi-arm32

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在Raspberry Pi(ARM32)上的Docker中构建,运行和测试.NET Core和ASP.NET Core 2.1 的相关文章

随机推荐