[料理佳餚] 用 PowerShell 在 CentOS 7 上實現 ASP.NET Core 的藍綠部署

PowerShell 目前是開源的,而且跨平台,做為一位長期在微軟技術生態圈打滾的碼農,面對要撰寫 Script 做自動化工作的場景,怎麼可以不用呢? 馬上來將上一篇文章用 Shell Script 實現藍綠部署,改用 PowerShell 來實現。

相對於 Shell Script 在語法上將標點符號發揮得淋漓盡致,我個人覺得 PowerShell 顯得平易近人許多,我個人在學習 Shell Script 時有一道檻,那就是有很多的標點符號組合要強記,而 PowerShell 的標點符號就用得沒那麼多,還有就是 PowerShell 的語法比較貼近平常在用的程式語言,熟悉感比較強烈。

下載安裝 PowerShell

廢話不多說,馬上就在 CentOS 7 執行下面的指令將 PowerShell 裝起來,我安裝的版本是 6.2.4。

sudo yum install -y https://github.com/PowerShell/PowerShell/releases/download/v6.2.4/powershell-6.2.4-1.rhel.7.x86_64.rpm

安裝完成後,執行 pwsh 就會進入 PowerShell 的操作介面,就表示安裝成功。

相關步驟的說明請參考我上一篇的文章,底下我僅貼上相對應的 PowerShell 指令碼。

Who is Production? Who is Stage?

$conf = (Get-Content /etc/nginx/conf.d/www.conf | Out-String)

$conf -match "localhost:(\d+)" | Out-Null

if ( $Matches.1 -eq "8001" ) {
    $prod = "WebApp-8001"
    $stage = "WebApp-8002"
} else {
    $prod = "WebApp-8002"
    $stage = "WebApp-8001"
}

Stop Stage service

if ( (systemctl is-active $stage | Out-String).Trim() -eq "active" ) {
    sudo systemctl stop $stage
}

Pull from deployment repository

Set-Location -Path "/home/User/test-deploy"

$prev_sha = (git rev-parse HEAD | Out-String)

git pull --quiet

$diff_log = (git diff --stat=1000,1000 $prev_sha | Out-String)

if ( -NOT ($diff_log -match "[1-9][0-9]*\sfiles?\schanged")) {
    exit 0
}

Mirror copy deployment files to Stage folder

rsync -rtD --force --delete --ignore-errors /home/User/test-deploy/WebApp/ /var/www/$stage/

Start Stage service

sudo systemctl start $stage

Modify and reload Nginx's conf

$prod -match "[^-]+-(\d+)" | Out-Null

$prod_authority = "localhost:$($Matches.1)"

$stage -match "[^-]+-(\d+)" | Out-Null

$stage_authority = "localhost:$($Matches.1)"

sudo sed -i "s/$prod_authority/$stage_authority/g" /etc/nginx/conf.d/www.conf

sudo nginx -s reload

Stop Production service

Start-Sleep -Seconds 30
sudo systemctl stop $prod

完整指令碼

$conf = (Get-Content /etc/nginx/conf.d/www.conf | Out-String)

$conf -match "localhost:(\d+)" | Out-Null

if ( $Matches.1 -eq "8001" ) {
    $prod = "WebApp-8001"
    $stage = "WebApp-8002"
} else {
    $prod = "WebApp-8002"
    $stage = "WebApp-8001"
}

if ( (systemctl is-active $stage | Out-String).Trim() -eq "active" ) {
    sudo systemctl stop $stage
}

Set-Location -Path "/home/User/test-deploy"

$prev_sha = (git rev-parse HEAD | Out-String)

git pull --quiet

$diff_log = (git diff --stat=1000,1000 $prev_sha | Out-String)

if ( -NOT ($diff_log -match "[1-9][0-9]*\sfiles?\schanged")) {
    exit 0
}

rsync -rtD --force --delete --ignore-errors /home/User/test-deploy/WebApp/ /var/www/$stage/

sudo systemctl start $stage
Start-Sleep -Seconds 10

$prod -match "[^-]+-(\d+)" | Out-Null

$prod_authority = "localhost:$($Matches.1)"

$stage -match "[^-]+-(\d+)" | Out-Null

$stage_authority = "localhost:$($Matches.1)"

sudo sed -i "s/$prod_authority/$stage_authority/g" /etc/nginx/conf.d/www.conf

sudo nginx -s reload

Start-Sleep -Seconds 30
sudo systemctl stop $prod

參考資料

相關資源

C# 指南
ASP.NET 教學
ASP.NET MVC 指引
Azure SQL Database 教學
SQL Server 教學
Xamarin.Forms 教學