前言
最近在開發一套管理系統,做了前后端分離。
后台使用的是Asp.Net Core 3.1
前端使用的是Vue+Ant Design
自己搞了一台雲服務器,打算把系統部署到雲服務器上。以供外網訪問。
服務器OS是WinServer2016
所以打算通過IIS平台來發部與部署系統。
后台部署
后台部署很好辦。因為可以通過Visual Studio,使用IIS的Web Deploy組件一健發布到服務器
前端部署-手動
因為項目還小。要部署的也就一個前端,一個后端。也沒有什么分布式部署。
顯然現還用不到到通過工具自動從GIT拿代碼,然后通過流水線自動構建這種大炮。
在沒有使用PowerShell自己部署前,前端部署流程是:
1。通過npm run build:live編譯,然后會把編譯好的文件生成在dist目錄
2。通過Windows遠程桌面,連接到遠程服務器。然后Ctrl+C,Ctrl+V把文件復制到服務器指定目錄
因為dist目錄文件數量太多,但是大小都比較小,直接復制可能比較慢。
把dist目錄壓縮一下。然后手動復制到服務器,然后解壓到服務器目錄。
這樣速度上來說比直接復制快一點。
但是一想到后端可以通過VS一鍵發布到服務器,而前端就要通過手動的方式復制到服務器
這樣的差距有點大。所以自己想通過寫一些腳本達到自動部署的目的。
自動部署方案
雖然說要設計一個自動部署方案,還不如說是通過機器模擬手工部署的流程。
達到把手工的工作機器自動完成。從而解放雙手。
那么流程其實還是和手工差不多。
1。編譯前端代碼
2。把編譯后dist目錄壓縮成一個ZIP文件
3。遠程連接到服務器
4。把壓縮文件傳輸到服務器
5。把壓縮文件解壓到指定目錄(先把原目錄所有文件刪除,再把壓縮文件解壓)
6。斷開遠程服務器連接,刪除本地壓縮文件
自動部署PowerShell腳本
基本上把上面的6個動作都用腳本實現,基本上就實現了自動部署的流程。
接下來就是一步步的實現過程
1。編譯前端代碼
這個很好辦。基本就是執行一下npm run build:live腳本
Write-Host 'Build Starting' -ForegroundColor Yellow $BuildScript={npm run build:live} Invoke-Command -ScriptBlock $BuildScript Write-Host 'Build Completed' -ForegroundColor Green
Write-Host就是在控制台輸出信息,-ForegroundColor就是指定以什么顏色輸出
Invoke-Command就是執行一段腳本 -ScriptBlock就是腳本內容,這里我們定義了npm run build:live
2。把編譯后dist目錄壓縮成一個ZIP文件
Write-Host 'Compress Starting' -ForegroundColor Yellow $CurDateString=Get-Date -Format "yyyyMMddHHmmss" $ZIPFileName="Deploy"+$CurDateString+".zip" $CurPath=(Resolve-Path .).Path $ZIPFilePath=$CurPath+"\"+$ZIPFileName Compress-Archive -Path ".\dist\*" -DestinationPath $ZIPFilePath Write-Host 'Compress Completed' -ForegroundColor Green
通過Compress-Archive命令,我們可以把目錄壓縮成ZIP文件
-Path 壓縮的路徑
-DestinationPath 生成ZIP文件的路徑
然后壓縮文件名是通過字符串+日期的格式來生成文件,這樣也就知道我們部署文件的時間了。
通過Start-Process的PowerShell來執行一個壓縮命令
完成以上命令,那么就會在前端代碼根目錄生成一個對應的壓縮文件了
3。遠程連接到服務器
通過PowerShell遠程連接到服務器這一步是比較難的。
因為他要在服務器和本機做一定的配置才可以實現
首先在服務器里面
通過PowerShell運行Enable-PSRemoting
來開啟可以使用PowerShell遠程連接
然后打開PowerShell遠程連接對應的防火牆端口
開啟防火牆"Windows 遠程管理“項,端口:5985
然后在服務器和本機都執行:winrm quickconfig
來快速配置WinRM
然后在本機通過PowerShell執行
Set-Item wsman:localhost\Client\TrustedHosts -value 服務器IP
來允許本機可以遠程連接到服務器
至此。環境配置方面就都已經完成。可以通過PowerShell來連接到服務器了
然后我們通過寫PowerShell腳本,來實現遠程連接到服務器
Write-Host 'Deploy Starting' -ForegroundColor Yellow $User = "登錄帳號" $Password = Read-Host -Prompt "Please enter the server password" -AsSecureString Write-Host 'Start connecting to the server' -ForegroundColor Yellow $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $Password $Session = New-PSSession -ComputerName 服務器IP -Credential $Credential Write-Host 'Successfully connected to the server' -ForegroundColor Green
我這里把登錄服務器帳號寫死了。但是密碼要在每次執行的時候輸入。以達到保密的目的。
因為我們這個腳本是要上傳到Git的。要是被人看到了還是不好,所以密碼就沒有寫死在這里了。要每次輸入
Read-Host -AsSecureString就是指要在控制台輸入一串密碼。密碼是以*顯示出來。
New-PSSession就是打開一個遠程的會話 -Credential是以指定憑據的方式打開遠程會話
到這里沒有報錯的話。基本上就表示連接到服務器了
4。把壓縮文件復制到服務器
這個步驟還是比較簡單。基本上就一個命令
Copy-Item $ZIPFilePath -Destination $RemotePath -ToSession $Session
Copy-Item 復制一個對像 -Destination 復制的目標地址(服務器目錄) -ToSession 哪個遠程會話連接
基本上這樣一個命令就可以把本地的一個文件復制到遠程服務器目錄了
5。把壓縮文件解壓
這個步驟基本上和壓縮是一樣的。也是調用Expand-Archive來執行解壓。
有區別的是壓縮是在本機執行。解壓是在遠程會話執行
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
Invoke-Command -Session就是在指定遠程會話里執行一個命令
第一個腳本是先把服務器上的目標目錄文件清除,所以Invoke-Command -ScriptBlock是調用遠程的Remove-Item
第二個腳本是在遠程會話解壓ZIP文件 -Path是壓縮文件路徑,-DestinationPath是解壓到目標地址路徑
6。斷開遠程連接,刪除本的壓縮文件
這個步就比較簡單了,基本上就調用兩個命令就OK
Disconnect-PSSession -Session $Session Remove-Item -Path $ZIPFilePath
Disconnect-PSSession 斷開一個遠程會話
Remove-Item移除一個文件
到此,一個自動部署的腳本就完成了。把腳本保存在一個文件里。
要部署的時候。直接在VSCode的終端里運行這個PowerShell腳本文件。
就可以自動把編譯好的前端部署到服務器了
下圖為運行結果
本PowerShell完整的腳本

1 Write-Host 'Build Starting' -ForegroundColor Yellow 2 $BuildScript={npm run build:live} 3 Invoke-Command -ScriptBlock $BuildScript 4 Write-Host 'Build Completed' -ForegroundColor Green 5 Write-Host 'Compress Starting' -ForegroundColor Yellow 6 $CurDateString=Get-Date -Format "yyyyMMddHHmmss" 7 $ZIPFileName="Deploy"+$CurDateString+".zip" 8 $CurPath=(Resolve-Path .).Path 9 $ZIPFilePath=$CurPath+"\"+$ZIPFileName 10 Compress-Archive -Path ".\dist\*" -DestinationPath $ZIPFilePath 11 Write-Host 'Compress Completed' -ForegroundColor Green 12 Write-Host 'Deploy Starting' -ForegroundColor Yellow 13 $User = "登錄帳號" 14 $Password = Read-Host -Prompt "Please enter the server password" -AsSecureString 15 Write-Host 'Start connecting to the server' -ForegroundColor Yellow 16 $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $Password 17 $Session = New-PSSession -ComputerName 服務器IP -Credential $Credential 18 Write-Host 'Successfully connected to the server' -ForegroundColor Green 19 Write-Host 'Start deploying files to the server' -ForegroundColor Yellow 20 $RemotePath="D:\Deploy\" 21 Copy-Item $ZIPFilePath -Destination $RemotePath -ToSession $Session 22 $RemoteDestinationPath=$RemotePath+"Web\" 23 $RemoteZipPath=$RemotePath+$ZIPFileName 24 Invoke-Command -Session $Session -ScriptBlock {param($p) Remove-Item -Path $p -Recurse -Force} -ArgumentList $RemoteDestinationPath 25 Invoke-Command -Session $Session -ScriptBlock {param($p,$dp) Expand-Archive -Path $p -DestinationPath $dp} -ArgumentList $RemoteZipPath,$RemoteDestinationPath 26 Disconnect-PSSession -Session $Session 27 Remove-Item -Path $ZIPFilePath 28 Write-Host 'Disconnected from server' -ForegroundColor Yellow 29 Write-Host 'Deploy Completed' -ForegroundColor Green
特別感謝:清平樂(Tutuu) 在PowerShell對於壓縮與解壓的幫助。