배포 자동화(with. Github Actions)
수작업으로 하는 배포는 개발 생산성을 저하시키는 요소 중 하나입니다.
코드 업데이트 → 빌드 → 실행
이라는 일련의 작업을 반복해야 하고, 반복적인
작업에 리소스가 투입되기 때문에 효율성이 떨어지기 때문입니다. 배포 환경을
개선하기 위해 Github Actions을 활용해 자동 배포로 전환한 경험을 공유해보고자
합니다.
기존 배포 방식의 문제점
기존의 배포 방식은 다음과 같았습니다.
- 로컬에서 원격 저장소의 변경된 코드 pull
- 로컬에서 프로젝트 빌드
- 서버에 빌드 파일 복사
- 터미널로 서버 접속하거나
- FileZilla로 연결해서 복사
서버를 재실행할 필요까지는 없어서 단계가 많아 보이지는 않지만, 수정이 잦아지면서 배포에 들어가는 시간이 많아졌습니다. 프론트엔드 개발을 혼자 담당하고 있었고, 시간이 한정적이기 때문에 기능 개발을 할 수 있는 시간은 짧아졌습니다. 그래서 기능 개발에 더 집중할 수 있는 환경을 만들고자 배포 자동화를 진행하게 되었습니다.
개선 방향
Github Action 사용
Jenkins, Travis CI 등 여러 플랫폼이 있지만 해당 프로젝트에서는 Github Actions를 선택했습니다. 프로젝트 코드를 Github에서 관리하고 있어 레포지토리 안에서 한 번에 적용할 수 있다는 점이 선택하는데 크게 작용했습니다.
빌드와 배포를 단계적으로 만들 것
Github Actions에 대한 자료를 조사했을 때, 하나의 Job에 여러 역할을 부여하는
예시를 많이 보았습니다. 하지만, 가독성과 유지보수 측면에서 단계를
세분화하는 것이 더 유리하다고 생각했습니다. 빌드
와 배포
라는 역할에 맞는
단계를 만들면, 각 단계에 수정이 필요할 때 해당 단계만 확인하면 된다는 이점도
발생합니다.
단계 세분화를 위해서는 빌드 파일을 공유하는 기능이 필요했습니다. 해당 기능을
Github Actions에서 Artifact
로 제공하고 있어 이를 사용하기로 했습니다.
프로젝트 적용
기본 설정
workflow의 이름을 지정합니다.
workflow 안에서 사용될 변수를 설정합니다.
휴먼 에러를 방지하고자 artifact에
사용할 변수명과 파일명을 미리 지정했습니다.
이벤트 지정
배포할 준비가 완료되었을 때 main 브랜치에 병합하는 브랜치 전략을 사용하고 있었기 때문에, main 브랜치에 push 될 때 실행되도록 작성했습니다.
실행 단계 세분화
Job: build
- Checkout
- Git의
checkout
명령어와 같은 역할을 하는 action입니다.
- Git의
- Node.js / pnpm / TS 세팅
- 빌드에 필요한 환경을 설정합니다.
- Node.js는 기본으로 설치되어 있지만 원하는 버전을 설정하기 위해
setup-node
를 사용합니다.
- 캐싱된 pnpm 모듈 세팅
- 빌드 시간 단축을 위해 프로젝트에서 의존하고 있는 모듈 중 캐싱된 데이터가 있으면 가져오도록 설정합니다.
- 프로젝트 빌드
- 빌드 파일 tar로 압축
- 하나의 파일로 업로드하기 위해 tar 명령어를 사용해 압축합니다.
- 빌드 파일 artifact로 저장
- deploy 단계에서 사용할 수 있도록
upload-artifact
로 저장합니다. - 변수명과 파일 경로는 미리 환경변수로 설정한 값을 사용합니다.
- deploy 단계에서 사용할 수 있도록
Job: deploy
needs
를 사용해 빌드 단계가 완료된 뒤에 실행되도록 설정했습니다. 그리고 해당
작업 단계에서 사용될 환경 변수를 미리 작성해 놓았습니다.
- Checkout
- 저장된 artifact 다운로드
download-artifact
를 사용해 build 파일을 다운로드 받습니다.- 다음 step에서 해당 단계의 결괏값을 사용할 수 있도록 id를 지정합니다.
- 서버로 빌드 파일 복사한 뒤, 압축 풀기
- scp로 서버에 빌드 파일을 복사하고, ssh로 서버에 접속해 압축을 푸는 스크립트를 실행합니다.
프로젝트 예시에서는 리눅스와 친숙해지기 위해 직접 스크립트를 작성했습니다. scp-action, ssh-action 을 사용해 좀 더 간단하게 작성할 수도 있습니다.
실행 결과
Actions 페이지에서 확인할 수 있는 화면입니다.
build와 deploy 두 작업이 단계적으로 실행되었음과 실행 시간을 알 수 있습니다. 실행했을 때 발생했던 경고나 에러가 있다면 작업별로 표시되기 때문에 오류를 수정하기 더 수월합니다.
Artifact는 만료되기 전까지 다운로드 받을 수 있습니다. 직접 파일 확인이 필요한 경우 workflow의 결과 화면에서 artifact 이름을 클릭해 다운로드가 가능합니다.
더 나아가서
포스팅을 작성하며 코드를 살펴보니 수정이 필요한 부분들이 보였습니다.
Checkout action의 반복
사실 현재 배포 단계에서는 저장소 파일이 아닌 artifact를 사용하기 때문에 Checkout이 필요하지 않아 삭제해도 됩니다. 하지만 만약 필요한 상황이 된다면, '재사용할 수 있도록 만들면 좋지 않을까?' 하는 생각이 듭니다.
scp와 ssh 관련 스크립트
스크립트를 파일로 따로 분리해서 해당 파일을 실행하도록 하거나 이미 만들어진 액션을 사용하도록 수정해 보고자 합니다. 스크립트가 workflow에서 여러 줄을 차지하니 가독성이 떨어지기 때문입니다.