1. 程式人生 > >自動部署Asp.Net Core到Docker

自動部署Asp.Net Core到Docker

> 原文連結:[個人部落格:自動部署Asp.Net Core至Docker](https://www.giantliu.cn/2020/08/25/200825AutoDeployToDocker/) ## 本文簡介 最近在開發一個管理系統,程式碼框架是用的前後臺分離的方式 後臺使用的是Asp.Net Core平臺,開發所有業務,向前臺提供Rest API介面。 使用的認證方式是JWT 前端有兩個專案,一個是Web端,一個是Mobild端 都是使用Vue + Ant Design of Vue架構 後端的開發工具使用的是Visual Studio 2019 前端的開發工具使用的是Visual Studio Code 在這前我也寫過通過PowerShell自動部署Asp.Net Core程式到Windows伺服器 並使用IIS向外提供服務。 > [使用PowerShell自動編譯部署](https://www.cnblogs.com/liuju150/p/PowerShell-Deploy-Nodejs.html) 為了使專案實現執行在全開源平臺,實現低成本、安全、高可用的目的 所以寫這個文章以實現自動部署系統至Ubuntu平臺使用Docker對外提供服務 > 本文章只實現後端介面專案(Rest API)的部署 > 本文所有自動部署程式碼是基於PowerShell ## 實現目標 1. 在Windows平臺自動編譯API介面 2. 把編譯生成的檔案釋出到Ubuntu伺服器 3. 在Ubuntu伺服器使用Docker對外提供服務 ## 前置條件 1. Ubuntu伺服器啟用了SSH,並可以使用RSA Key登入root 參考文件:[Ubuntu系統配置SSH服務](https://www.giantliu.cn/2020/08/24/200824UbuntuSSHConfig/) 2. Ubuntu伺服器安裝了PowerShell 參考文件:[使用PowerShell操作Ubuntu](https://www.giantliu.cn/2020/08/19/InstallPowerShell/) 3. Ubuntu伺服器安裝了Docker 參考文件:[Ubuntu安裝Docker](https://www.giantliu.cn/2020/08/24/200824InstallDockerToUbuntu/) ## 自動編譯Asp.Net Core Web API介面 ```powershell #設定程式碼目錄和編譯輸出目錄 $CurPath=(Resolve-Path .).Path $OutputPath=$CurPath+"\bin\publish\" #清空輸出目錄 Remove-Item -Path $OutputPath -Force -Recurse #呼叫dotnet publish命令釋出程式 #參考:https://docs.microsoft.com/zh-cn/dotnet/core/tools/dotnet-publish Invoke-Command -ScriptBlock {param($o) dotnet publish -o $o -c "Release" --no-self-contained -r linux-arm64 -v m --nologo "05.Coldairarrow.Api.csproj"} -ArgumentList $OutputPath #壓縮編譯後的釋出檔案 $CurDateString=Get-Date -Format "yyyyMMddHHmmss" #壓縮檔名加上日期,以後追溯 $ZIPFileName="Deploy"+$CurDateString+".zip" $ZIPFilePath=$CurPath+"\"+$ZIPFileName $CompressPath=$OutputPath+"*" #壓縮檔案 #Path:壓縮物件,DestinationPath:輸出壓縮檔案全路徑 Compress-Archive -Path $CompressPath -DestinationPath $ZIPFilePath ``` ## 把壓縮後的編譯檔案釋出到伺服器 ```powershell #使用RSA Key免密登入Ubuntu SSH $Session = New-PSSession -HostName 10.76.20.162 -UserName root -KeyFilePath "C:\Users\Administrator\.ssh\id_rsa" #設定遠端伺服器部署路徑 $RemotePath="/srv/Deploy/" #複製檔案到伺服器 Copy-Item $ZIPFilePath -Destination $RemotePath -ToSession $Session #設定程式部署目錄 $RemoteDestinationPath=$RemotePath+"API/" $RemoteZipPath=$RemotePath+$ZIPFileName #清空程式部署目錄 Invoke-Command -Session $Session -ScriptBlock {param($p) Remove-Item -Path $p -Recurse -Force} -ArgumentList $RemoteDestinationPath #解壓檔案到程式部署目錄 Invoke-Command -Session $Session -ScriptBlock {param($p,$dp) Expand-Archive -Path $p -DestinationPath $dp} -ArgumentList $RemoteZipPath,$RemoteDestinationPath #刪除本的壓縮檔案 Remove-Item -Path $ZIPFilePath ``` ![編輯部署](https://img2020.cnblogs.com/blog/45026/202008/45026-20200825124819723-1685907903.png) ## Docker對外提供服務 ### 在程式部署目錄配置Dockerfile ```ini #拉取asp.net core映象 FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false #設定工作目錄 WORKDIR /app #把伺服器檔案複製到Docker COPY . . #對外開放5000埠 EXPOSE 5000 #啟動API命令 ENTRYPOINT ["dotnet","Coldairarrow.Api.dll"] ``` ### 構建API映象,並啟動新容器 ```powershell #停止容器 Invoke-Command -Session $Session -ScriptBlock {docker stop api} #刪除容器 Invoke-Command -Session $Session -ScriptBlock {docker rm api} #刪除映象 Invoke-Command -Session $Session -ScriptBlock {docker rmi api} #通過Dockerfile構建映象 Invoke-Command -Session $Session -ScriptBlock {docker build -t api /srv/Deploy/API} #啟動新的容器 Invoke-Command -Session $Session -ScriptBlock {docker run -d -p 5000:5000 --name api api} ``` ![](https://img2020.cnblogs.com/blog/45026/202008/45026-20200825124850087-232416228.png) ## 部署結果 部署成功後,我們在瀏覽器裡開啟 [http://10.76.20.162:5000/swagger/](http://10.76.20.162:5000/swagger/) 就可以看到我們釋出的API介面 ![](https://img2020.cnblogs.com/blog/45026/202008/45026-20200825124908596-24433105.png) ## 原始碼 ```powershell Write-Host 'Build Starting' -ForegroundColor Yellow $CurPath=(Resolve-Path .).Path $OutputPath=$CurPath+"\bin\publish\" Remove-Item -Path $OutputPath -Force -Recurse Invoke-Command -ScriptBlock {param($o) dotnet publish -o $o -c "Release" --no-self-contained -r linux-arm64 -v m --nologo "05.Coldairarrow.Api.csproj"} -ArgumentList $OutputPath Write-Host 'Build Completed' -ForegroundColor Green Write-Host 'Compress Starting' -ForegroundColor Yellow $CurDateString=Get-Date -Format "yyyyMMddHHmmss" $ZIPFileName="Deploy"+$CurDateString+".zip" $ZIPFilePath=$CurPath+"\"+$ZIPFileName $CompressPath=$OutputPath+"*" Compress-Archive -Path $CompressPath -DestinationPath $ZIPFilePath Write-Host 'Compress Completed' -ForegroundColor Green Write-Host 'Deploy Starting' -ForegroundColor Yellow $Session = New-PSSession -HostName 10.76.20.162 -UserName root -KeyFilePath "C:\Users\Administrator\.ssh\id_rsa" $Session Write-Host 'Successfully connected to the server' -ForegroundColor Green Write-Host 'Start copying files to the server' -ForegroundColor Yellow $RemotePath="/srv/Deploy/" Copy-Item $ZIPFilePath -Destination $RemotePath -ToSession $Session Write-Host 'Copy files completed' -ForegroundColor Green Write-Host 'Start Expand files on the server' -ForegroundColor Yellow $RemoteDestinationPath=$RemotePath+"API/" $RemoteZipPath=$RemotePath+$ZIPFileName Invoke-Command -Session $Session -ScriptBlock {param($p) Remove-Item -Path $p -Recurse -Force} -ArgumentList $RemoteDestinationPath Invoke-Command -Session $Session -ScriptBlock {param($p,$dp) Expand-Archive -Path $p -DestinationPath $dp} -ArgumentList $RemoteZipPath,$RemoteDestinationPath $ConfigProductionFile=$RemoteDestinationPath+"appsettings.Production.json" Invoke-Command -Session $Session -ScriptBlock {param($p) Remove-Item -Path $p -Force} -ArgumentList $ConfigProductionFile Write-Host 'Expand Completed' -ForegroundColor Green Write-Host 'Deploy to Docker Starting' -ForegroundColor Yellow Invoke-Command -Session $Session -ScriptBlock {docker stop api} Invoke-Command -Session $Session -ScriptBlock {docker rm api} Invoke-Command -Session $Session -ScriptBlock {docker rmi api} Invoke-Command -Session $Session -ScriptBlock {docker build -t api /srv/Deploy/API} Invoke-Command -Session $Session -ScriptBlock {docker run -d -p 5000:5000 --name api api} Write-Host 'Deploy to Docker Completed' -ForegroundColor Green Remove-Item -Path $ZIPFilePath Write-Host 'Deploy Completed' -ForegroundColor Green ```