회사에서 보안적인 이유로 인해 특정 서버는 Jenkins를 사용할 수 없는 서버가 있었습니다. 그래서 매번 직접 서버에 접속하고 파일을 옮기고, 명령어를 입력해줘야 배포를 할 수 있었습니다.
이를 그나마 나은 방법으로 배포하기위해 빌드와 배포하는 명령어 모아둔 powershell 스크립트를 작성하여 배포 프로세스를 개선하였습니다. 스크립트는 아래와 같은 단계를 포함합니다.
- 변수지정
- 작업 디렉터리로 이동
- Gradle clean build 실행
- SCP로 파일 전송
- 사용자로부터 자격 증명 입력 받기
- SSH 세션 시작
- 원격 서버에서 명령 실행
- SSH 세션 종료
# local PC에 있는 프로젝트 경로
$localProjectPath = "C:\local\project"
# 원격 서버의 IP주소
$remoteServerName = "1111.222.33.4"
# 원격 서버 User명
$remoteUsername = "wontaekoh"
# 원격 서버에 있는 프로젝트 경로
$remoteProjectPath = "C:\remote\project"
# jar파일 이름
$jarFileName = "project-0.0.1-SNAPSHOT.jar"
#===========================================================================================
# 작업 디렉터리로 이동
Set-Location -Path $localProjectPath
Write-Output "CD to ${localProjectPath}"
# Gradle clean build 실행
$buildCommand = "./gradlew clean build"
Invoke-Expression $buildCommand
Write-Output "gradle clean build"
# 사용자로부터 자격 증명 입력 받기
$credential = Get-Credential
# SCP로 파일 전송
$localLibsPath = "${localProjectPath}\build\libs\${jarFileName}"
$remoteLibsPath = "${remoteProjectPath}\build\libs\"
$scpCommand = "scp ${localLibsPath} ${remoteUsername}@${remoteServerName}:${remoteLibsPath}"
Invoke-Expression $scpCommand
Write-Output "File transferred to ${remoteLibsPath} on ${remoteServerName}"
# SSH 세션 시작
$session = New-SSHSession -ComputerName $remoteServerName -Credential $credential
# 세션 객체가 유효한지 확인
if ($session -ne $null) {
Write-Output "SSH Session Create Success!"
# PowerShell 명령 실행을 위한 스크립트 블록
$psCommand = "Set-Location -Path '${remoteProjectPath}'; podman build -t spring-mes .; docker-compose -f docker-compose.yml down; docker-compose -f docker-compose.yml up -d"
$command = "powershell -Command `"$psCommand`""
# 원격 PowerShell 실행
$output = Invoke-SSHCommand -SSHSession $session -Command $command
# 명령 실행 결과 출력
Write-Output "Output: $($output.Output)"
Write-Output "Exit Status: $($output.ExitStatus)"
# SSH 세션 종료
Remove-SSHSession -SessionId $session.SessionId
Write-Output "SSH Session Close."
} else {
Write-Output "SSH Session Create Failure."
}
원격서버에 폴더 경로와 docker-compose.yml은 작성되어있어야합니다.
먼저, 필요한 변수를 선언합니다. 이는 로컬 프로젝트 경로, 원격 서버 정보, 원격 경로 및 JAR 파일명을 포함합니다. 변수부분만 잘 수정해주면 환경이 바뀌더라도 바로바로 스크립트를 재사용할 수 있습니다.
$localProjectPath = "C:\local\project"
$remoteServerName = "1111.222.33.4"
$remoteUsername = "wontaekoh"
$remoteProjectPath = "C:\remote\project"
$jarFileName = "project-0.0.1-SNAPSHOT.jar"
Set-Location cmdlet을 사용하여 작업 디렉터리로 이동합니다. 이 단계에서는 빌드를 실행할 디렉터리로 이동합니다.
Set-Location -Path $localProjectPath
Write-Output "CD to ${localProjectPath}"
Gradle 빌드를 실행하여 프로젝트를 빌드합니다. Invoke-Expression cmdlet을 사용하여 명령을 실행합니다.
$buildCommand = "./gradlew clean build"
Invoke-Expression $buildCommand
Write-Output "gradle clean build"
SCP를 사용하여 로컬 파일을 원격 서버로 전송합니다. 여기서 $localLibsPath와 $remoteLibsPath 변수를 사용하여 경로를 지정합니다.
$localLibsPath = "${localProjectPath}\build\libs\${jarFileName}"
$remoteLibsPath = "${remoteProjectPath}\build\libs\"
$scpCommand = "scp ${localLibsPath} ${remoteUsername}@${remoteServerName}:${remoteLibsPath}"
Invoke-Expression $scpCommand
Write-Output "File transferred to ${remoteLibsPath} on ${remoteServerName}"
Get-Credential cmdlet을 사용하여 사용자 자격 증명을 입력 받습니다. 이 자격 증명은 SCP 및 SSH 연결에 사용됩니다.
$credential = Get-Credential
New-SSHSession cmdlet을 사용하여 SSH 세션을 시작합니다. 이 세션은 원격 서버에서 명령을 실행하는 데 사용됩니다.
$session = New-SSHSession -ComputerName $remoteServerName -Credential $credential
SSH 세션이 성공적으로 생성되면, 원격 서버에서 필요한 명령을 실행합니다. 여기서는 Docker 컨테이너를 빌드하고 재시작하는 명령을 실행합니다.
if ($session -ne $null) {
Write-Output "SSH Session Create Success!"
# PowerShell 명령 실행을 위한 스크립트 블록
$psCommand = "Set-Location -Path '${remoteProjectPath}'; podman build -t spring-mes .; docker-compose -f docker-compose.yml down; docker-compose -f docker-compose.yml up -d"
$command = "powershell -Command `"$psCommand`""
# 원격 PowerShell 실행
$output = Invoke-SSHCommand -SSHSession $session -Command $command
# 명령 실행 결과 출력
Write-Output "Output: $($output.Output)"
Write-Output "Exit Status: $($output.ExitStatus)"
# SSH 세션 종료
Remove-SSHSession -SessionId $session.SessionId
Write-Output "SSH Session Close."
} else {
Write-Output "SSH Session Create Failure."
}
마지막으로, SSH 세션을 종료합니다. 이는 원격 서버와의 연결을 정리하고 세션 자원을 해제하기 위함입니다.
Remove-SSHSession -SessionId $session.SessionId
Write-Output "SSH Session Close."
구글링을 해도 자료가 잘 없어서 Chat GPT와 열심히 토론하며 이 스크립트를 작성했습니다. 물론, 조금만 잘못 물어보면 엉뚱한 답변이 돌아와서 고생도 했지만, 그 덕분에 많이 배웠습니다.
CLI 환경이 아직 어색하긴 하지만, 덕분에 조금씩 친해지고 있는 것 같습니다. 개발을 하다 보면 어쩔 수 없이 익숙해지는 것 같습니다.