主頁 > .NET開發 > 將 ASP.Net Core WebApi 應用打包至 Docker 鏡像

將 ASP.Net Core WebApi 應用打包至 Docker 鏡像

2021-11-13 07:14:01 .NET開發

將 ASP.Net Core WebApi 應用打包至 Docker 鏡像

運行環境為 Windows 10 專業版 21H1, Docker Desktop 3.6.0(67351),Docker Engine 20.10.8

1. ASP.Net Core Runtime 還是 .Net Core Runtime

在這里首先要區分一下 SDK 和 Runtime 的區別,SDK (Software Development Kit)主要是在開發程序中使用的,而 Runtime 是在實際運行的時候使用的(類似于 JDK 和 JRE 的關系),所以對于我們這種發布后運行的情況,Runtime 就足夠了,

一開始沒有分清楚 ASP.Net Core Runtime,和 .Net Core Runtime 的區別,導致自己的網站專案雖然拷貝進了鏡像但一直提示缺少運行時,ASP 的全稱是 Active Server Pages,顧名思義,是用于動態網頁的,所以網站應用要使用 ASP.Net Core Runtime;而 .NET Core Runtime 一般是用于控制臺應用的;還有一個類似的 .NET Desktop Runtime 一般是用于 Windows 桌面應用的,詳細可以參見微軟的 .NET 下載頁面 ,

2. ASP.NET Core WebApi 應用的編譯

雖然前兩天 .NET 6.0 發布了,也是 LTS,但此處還是使用 .NET Core 3.1 哈

新建一個 ASP.NET Core WebApi 應用,在 Controllers 檔案夾里面添加一個 HelloWorldController,并且在 appSettings.json 中添加一個配置項 WelcomeStr

HelloWorldController.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;

namespace HelloWorldWebApplication.Controllers
{
    [ApiController]
    [Route("[controller]/[action]")]
    public class HelloWorldController
    {
        private readonly IConfiguration Configuration;

        public HelloWorldController(IConfiguration configuration)
        {
            this.Configuration = configuration;
        }

        [HttpGet]
        public string Hello()
        {
            return Configuration.GetSection("WelcomeStr").Value;
        }
    }
}

appSettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "WelcomeStr": "Hello ASP.NET Core 3.1!"	# 新增部分
}

功能也比較簡單,回傳一個在組態檔中定義的歡迎語,控制器中的依賴注入相關內容在此處就不細講了,運行一下看一下本地的效果:

接下來就是本地發布了,右鍵專案選擇發布,選擇發布到檔案夾,配置項的 Debug 和 Release、目標框架 自不用多說,關于“部署模式”,框架依賴 的意思是,發布的內容必須要在安裝了相應運行環境的機器上才能運行(正是我們打包至Docker想要的),而獨立 的意思是,即使機器沒有安裝相應的運行環境,也可以運行,對于目標運行時,如果我們要打包到 Docker 的 Linux x64 鏡像中,應當選擇 linux-x64,點擊“發布”,在專案的根目錄中,依次進入 bin\Release\netcoreapp3.1\publish,這里面的檔案就是發布后的檔案,我們要將它們打包進鏡像,

3. Dockerfile 的創建與打包

準備作業的最后一步了,注意檔案名稱一定要是 Dockerfile,鄙人一開始使用 VS Code 新建了一個 .dockerfile 檔案,在使用 docker 構建命令時一直提示沒有構建檔案,

Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:3.1-focal
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone
RUN mkdir /HelloWorldWebApplication
COPY ./ /HelloWorldWebApplication
EXPOSE 80
WORKDIR /HelloWorldWebApplication
CMD ["/bin/bash","-c","./HelloWorldWebApplication"]

這里面的注意點就比較多了,我們逐個來說

第 1 行,使用 From 選擇基礎鏡像,所有的選項可以參見 ASP.NET Core Runtime 的 DockerHub 頁面,此處選用的是基于 Ubuntu、 運行時版本是 3.1 的鏡像,后面的 focal 其實對應的作業系統的代號,即 Ubuntu 20.04 Focal Fossa(類似的 Buster 是 Debian 10 的代號),如果希望鏡像盡可能的小,可以使用 alpine 鏡像(這里選用 Ubuntu 鏡像主要是為了個人的操作方便,比如按下別名 ll 就可以執行對應命令 ls -l,alpine 鏡像雖然小,但很多常用命令、功能都沒有)

第 2 ~ 3 行設定時區,如果使用的是 alpine 鏡像,需要手動拷貝時區檔案

第 4 行,在容器中創建目錄,一開始的時候沒寫這行,導致后面的 COPY 找不到檔案夾了,這可不像是 docker cp 可以自動在容器中創建檔案夾啊,

第 5 行,使用 COPY 命令復制,切記在 源路徑中不要使用 *,如 COPY * /HelloWorldWebApplication,因為這會忽略第一層的檔案夾,假設我們當前目錄是這樣的(多了wwwroot):

│ appsettings.Development.json
│ appsettings.json
│ Dockerfile
│ HelloWorldWebApplication
│ HelloWorldWebApplication.deps.json
│ HelloWorldWebApplication.dll
│ HelloWorldWebApplication.pdb
│ HelloWorldWebApplication.runtimeconfig.json
│ web.config

└─wwwroot
                  index.html

復制進去后,wwwroot 檔案夾已經沒了:

root@f659a7e407e1:/HelloWorldWebApplication# ll
total 264
drwxr-xr-x 1 root root 4096 Nov 12 02:54 ./
drwxr-xr-x 1 root root 4096 Nov 12 02:55 ../
-rwxr-xr-x 1 root root 216 Nov 12 02:54 Dockerfile*
-rwxr-xr-x 1 root root 90680 Nov 12 02:24 HelloWorldWebApplication*
-rwxr-xr-x 1 root root 114406 Nov 12 02:24 HelloWorldWebApplication.deps.json*
-rwxr-xr-x 1 root root 8704 Nov 12 02:24 HelloWorldWebApplication.dll*
-rwxr-xr-x 1 root root 19932 Nov 12 02:24 HelloWorldWebApplication.pdb*
-rwxr-xr-x 1 root root 311 Nov 12 02:24 HelloWorldWebApplication.runtimeconfig.json*
-rwxr-xr-x 1 root root 162 Nov 12 01:49 appsettings.Development.json*
-rwxr-xr-x 1 root root 236 Nov 12 01:56 appsettings.json*
-rwxr-xr-x 1 root root 0 Nov 12 02:47 index.html*
-rwxr-xr-x 1 root root 545 Nov 12 02:24 web.config*

第 6 行,使用 EXPOSE 指明應當映射的埠,為什么這個埠一定是 80 呢,我就是想使用 8001 呢,這是在 ASP.NET Core 3.1 Runtime 鏡像中定義的環境變數,可以進入容器,使用 env 命令查看,可以發現:

所以如果想修改埠,在 Dockerfile 添加如下指令即可

ENV ASPNETCORE_URLS=http://+:5000

第 7 行,使用 WORKDIR 切換作業路徑,如果不切換作業路徑,則會找不到組態檔,如修改 Dockerfile,洗掉該行,并修改最后一行(需要指定執行檔案的路徑)為:

CMD ["/bin/bash","-c","./HelloWorldWebApplication/HelloWorldWebApplication"]

再次訪問,可以看到沒有獲取到組態檔的內容:

第 8 行,使用 CMD 執行命令,我們可以直接執行 ./HelloWorldWebApplication,可別忘了是在 shell 中,所以要指定 /bin/bash 或 /bin/sh(和使用的具體作業系統鏡像有關,在 Ubuntu 中是 /bin/bash),也嘗試過使用 alpine,似乎直接執行并不奏效,需要執行的命令為 /bin/sh dotnet ./HelloWorldWebApplication.dll,

4. 運行

終于到最后的執行步驟了,在 Windows 的終端中切換目錄到專案的 publish 檔案夾中,執行 docker build -t helloworld_web:v1 . 生成最終的鏡像,使用 docker run -itd -p 5002:80 helloworld_web:v1 創建并運行容器(映射到 5002 埠),可以看到得到了與本地同樣的效果:

需要注意的是,此時使用的配置是 Production

后記:

這一路操作下來,雖然主要的思路沒毛病,但細節的東西還是不少的,終于把之前的 Docker 內容實際運用上了,

Docker Desktop 的功能也越來越完備了,現在可以查看構建 image 的 Dockerfile 檔案:

另外無意間看到了 Visual Studio 2019 中可以直接使用發布到 Docker 的功能, 有空嘗試下,

參考:

.NET Core 官方下載
https://dotnet.microsoft.com/download/dotnet/3.1

Asp.net core在docker容器中的埠問題
https://www.cnblogs.com/RandyField/p/13059985.html

Linux 下執行本目錄的可執行檔案(命令)為什么需要在檔案名前加“./”
https://www.cnblogs.com/fortunel/p/8663669.html

Docker COPY 復制檔案夾的詭異行為
https://www.jianshu.com/p/9b7da9aacd8a

Dockerfile復制時如何保留子目錄的結構
https://www.pkslow.com/archives/dockerfile-copy-keep-subdirectory-structure

linux的顯示全部環境變數
https://blog.csdn.net/weixin_39880318/article/details/116864978

ASP.NET Core 2.1 使用Docker運行
https://www.cnblogs.com/stulzq/p/9201830.html

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/356628.html

標籤:.NET技术

上一篇:Linxu+Docker+Gitee+Jenkins自動化部署.NET Core服務

下一篇:一看就懂的IdentityServer4認證授權設計方案

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more