귀찮은 빌드 자동화하기
지금 회사에서 프로젝트로 자바, 스프링 기반의 웹 솔루션을 개발하고 있다. (사실 거의 SI 프로젝트다)
이 프로젝트는 CI/CD같은 파이프라인이 구축되지 않고, 시간에 쫓기느라 그런 걸 할 시간도 없다. 만약 하는 게 어떠냐고 제안하면 욕먹을 게 뻔했다.. (물론 아직 1년도 안 된 신입이기 때문에 제안도 못 해봤지만..)
우리끼리 ‘개발서버’라고 부르는 사내 리눅스 서버(aws)가 있는데, 각자가 개발한 내용을 빌드해서 테스트해보는 용도로 사용하고 있다. 즉, Git에 커밋된 코드를 자동 배포하는 게 아니라 개발자 로컬에 있는 코드를 배포하는 것이다.
좋은 환경에서 개발하는 분들은 “왜 저렇게 개발하지?” 하며 이 과정자체를 이해하지 못할 수도 있다.
📢 참고로, 실제 스크립트는 올리지 않았다. 내가 개인적으로 짠 스크립트이고, 회사에 사용되는 코드도 아니지만 혹시나 회사에 폐를 끼칠까봐 조심스러운 부분이 있다. (신입이라 뭐든 조심하는 것이 좋을 것 같아서..😜)
기존 빌드 및 배포 과정
기존에 하던 빌드하고 배포하는 방식은 매우 간단하지만, 은근히 귀찮은 일이었다.
- 현재 프로젝트를 빌드한다.
- 프로젝트/target/ 에 생성되는 jar 스냅샷 파일을 개발서버에 수동으로 업로드한다.
(윈도우에서 개발 중이기 때문에 mobaXtrem과 같은 툴로 드래그 앤 드랍을 했다.) - 기존에 실행되던 jar 파일의 이름에 현재 날짜와 시간을 붙여 백업 폴더로 이동시킨다.
- 새로 업로드된 jar파일의 이름을 jar 실행 쉘 스크립트에 지정된 실행 파일명에 맞게 변경한다.
- 정지 쉘 스크립트를 실행 후, 시작 쉘 스크립트를 실행한다.
뭔가 수정한 뒤 리눅스에서 테스트를 해보기 위해서는 항상 이 과정을 거쳐야했다. 심지어 내게 출근할 때마다 해당 작업을 수행하라는 지시가 내려왔다.
프로젝트가 하나면 모르겠는데 5개나 된다. 사실, 몇 개월동안 내가 이 작업을 하지 않고 내가 테스트할 것만 수동 빌드, 배포했기 때문에 크게 불편함을 느끼지 못했다. 하지만 매일 5번의 똑같은 빌드, 업로드, 이름 변경, 폴더 이동, 정지와 시작을 한다는 것은 참 귀찮은 일이었다.
그래서 한 번 귀찮고 앞으로 편하자는 생각으로 난생 처음 빌드 및 배포 자동화 쉘 스크립트를 작성해보았다.
자동화된 빌드 및 배포 과정
이제 매우 간단하다. 그냥 쉘 스크립트를 실행하면 빌드, 업로드, 이름 및 폴더 변경, java 프로세스 재시작을 할 수 있다. 쉘 스크립트를 실행하기만 하면 더 이상 내가 할 것은 없다. 이렇게 간단한 것을 왜 이제서야 했나싶다.
어떻게 했나?
앞서 말한대로, 나는 쉘 스크립트를 한 번도 짜본 적이 없기때문에 많은 구글링이 필요했다. 게다가, 회사 로컬 개발환경이 윈도우이기 때문에 Windows PowerShell을 사용했다. 리눅스와 개행이 다르고 문법도 달라서 꽤 애먹었다.
역시 개발은 Mac으로…. 제발 Mac으로 개발하게 해주세요 ㅜ
연결 프로토콜
고려한 파일 전송 프로토콜은 SFTP(Secure File Transfer Protocol)
와 SCP(Secure Copy Protocol)
였다.
두 프로토콜 모두 OpenSSH를 기반으로 파일을 전송하는 프로토콜이다.
🔊 특이한 점은
FTP(File Transfer Protocol)
가 보안적으로 발전한 것이 SFTP일 것이라고 추측했는데, 둘은 애초에 기반이 다른 프로토콜이라고 한다.FTP
와SFTP
는 이름이 비슷하고 기능 역시 비슷하지만 전혀 다른 프로토콜임을 기억하자.
- SFTP와 SCP의 차이
내가 생각할 때 두 프로토콜의 가장 큰 차이는 접속 여부(세션 유지, 명령어 사용가능)이다.
SCP의 경우 SSH로 연결하여 파일을 전송하면 프로토콜의 임무는 완료이다. 따라서 명령어에 파일전송을 바로 할 수 있도록 경로를 적어줘야 한다.
scp -p 50022 {로컬파일경로}/{파일명} {원격 유저명}@{원격 호스트}:{원격에서 업로드할 경로}
이런식으로 명령어 한 줄에 파일 전송이 끝나기 때문에, 업로드할 경로는 절대 경로를 넣어주는 것이 좋다.
따로 접속하여 리눅스 명령어를 사용하는 등의 작업은 할 수 없다.
SFTP의 경우 역시 SSH를 통해 연결한다. SCP와 다른 점은 SFTP는 연결 후에도 명령어를 작성할 수 있다. 따라서 연결할 때 파일에 관련된 모든 정보를 작성할 필요 없다.
sftp -oPort=50022 {원격 유저명}@{원격 호스트} >> 연결
cd {원격에서 업로드할 경로}
lcd {로컬파일경로}
put {파일명}
위의 예제는 SFTP 연결 후, cd
명령어로 연결된 서버의 경로로 이동하고 lcd
명령어로 내 로컬 경로를 이동한다. put
명령어로 파일을 업로드, get
명령어로 파일을 다운로드 할 수 있다. 또, 내가 필요한 파일명 변경 및 파일 이동에는 rename
을 사용할 수 있다.
하지만 SFTP에서 지원하는 명령어는 제한적이기 때문에 리눅스 명령어를 사용할 수는 없다.
설명이 길어졌는데, 나는 빌드한 파일을 업로드 하는 데 SCP(Secure Copy Protocol)
을 사용했다. SFTP
를 사용하면 빌드 및 배포에서 내가 원하는 작업을 모두 할 수 있었다. 그럼에도 SFTP
가 아닌 SCP
를 사용한 것은 OS적인 이슈 때문이었다.
내 개발환경은 Windows이고, 자동화된 쉘 스크립트를 작성하기 위해 PowerShell을 사용했는데 공교롭게도 PowerShell은 SFTP 를 지원하지 않는다. 물론 다른 응용프로그램을 설치하여 사용할 순 있겠지만 나는 동료들과 공유하기 위해 가장 간단한 방법이 필요했다.
결국 SCP를 통해 파일을 적절하게 업로드 한 뒤, SSH로 원격 접속하여 리눅스 명령어를 실행하는 형태로 쉘 스크립트를 작성하게 되었다.
실수
처음 스크립트를 실행할 때, Connect Refused로 고생했다. 분명 로컬에서 ssh로 잘만 접속했는데 갑자기 안 되서 뭐가 문제인가 싶었다.
바보같이 포트를 놓쳤다.. scp
를 사용할 때 포트를 지정해주지 않으면 자동으로 ssh
기본 포트인 22로 간다. 사내 개발서버의 ssh
포트는 실제로 22가 아니었다.
나가며
내가 귀찮아서 해야할 일을 빠르게 끝내고 간단한 스크립트를 작성했다. 왜 진작 안 했는 지 모를 정도로 간단하고 효율적이었다. 또, 동료들에게 해당 파일들과 사용방법을 나눠주고 나니 뭔가 도움이 된 듯한 느낌이 들어 좋았다. 내 힘으로 팀원에게 좀 더 도움을 줄 수 있는 실력있는 개발자가 되기위해 노력해야겠다.
사담으로,
이 작업을 하면서 든 생각은 로컬 개발환경으로 윈도우는 너무 불편하다는 점이었다. 요즘 웬만한 서버들은 모두 Linux 환경에 배포된다. Mac은 Linux 기반의 OS이기 때문에 파일경로(/부터 시작), 개행(LF), shell 작성 문법 등이 linux와 매우 유사하다. 그런데 Windows는 파일 경로가 다르고(C:), CRLF 방법으로 개행하고, 기본적으로 shell이 bash가 아니기 때문에 문법도 다르다.
개발자는 Mac 써야한다 라고 말하는 사람들이 많은데 이번 경험으로 격하게 동의하게 되었다.