在 dotnet runtime 的容器中安装 dotnet global tool
在 dotnet runtime 的容器中安裝 dotnet global tool
Intro
.NET Core 從 2.1 開始支持 Global tool, 借助 global tool 我們可以通過命令行來實現很多功能,微軟提供的一系列的 dotnet 診斷工具也都提供了 global tool,我們可以通過 global tool 比較方便的進行使用,
但是 global tool 默認是只能裝了 SDK 之后才能裝,在實際的生產環境我們一般都是使用只包含 runtime 的 docker 鏡像,沒有 SDK 就不能直接安裝 global tool,那我們要怎么做才能在只有 runtime 的 docker 鏡像中使用 global tool 呢?且看下面的介紹
Global tool
dotnet global tool 是框架依賴發布的,所以是需要依賴運行時的,如果 dotnet tool 依賴的運行時找不到的時候,會嘗試使用高版本的 runtime,遵循前滾(roll-forward)規則
應用程序前滾至指定的主要版本和次要版本的最高修補程序版本。
如果主要版本號和次要版本號沒有匹配的運行時,則使用下一個較高的次要版本。
前滾不會發生在 runtime 的預覽版本,也不會發生在預覽版和正式版之間。因此,使用預覽版創建的 .NET ?global tool 必須由作者重新生成和重新發布,再重新安裝。
在下面兩種常見的場景下默認不會發生 roll-forward :
只有低版本運行時可用時,roll-forward 只會選擇之后的版本,低版本不會被選擇
只有更高的主要版本運行時可用時,roll-forward 默認不會跨越主要版本的邊界,主要版本發生變化有些 API 可能會有不兼容的變更
如果找不到一個合適的 runtime 版本,會運行失敗并拋出錯誤信息。
我們可以通過 dotnet --info 或者 dotnet --list-runtimes 來查看已有的 runtime 信息
Install dotnet global tool
通過 dotnet tool install --global dotnet-dump 我們就可以安裝 dotnet-dump 這個 global tool 了,但是就像前面提到的,我們必須要安裝 SDK 才能安裝 global tool,但是其實 global tool 運行的時候只依賴于 runtime,這就有點“悖論”了,明明我只需要 Runtime 就可以運行的,但是要安裝 SDK 才能安裝,在 Github 上提了一個 issue,有需要的可以關注一下:https://github.com/dotnet/sdk/issues/18168
在網上 Google 之后就會發現有一些解決方案,大體上分為兩類,一種是直接安裝 SDK 或使用 SDK 的環境,第二種則是在 SDK 的環境下安裝 global tool,裝好之后把 global tool 拷貝到只有 runtime 的環境中
Docker practice
在 docker 環境中,我們可以結合默認的多階段構建的方案,在 build 鏡像中安裝 dotnet global tool,在最后拷貝發布內容的時候同時也拷貝 dotnet global tool
Dockerfile 示例如下:
FROM?mcr.microsoft.com/dotnet/sdk:5.0-alpine?AS?build-env WORKDIR?/app#?install?dotnet?tool RUN?dotnet?tool?install?--global?dotnet-dumpCOPY?SparkTodo.Shared/SparkTodo.Shared.csproj?SparkTodo.Shared/ COPY?SparkTodo.API/SparkTodo.API.csproj?SparkTodo.API/ RUN?dotnet?restore?SparkTodo.API/SparkTodo.API.csproj#?copy?everything?and?build COPY?.?.WORKDIR?/app/SparkTodo.API RUN?dotnet?publish?-c?Release?-o?out#?build?runtime?image FROM?mcr.microsoft.com/dotnet/aspnet:5.0-alpine LABEL?Maintainer="WeihanLi" WORKDIR?/app COPY?--from=build-env?/app/SparkTodo.API/out?. COPY?--from=build-env?/root/.dotnet/tools?/root/.dotnet/tools ENV?PATH="/root/.dotnet/tools:${PATH}" EXPOSE?80 ENTRYPOINT?["dotnet",?"SparkTodo.API.dll"]通過多階段構建的方式,我們可以避免直接使用特別大的 SDK 鏡像,通過這種方式安裝 dotnet tool 鏡像只會增加幾十M的大小(我裝了一個 dotnet-dump,具體還是要看 dotnet tool 的大小)
通過 docker run --rm --name sparktodo sparktodo-api 運行一個容器,然后通過 docker exec -it sparktodo sh 進入到容器內部,然后就可以測試我們安裝的 dotnet global tool 了
可以看到我們安裝的 dotnet global tool 已經可以正常使用了
More
我們在 Dockerfile 里安裝了 dotnet global tool 并使用了默認的 dotnet tool 的路徑,并配置了環境變量以便于可以直接使用 dotnet global tool,如果需要也可以配置 dotnet tool 的安裝路徑,通過 dotnet tool install --global dotnet-dump --tool-path /usr/bin 來指定自定義的路徑
References
https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools
https://docs.microsoft.com/en-us/dotnet/core/tools/troubleshoot-usage-issues
https://docs.microsoft.com/en-us/dotnet/core/deploying/#publish-framework-dependent
https://andrewlock.net/running-net-core-global-tools-in-non-sdk-docker-images/
https://github.com/dotnet/sdk/issues/18168
https://github.com/WeihanLi/SparkTodo/blob/master/Dockerfile
總結
以上是生活随笔為你收集整理的在 dotnet runtime 的容器中安装 dotnet global tool的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WPF Grid添加边框的两种方法
- 下一篇: WeihanLi.Npoi 1.18.0