將.Net Core釋出至Docker,並連線 Redis、上傳檔案到本機、連線sqlserver資料庫

以往清泉發表於2020-12-27

此片文章目標是將 .Net Core 釋出到 Docker 上,並且連線到在 Docker上的 Redis 、上傳檔案到本機資料夾和連線 sqlserver 資料庫。

建立專案

建立專案就不用說了,我是用得 vs2019 建立的 net core 3.1 的專案,把上傳檔案、連線redis和sqlserver的程式碼寫好,因為我是在 window 環境下開發的,所以如果我們需要釋出到 linux 系統的話需要注意所有用到路徑的地方,比如我遇到的這幾個點:

1.儲存檔案地址

如下在 window 上儲存檔案的話地址是如下使用 '\' 的

// 新檔名(包括路徑)
filename = Environment.CurrentDirectory + @"\upload\" + filename;

在 linux 系統下就需要用 '/' 否則可儲存不了呀

// 新檔名(包括路徑)
filename = Environment.CurrentDirectory + @"/upload/" + filename;

2.載入程式集

我是通過如下方法動態載入實體對映型別的,看下面標黃的程式碼,在獲取的路徑前加了一個 “/” 是因為在 linux 中需要使用絕對路徑,像是 /app/xxx 這種,不加的話就會報錯

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // 通過反射獲取繼承IEntityTypeConfiguration的實體型別
    string assembleFileName = Assembly.GetExecutingAssembly().CodeBase.Replace("Capricorn.Db.SqlServer.dll", "Capricorn.Entity.Mapping.dll").Replace("file:///", "");
    Assembly asm = Assembly.LoadFile("/" + assembleFileName);
    //.....省略其他程式碼
}

報錯內容,看到這個就要注意路徑問題了

Absolute path information is required. (Parameter 'path')

我們還要在 Program.cs 檔案下加上如下標黃的程式碼,設定埠

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseUrls("http://*:80")
                .UseStartup<Startup>();

釋出專案

釋出程式碼前需要先新增 Docker 支援,右鍵專案->新增-》Docker 支援 後就會讓你選擇釋出的目標系統如下,我這裡選擇 linux

 選擇完成後會新增一個 Dockerfile 檔案,會幫我們生成相應的構建映象的程式碼,但是我們可以簡化到如下

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
RUN sed -i 's/TLSv1.2/TLSv1.0/g' /etc/ssl/openssl.cnf
WORKDIR /app
EXPOSE 80
COPY . .
ENTRYPOINT ["dotnet", "Capricorn.dll"]

注意 Dockerfile 檔案中的第二行 RUN 的程式碼因為需要更新映象環境的 TLS 版本,否則在連線 sqlserver 的時候可能會報如下錯誤:

A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: TCP Provider, error: 35 - An internal exception was caught

 之後就釋出為檔案系統就行如下,我釋出到 D:\website

 

打包映象

之後我們到釋出的目標位置下,開啟 PowerShell 執行如下打包程式碼

PS D:\website> docker build -t myweb .

等待 Dockerfile 中的基礎映象下載完成,後就會完成我們打包的映象了

備註

其實我們還可以通過 vs 進行打包,我們如下圖所示,在工具欄出選擇 Docker,之後執行就會自動進行打包

但是會有個問題,你可能會發現打包了半天都打包不完,一直顯示容器預熱中,然後在輸出檢視中看到容器工具中輸出停止在如下程式碼,這三個內容很關鍵

Info: Using vsdbg version '16.8.11013.1'
Info: Using Runtime ID 'linux-x64'
Info: C:\Users\Xu\vsdbg\vs2017u5 exists, deleting.

要解決這個問題我們可以手動拼接下載路徑,下載路徑如下

https://vsdebugger.azureedge.net/vsdbg-(你的版本號 .號換成-號)/vsdbg-(你的Runtime ID).zip

比如按照我的輸出中的內容就需要如下的下載連結 

https://vsdebugger.azureedge.net/vsdbg-16-8-11013-1/vsdbg-linux-x64.zip

下載完成後在我們在需要的路徑下直接解壓檔案,再建立兩個文字檔案 success_version.txt 和 success_rid.txt 。在 success_version.txt 檔案中新增我們的版本號(我這是16.8.11013.1),在 success_rid.txt 中新增我們的 Runtime ID (我這是linux-x64),之後取消執行,重啟專案,然後在重新生成就行啦。

執行容器

我們因為需要連線 redis 所以需要一個網路使容器可以互相通訊,建立網路程式碼如下

PS D:\website> docker network create -d bridge test-net

之後我們執行專案的容器做如下操作

1.繫結剛剛建立的網路 test-net,可以與後面的 redis 通訊

2.掛載容器中的路徑 /app 到本機的釋出路徑 d:\website 下,這樣我們如果程式碼需要重新發布,在釋出完成後直接重啟容器就可以生效了

3.繫結容器內的 80 埠到本機的 5000 埠,可以通過訪問本地埠訪問網站

PS D:\website> docker run -itd --name myweb --network test-net -v d:\website:/app -p 5000:80 myweb

 執行Redis容器,我們直接用 Docker Hub 中的映象

PS D:\website> docker run -itd --name redis_myweb --network test-net redis

如果資料庫用的也是容器那和 redis 的操作差不多,不過我這裡使用的是本機上的 sqlserver 資料庫,具體在 appsetting.json 的配置內容如下

{
  "ConnectionStrings": {
    "BaseDb": {
      "ProviderName": "System.Data.SqlClient",
      "ConnectionString": "Data Source=host.docker.internal,1433;Database=****;User ID=sa;Password=*********"
    },
    "Redis": {
      "ConnectionString": "redis_myweb",
      "Prefix": "Cap_"
    }
  }
}

可以看到,由於 redis 是在容器中執行的,所以連線字串為執行的容器的名稱。而資料庫因為連線本機,所以地址使用了 host.docker.internal 作為地址。host.docker.internal 表示主機的地址,在主機為 windows 的機器中才能用,如果 redis 想使用本機的,那連線字串也可以用 host.docker.internal 。

執行網站

我們訪問地址 http://localhost:5000/ 可以看到訪問成功了

 

 之後上傳檔案,也可以看到我們本機掛載的資料夾下多了一個 upload 資料夾,裡面多了我們上傳的檔案

 

 訪問資料庫可以看到成功返回了資料

 

 設定快取也成功啦

 

 

 

相關文章