PowerShell 스크립트를 사용하여 SpringBoot프로젝트를 원격 서버에 배포하기

wontaekoh·2024년 5월 25일
0

인프라

목록 보기
7/9
post-thumbnail

회사에서 보안적인 이유로 인해 특정 서버는 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은 작성되어있어야합니다.

📌 스크립트 설명

1. 변수선언

먼저, 필요한 변수를 선언합니다. 이는 로컬 프로젝트 경로, 원격 서버 정보, 원격 경로 및 JAR 파일명을 포함합니다. 변수부분만 잘 수정해주면 환경이 바뀌더라도 바로바로 스크립트를 재사용할 수 있습니다.

$localProjectPath = "C:\local\project"
$remoteServerName = "1111.222.33.4"
$remoteUsername = "wontaekoh"
$remoteProjectPath = "C:\remote\project"
$jarFileName = "project-0.0.1-SNAPSHOT.jar"

2. 작업 디렉터리로 이동

Set-Location cmdlet을 사용하여 작업 디렉터리로 이동합니다. 이 단계에서는 빌드를 실행할 디렉터리로 이동합니다.

Set-Location -Path $localProjectPath
Write-Output "CD to ${localProjectPath}"

3. Gradle clean build 실행

Gradle 빌드를 실행하여 프로젝트를 빌드합니다. Invoke-Expression cmdlet을 사용하여 명령을 실행합니다.

$buildCommand = "./gradlew clean build"
Invoke-Expression $buildCommand
Write-Output "gradle clean build"

4. SCP로 파일 전송

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}"

5. 사용자로부터 자격 증명 입력 받기

Get-Credential cmdlet을 사용하여 사용자 자격 증명을 입력 받습니다. 이 자격 증명은 SCP 및 SSH 연결에 사용됩니다.

$credential = Get-Credential

6. SSH 세션 시작

New-SSHSession cmdlet을 사용하여 SSH 세션을 시작합니다. 이 세션은 원격 서버에서 명령을 실행하는 데 사용됩니다.

$session = New-SSHSession -ComputerName $remoteServerName -Credential $credential

7. 원격 서버에서 명령 실행

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."
}

8. SSH 세션 종료

마지막으로, SSH 세션을 종료합니다. 이는 원격 서버와의 연결을 정리하고 세션 자원을 해제하기 위함입니다.

Remove-SSHSession -SessionId $session.SessionId
Write-Output "SSH Session Close."

✨ 마무리

구글링을 해도 자료가 잘 없어서 Chat GPT와 열심히 토론하며 이 스크립트를 작성했습니다. 물론, 조금만 잘못 물어보면 엉뚱한 답변이 돌아와서 고생도 했지만, 그 덕분에 많이 배웠습니다.
CLI 환경이 아직 어색하긴 하지만, 덕분에 조금씩 친해지고 있는 것 같습니다. 개발을 하다 보면 어쩔 수 없이 익숙해지는 것 같습니다.

profile
주니어 백엔드 개발자, 오원택입니다!

0개의 댓글