본문 바로가기

프로젝트/푸드피커

[푸드피커] Github Actions 를 활용한 NodeJS 백엔드 배포 CI/CD 구축(With 국내 클라우드 플랫폼 Cloudtype )

반응형

들어가기 전 | 배포 방향과 클라우드 타입 내부 동작 원리

저번 시간에는 Github Actions 을 이용한 프론트엔드 배포를 시도하였습니다. 이번 시간에는 NodeJS Express 기반의 백엔드를 배포하려고 합니다.

 

배포에 사용되는 도구는 Github Actions 를 사용합니다. 배포 클라우드 플랫폼은 국내에서 활발하게 활동 중이고 가파르게 성장중엔 Cloud Type 을 이용할 예정입니다. 참고로 클라우드타입은 내부적으로 도커 컨테이너를 사용합니다. 깃허브 레포지토리에서 소스파일을 받아온 후 해당 파일을 도커 이미지로 만들고 생성된 컨테이너를 서버에서 실행하는 방식으로 동작합니다.

 

백엔드 레포지토리의 경우에는 공개된 저장소가 아닌 비공개 저장소에 접근하여 프로젝트를 배포 합니다. 이렇게 하는 이유는 해당 프로젝트에서 사용되는 데이터베이스가 SQLite 이므로, 저장소를 통해 외부에 노출되기 때문입니다. (물론,  사용자 개인 정보를 포함한 프라이버시 정보를 절대 포함시키지 않습니다). 이를 최대한 방지하기 위한 목적으로 사용하였습니다.

 

기본적으로 클라우드타입이라는 플랫폼을 이용하여 깃허브 액션을 통해 배포하는 사용자의 입장에서 배포의 방향은 아래와 같을 겁니다. 그 만큼 플랫폼 내부적으로 추상화되어 진행되기 때문에, 복잡한 배포 환경을 구축하는 것은 생각보다 많은 제약이 따를 수 있습니다. 

 

현 프로젝트에서 사용된 백엔드는 매우 구조가 단순합니다. 빌드 크기도 크지 않고, 사용자의 개인정보 등의 암호화하여 보관할 필요가 있는 정보를 데이터베이스에 저장하지도 않습니다. 과도한 트래픽이 매일 발생하는 상황도 아닙니다. 여러 조건을 비교해본 결과 사용해도 좋다는 결론을 얻어서 해당 플랫폼 서비스를 이용합니다.

 

만일 이 포스트를 보고, 현 플랫폼을 사용하고자 결정하셨다면, 그 전에 마지막으로 현재 프로젝트 환경에 부합하는지 공식 문서(https://docs.cloudtype.io/guide/welcome/before-using) 를 참고해보시길 바랍니다. 무턱대고 적용하는 것은 향후 유지보수와 확장에 제약이 있을 수 있습니다. 이를 명심하고 진행해봅시다.

 

그럼 시작하겠습니다


 

환경설정 | 클라우드 타입 배포용 키 생성

깃허브 SSH URL 복사

우선 배포용 키 생성에 필요한 SSH URL 을 카피해 줍니다. 위치는 깃허브 레포지토리 -> Code -> Local -> SSH 순으로 접근 후 클립보드 복사 아이콘을 클릭해줍니다.

 

생성된 배포용 키를 보려면?

클라우드타입 회원가입 후  대시보드로 접속하게 되면 아래 톱니바퀴가 보입니다. 이를 클릭해 줍니다.

 

 

 

그러면 좌측 카테고리에 키관리가 보일텐데 이를 클릭해 줍니다.

 

키관리 페이지에서 하단에 보면 파란색 버튼으로 디플로이 키 생성하기 를 눌러줍니다. 그리고 앞서 클립보드에 복사한 SSH URL 을 붙여넣기 후 저장해 줍니다.

 

다시 키 관리 화면으로 돌아온 후 목록을 확인해보면 추가된 디플로이 키가 보입니다. 그리고 이를 드롭다운하면 아래와 같이 ssh-rsa-AAA~ 가 보일텐데 이를 복사해줍니다.

 

환경설정 | 프로젝트 생성 및 깃허브 배포용 키 등록

깃허브 SSH URL 복사

생성한 프라이빗 저장소에서 Code -> Local -> SSH 로 들어오면 탭 카테고리 하단에 주소가 보입니다. 이를 복사해 줍시다. 

프로젝트 생성

그 후 클라우드 타입으로 돌아와서 프로젝트를 생성해줍니다. 양식에 맞춰서 작성 후 생성하기를 눌러 줍니다. 저의 경우에는 푸드피커 백엔드라고 미리 만들어 두었습니다.

현재 리전은 한국- 서울 하나 뿐 입니다(2024.06.12 기준).

 

깃허브 연동 및 배포 키 등록

생성된 프로젝트 를 클릭하면, 우측 화면에 아래와 같이 표시됩니다. 여기서 + 를 눌러줍시다

 

그러면 아래 화면이 뜨는데, 그 중에서 Git URL로 배포하기를 클릭해줍니다.

 

그러면 하단의 Git 저장소 배포하기 밑에 URL 을 입력하는 창이 보입니다. 앞서 복사한 SSH URL 을 붙여넣기 해줍니다.

 

 

그러면 하단에 암호화된 SSH 접속용 배포키가 뜨는 것을 볼 수 있습니다. 이를 복사해 줍니다.

 

이제 깃허브 레포지토리에 돌아 옵니다. Settings -> Deploy Keys -> Add deploy Key 를 차례대로 눌러줍니다.

 

 

그러면 하단의 화면이 뜰텐데 앞서 복사한 SSH 키를 붙여넣기 해줍니다. 그 후  Add Key를 눌러줍시다. title 은 자유롭게 지정해도 되고, Allow write access 는 체크하지 않습니다.

 

 

클라우드 타입 배포

앞서 SSH 키를 발급받고 디플로이 키를 깃허브에서 생성 하였습니다. 이제 다시 해당 화면으로 돌아와서 나머지 배포를 위한 옵션을 작성해줍니다. 이 부분은 크게 설명할 것이 없습니다. 각자의 배포 환경에 맞게 설정해줍니다. 그 후 최하단의 배포하기를 클릭해줍니다.

 

그러면 배포가 시작되고 있다는 화면이 뜨는데, 잠시 기다려 줍시다.

 

배포 결과

수동적인 방식으로는 정상적으로 서버 실행을 성공하였습니다. 사실 한 번에 성공한 것은 아니고, 아주 사소한 문제를 경험하였지만, 그래도 결과는 성공 입니다.

 

 

Github Actions 을 이용한 배포 자동화

클라우드 타입에서는 배포 자동화를 위한 Github Actions 코드를 프로젝트 생성 후 깃허브 레포지토리와 연동하게 되면 자동으로 템플릿을 만들어 사용자에게 제공해주고 있습니다. 따라서 해당 템플릿을 사용하여 CI/CD 를 설정해볼 것입니다.

 

클라우드타입에서 제공해주는 깃허브 액션 템플릿 코드 복사

배포된 프로젝트를 보면 하단 에 CLI 가 보일 겁니다. 이를 클릭해 줍니다.

 

하단으로 쭈욱 스크롤 하다보면 깃허브 액션 템플릿이 보입니다. 해당 코드는 앞서 우리가 배포를 위해 설정했던 모든 정보들이 자동으로 입력되어 있습니다. 

 

 

.github/workflows/deploy-deploy.yaml  경로 생성 및 yaml 파일 작성

우선 프로젝트의 루트 경로 (즉, src 폴더와 나란히 위치한 경로)에 .github/workflows/deploy-deploy.yaml  파일을 생성해줍니다. 참고로 yaml 파일 이름은 앞서 템플릿 제목 하단에 나와 있습니다.

각자의 yaml 파일명은 각자 배포 후 깃허브 액션 템플릿 제목의 하단에 나와 있습니다.

 

 

앞서 템플릿에서 복사한 코드를 붙여넣기 해줍니다.

 

그런데 secrets 아래로 노란색의 밑줄이 끄어져 있는 것을 볼 수 있습니다. 이는 깃허브 액션을 위한 비밀키로 등록한 키가 아니기 때문에 발생한 부분입니다. 따라서 이 부분을 깃허브 레포지토리로 가서 추가해줘야 합니다.

 

 

GitHub Personal Token 발급받기

앞서 GHP_TOKEN 을 의미 합니다. 우선 해당 토큰 부터 발급 받아 봅시다.

 

깃허브 계정 프로필 -> Settings 

우선 깃허브 계정 프로필이 보이는 아이콘을 클릭해줍니다. 그리고 Settings 항목을 찾아서 클릭해줍시다.

Developer Settings 

좌측 메뉴에서 최하단으로 이동해서 보면 Developer Settings 항목이 보이면 클릭해 줍니다.

Tokens (classic) -> Generate new Token -> generate new token( classic)

개발자 셋팅 화면으로 이동하면 Tokens (classic) -> Generate new Token -> generate new token( classic) 을 차례대로 클릭해줍니다.

 

옵션 지정 후 생성하기

그럼 아래 화면이 보일 겁니다. 토큰 식별 이름, 만료날짜, 조회가능한 범위를 각각 지정해야 합니다. 만료 기간은 최대한 짧은게 좋다고 하지만 너무 자주 만료되어도 불편하므로 저의 경우에는 90일로 지정했습니다.

 

그리고 Select scopes 의 경우에는 클라우드 타입에서 명시적으로 repo 와  admin:public_key 를 필요로 한다고 하였으므로 이를 선택해줍니다. 

 

생성된 GPT 토큰 복사 후 비밀키로 설정하기

앞서 화면으로 돌아오면 아래와 같이 키가 생성된 것을 볼 수 있습니다. 해당 키는 딱 최초 1번 만 조회가 가능합니다. 즉, 새로 고침 이후에는 다시 볼 수 없고, 재생성해야 하므로 이를 안전한 곳에 보관해 둡시다. 그리고 해당 키는 비밀키로 저장할 생각이므로 미리 한 쪽에 정리해둡시다(바로 복사해서 설정하기 쉽도록 하기 위해서 입니다).

 

클라우드 타입 API KEY 발급받기

이제 깃허브 액션과 리포지토리 연동에 사용할 클라우드타입 플랫폼의 API  KEY를 발급 받아야 합니다.

이 부분은 (https://docs.cloudtype.io/guide/references/apikey) 공식 사이트의 문서에 나와 있으니 참고하여 발급 받도록 합시다. 

 

 

비밀키 등록

앞서 키들을 모두 발급받았다면, 이제 해당 키들을 깃허브 액션에서 secrets. 로 접근할 수 있도록 비밀키를 등록해줘야 합니다. 프로젝트 레포지토리로 들어온 뒤 Settings -> Secrets and Variables -> Actions 로 들어 갑니다.

 

그 후 New repository secret 을 클릭합니다.

 

앞서 생성한 각 키의 이름과 값을 설정하여 생성해줍니다.

 

CI/CD 테스트 

이제 가이드라인에 따른 모든 설정이 끝났습니다. 실제로 커밋 후 정상적으로 배포 자동화가 되고 있는지 테스트 해보겠습니다.

 

저장소 푸시 후 갈색 아이콘이 표시되고 있습니다. 이는 깃허브 액션이 동작 중임을 나타냅니다.

 

해당 아이콘을 클릭 후 세부 페이지로 이동하니 정상적으로 실행이 되어 완료 되었다는 녹색 아이콘이 보입니다.

 

 

마지막으로 클라우드 타입의 프로젝트로 들어오니 정상적으로 배포 까지 이루어진 것을 모두 확인하였습니다.

 

 

 

[나가는 말] 가이드 라인이 정말 친절했습니다.

확실히 한국 플랫폼이라 그런걸까요? 가이드라인이 한국인이 쉽게 이해할 수 있도록 필요한 가이드가 정리되어 있었습니다. 깃허브 액션을 위한 파일을 구성하는 것도 여간 까다로운 것이 아닌데, 최초 배포 시 자동으로 사용자가 설정한 옵션을 기반하여 초기 템플릿을 만들어 주기 때문에, 이를 기반으로 사용자의 필요에 따라서 설정을 변경해 가며 배포할 수 있다는 점이 매력적이었던 것 같습니다. 

 

이제 배포 자동화를 통해 백엔드 배포는 성공적으로 마무리 되었습니다. 다만, 백엔드 서버와 외부 프론트엔드 간에 통신하는 부분이 마무리 되지 못해서 다음 포스트에서는 이에 대한 부분을 정리하면서 해결해 나가볼 생각입니다. 혹여나 클라우드 타입을 통해 배포 자동화를 하시는 분이 있다면 도움이 되는 포스트였기를 바라며 이상 글을 줄여봅니다.

 

비고

해당 포스트 작성을 마친 20분이 지난 시간 기준으로, 프론트엔드와 백엔드 사이의 api 연동은 비교적 쉽게 해결 되었습니다. 우선 백엔드 TCP 접근을 외부에서 허용할 수 있도록 했고, CORS 를 위해 프론트엔드 도메인만 해당 서버에 요청을 보낼 수 있도록 도메인 출처를 제한하였습니다. 프론트엔드에서도 백엔드 주소를 환경변수로 추가하여 로컬 서버로 api 요청을 보내는 것이 아닌 백엔드의 HTTP 주소로 요청이 되도록 변경하였습니다. 

https://docs.cloudtype.io/guide/references/allow-external

 

외부 TCP 접근 허용 - 클라우드타입 Docs

클라우드타입은 클라우드 기반 애플리케이션을 빠르게 개발하고 배포할 수 있는 클라우드 애플리케이션 플랫폼입니다.

docs.cloudtype.io

 

 


트러블 슈팅

return process.dlopen(module, path.toNamespacedPath(filename)); 으로 인한 서버 실행 중단

로컬에서는 정상적으로 빌드가 되고 npm run start 를 입력하면 서버 실행이 잘 됩니다. 그런데, 클라우드 타입에서 빌드 과정을 거쳐 npm run start 가 스크립트로 실행이 되면, 아래와 같이 특정 네임스페이스 경로에 있는 파일을 찾을 수 없다는 에러가 발생하고 있습니다.

 

첫 번째 해결방안 | node 버전 맞추기 -> 실패

찾아보니 해당 문제가 발생할 수 있는 원인 중 한가지로 노드 버전이 서로 불일치한 경우에도 이 문제가 발생할 수 있다고 합니다. 그래서 로컬에서 노드 버전을 확인해보니 v20.14 와 v20.11 과 같이 서로 다른 버전을 사용하고 있음을 볼 수 있었습니다.

 

따라서 최신 버전인 v20.14.0 버전을 NodeJS 사이트에 방문하여 설치해줍니다.

다시 버전을 확인하니 v20.14.0 으로 업데이트 되었습니다.

 

 

그럼 이제 새로운 버전의 노드JS 에 맞춰 관련 종속성들을 업데이트 해주기 위해 다음 명령어를 차레대로 git bash 에서 입력해줍니다.

rm -rf node_modules # 기존 노드 모듈 삭제
npm update # V20.11 이렇게 있으면 20. 부분은 건드리지 않고, xx.11 부분을 기준으로 업데이트
npm install # package.lock.json 기준으로 종속성 설치

 

로컬에서 npm run start 후에도 문제 없이 동작합니다. 따라서 바로 배포를 시도하였으나, 같은 문제로 실패하였습니다.

 

일단 이 문제는 노드 버전의 문제는 아니었습니다. 

 

두 번째 해결방안 |  불필요한 종속성 삭제 -> 해결

에러를 유심히 살펴보니 다른 것은 내부적으로 접근하기 어렵기 때문에 가만히 두더라도 딱 한 가지 node_modules 로 접근이 가능한 모듈이 하나 보입니다. sqlite3-binding.js 라는 파일입니다. 해당 파일은 원래 sqlite3 에 대한 암호화를 쉽게 적용하게 해주는 sqlite3 래퍼 라이브러리 인데, 사실상 윈도우 환경에서 sqlite3 에 대한 암호화를 지정하는 것이 설정 러닝커브와 저작권 이슈로 포기했었습니다. 즉, 해당 라이브러리를 사용하지 않아도 기존의 sqlite3 라이브러리만 사용해도 된다는 말입니다.

 

 

이제 이 불필요한 종속성을 삭제해줍니다. 

 

삭제하고 나니 아래 에러가 발생하였지만, 이는 사용되지 않는 종속성이 import 되었기 때문에 발생한 문제이므로, 해당 패키지 대신에 sqlite3 를 가져오도록 바꿔주었습니다.

 

이제 클라우드타입 플랫폼으로 돌아가서 재배포 해보니, 다행히 성공적으로 빌드 후 서버 실행이 완료 되었습니다.

 

참고자료

 

GitHub Actions - 클라우드타입 Docs

클라우드타입은 클라우드 기반 애플리케이션을 빠르게 개발하고 배포할 수 있는 클라우드 애플리케이션 플랫폼입니다.

docs.cloudtype.io

 

반응형