👨👦
オリジナルのスマートスピーカーを作ってみる 7 デプロイ自動化
この記事は?
この記事は オリジナルのスマートスピーカーを作ってみる シリーズの続き「その7」です。
デプロイを自動化する
まだデプロイを自動化していなかったので、します。
シンプルにスクリプト (powershell) を作成しようと思います。
スクリプトの概要
- アプリケーションのビルド
- リモートのアプリケーションサーバーのアプリを停止
- リモートのアプリケーションサーバーへビルド成果物をアップロード
- リモートのアプリケーションサーバーのアプリを起動
諸環境
スクリプト実行マシン 兼 ビルドマシン
OS | Windows 11 (x64) |
アプリケーション情報
アプリケーションプラットフォーム | .NET 8 |
言語 | C# 12 |
IDE | Visual Studio Community 2022 |
プロジェクト | WorkerService |
アプリケーションサーバー
製品名 | Raspberry Pi 5 |
OS | Raspberry Pi OS (ベースは Debian GNU/Linux 12 (bookworm)) |
CPU アーキテクチャ | aarch64/arm64 |
メモリ | 8GB |
- アプリケーションサーバーへの接続方法
- SSH プロトコルを利用
- 認証方法は公開鍵認証方式
- SSH クライアントソフトは OpenSSH_for_Windows
- リモートマシン上でコマンド実行は以下の方法を利用
- $ ssh remote_user@remote_ip "実行したいコマンド"
- リモートマシンのデフォルトシェルは bash です
- ファイルのアップロード方法
- SFTP プロトコルを利用
- SFTP クライアントソフトは WinSCP
- 認証方法
- SFTP は SSH の拡張プロトコルなので設定は不要
デプロイのスクリプト (Powershell)
デプロイのスクリプト (Powershell) を以下に紹介します。
deployment.ps1
# ソリューションフォルダに移動後、以下のコマンドでこのスクリプトを実行できます。
# powershell -NoProfile -ExecutionPolicy Unrestricted .\MyProject\shellscripts\deployment.ps1
Write-Host "----- start deployment.ps1 -----";
# エラーが発生したときにスクリプトの実行を停止する
$ErrorActionPreference="Stop"
~~~各設定値の取得、変数宣言は省略~~~
#ビルドを実行
dotnet publish -c Release -r linux-arm64 --self-contained true;
#Serviceを停止する
Write-Host "●${myapp_systemmd_service_name}の停止を始めます";
$service_stop_result = ssh $server_user@$server_ip "sudo systemctl stop ${myapp_systemmd_service_name}";
if($service_stop_result -ne $null)
{
Write-Host "service_stop_result: ${service_stop_result}";
}
#古い成果物の削除処理
Write-Host "●古い成果物の削除をはじめます";
#デプロイ先フォルダ内をファイルのリストを取得
$ls_result = ssh $server_user@$server_ip "ls ${publish_dir}";
$fileList = $ls_result -split " ";
#古いビルド成果物が存在する場合、古いファイルを削除
if($fileList -contains $myapp_service_dll)
{
Write-Host "${myapp_service_dll}が存在します。log以外の削除を実行します。";
$delete_all_without_log = "find ${publish_dir} -mindepth 1 -maxdepth 1 -type d ! -name `"log`" -exec rm -rf {} \; && find ${publish_dir} -mindepth 1 -maxdepth 1 -type f -delete";
$delete_result = ssh $server_user@$server_ip "${delete_all_without_log}";
if($delete_result -ne $null)
{
Write-Host "delete_result: ${delete_result}";
}
}
else
{
Write-Host "${myapp_service_dll}が存在しません。削除は実行しません。";
}
# WinSCPスクリプトを作成
$script = @"
# 接続情報を設定。秘密鍵を指定しています。
open sftp://$server_user@$server_ip -privatekey=$ppk_dir
# リモートディレクトリに移動
cd ${publish_dir}
# フォルダ内のすべてのファイルをアップロード
put $local_publish_dir\*
# appsettings.deploy.jsonをアップロードし、ファイル名を変更
put $deploy_app_serrings_file $app_settings_filename
# service_settings.deploy.json をアップロードし、ファイル名を変更
put $deploy_service_settings_file $service_settings_filename
# 接続を閉じる
close
exit
"@
# 一時的なWinSCPスクリプトファイルを作成
$tempFile = [System.IO.Path]::GetTempFileName()
$script | Out-File -FilePath $tempFile
# デプロイ
# WinSCP.comにスクリプトを渡し、デプロイを実行
Write-Host "WinSCP.com により成果物をデプロイしています...";
# 末尾に "> `$null" を追加すると、WinSCP.comの出力を非表示にできる
$cmd = "${winscpcom_file} -script=`"${tempFile}`" > `$null"
Invoke-Expression $cmd;
# 一時的なスクリプトファイルを削除
Remove-Item -Path $tempFile
# chomod の実行
Write-Host "●${myapp_service_exe_filename}の実行権限を付与します";
$chmod_result = $cmd = ssh $server_user@$server_ip "chmod +x ${publish_dir}/${myapp_exe_filename}";
if($chmod_result -ne $null)
{
Write-Host "chmod_result: ${chmod_result}";
}
# systemd ユニットファイルのシンボリックリンクの作成
Write-Host "●${myapp_systemmd_service_name}のシンボリックリンクを作成します";
$symbol_result = $cmd = ssh $server_user@$server_ip "sudo ln -sf ${publish_dir}/${myapp_systemmd_service_name} ${systemd_unitfile_dir}";
if($symbol_result -ne $null)
{
Write-Host "symbol_result: ${symbol_result}";
}
#デーモンのリロード
Write-Host "●systemctl daemon-reloadを実行します";
$daemon_reload_result = $cmd = ssh $server_user@$server_ip "sudo systemctl daemon-reload";
if($daemon_reload_result -ne $null)
{
Write-Host "daemon_reload_result: ${daemon_reload_result}";
}
#サービスを起動する
Write-Host "●${myapp_systemmd_service_name}の起動を始めます";
$service_start_result = $cmd = ssh $server_user@$server_ip "sudo systemctl start ${myapp_systemmd_service_name}";
if($service_start_result -ne $null)
{
Write-Host "service_start_result: ${service_start_result}";
}
Write-Host "Now listening on: ${web_app_url}";
#ブラウザでダッシュボードを開く
cd $browser_directory_path;
$cmd = "Start-Process .\chrome.exe `"${web_app_url}`"";
Invoke-Expression $cmd;
Write-Host "----- finish deployment.ps1 -----";
Discussion