express sequelize로 개발시작
개발 과정에서 sequelize의 리미트와 오프셋 설정을 쿼리스트링으로 가져올 시에 타입이 맞지 않아서 페이지 네이션을 정상작동하지 않는 문제 발생했다.
타입 체크의 중요성을 깨닫고 취업시장에서도 타입스크립트를 반 필수적으로 요구하는 것을 발견했다.
TypeScript가 기본으로 내장되어있는 Nest.js에 관심을 가지게 되었다.
express sequelize 개발 완료 후 Nest.js로 마이그레이션 계획 세웠다.
Nest.js의 ORM을 어떻게 조합할까 고민하고 직접 사용해서 테스트했다.
executeRaw
가 가진 특출난 장점이 없다. 즉, Sequelize.fn(), TypeORM QueryBuilder이 가지지 못한 장점이 없는 것이다. 그래서 alias를 지정하기 위해서 SQL 쿼리를 실행 할 수 밖에 없게 됨으로써 프로퍼티의 키네임을 바꾸기 위해서는 SQL 쿼리를 실행 하던가 아니면 매핑해서 데이터의 이름을 바꿔야하는 두 가지 선택지만 남게 된다. 데이터를 매핑하게 된다면 많은 데이터를 한번에 가져와야 할 때 데이터 처리 속도에서 손해를 보게되고 SQL 쿼리를 쓰자면 코드의 가독성과 일관성이 떨어질 수 있다는 점이 아쉽다.Timestamp
기능이다. 이를 통해서 데이터베이스의 변경 사항을 안전하게 적용하고 추적 할 수 있다.Jenkins vs GitHub Actions?
우선 완성되어있는 express sequelize를 CI/CD하기 위해서 Jenkins vs GitHub Actions 중에서 선택해야했다.
쉽게 하는 방법으로 GitHub Actions를 선택 할 수있었지만 현재 디펙토에 가까운 프로그램이 Jenkins 라는 의견이 모아졌기 때문에 Jenkins를 채택했다. 호스트 서버에 Jenkins를 설치하는 방법은 두가지 있었는데
호스트 서버에 직접 설치하는 방법
Docker를 설치하고 image를 이용하는 방법
Jenkins설치하는 방법 두 가지 다 해 본결과 Docker의 image를 이용하는 편이 편리 했다. 그러나 Jenkins 플러그인 설치시 재부팅과 동시에 초기화 되는 문제가 발생했다. 조사해본 결과 Docker image로 Jenkins container구성시에 -v 옵션으로 젠킨스 컨테이너가 재부팅 해도 젠킨스의 데이터가 보존 될 수 있도록 설정해야 한다는 사실을 알았다. 그리고 그리고 젠킨스의 컨테이너 내부에서 호스트의 Docker 데몬과 통신 할 수 있도록 -v /var/run/docker.sock:/var/run/docker.sock 옵션을 추가해야했다. 이 옵션은 컨테이너 안에서 도커 명령어를 실행할 수 있게 해준다.
Jenkins의 선언적 파이프라인을 이용한 **CI/CD 플랜
Git main repo에 merge 발생한다.
Jenkins가 **web 후크로 이를 감지하고 repo의 main을 클론한다.
Jenkins서버에서 클론을 바탕으로 Docker 이미지를 만들고 Jenkins의 빌드 환경변수를 Docker image에 입력해서 버전을 관리한다.
IMAGE_TAG = "gunsun/realjeans:1.0.${env.BUILD_NUMBER}"
생성한 이미지를 Docker hub에 올린다.
각 서버는 프리티어로 만들어졌기 때문에 절대적으로 용량이 부족하다. 따라서 배포 서버에 존재하는 기존 Docker container를 stop하고 삭제하며 구버전 이미지도 삭제한다. 버전 관리는 Docker hub가 담당한다.
EC2서버는 총 4개로 Nginx 서버, Jenkins 서버, 배포서버 2대이다.
Nginx EC2서버에서 라운드 로빈 방식을 취하고 있다.
서버가 2개 밖에 없기 때문에 롤링 방식으로 진행한다.
배포 서버는 각각 1번서버 2번서버로 분리되어있고 Nginx에서 각 서버를 10초마다 테스트 하고 서버가 살아있는 유무에 따라서 배포 순차적으로 진행 할 것이다.
이러한 일련의 과정을 Jenkins의 선언적 파이프라인 stage로 분할하고 성공하거나 실패하면 슬랙으로 팀원에게 알람이 전달된다.
Nest.js build를 못버티는 Jenkins EC2 프리티어 서버
//사진 첨부
Git main repo에 merge 발생한다.
Jenkins EC2서버는 main에 merge가 발생할 때, 각각 배포서버의 저장공간, docker image, docker container 상태를 확인하고 슬랙으로 정보를 보낸다.
Git Hub Actions이 이를 감지하고 이미지를 빌드해서 Docker hub에 올린다.
각 서버는 프리티어로 만들어졌기 때문에 절대적으로 용량이 부족하다. 따라서 기존의 docker container를 stop하고 삭제하며 기존의 구버전 이미지도 삭제한다. 버전 관리는 Docker hub가 담당한다.
서버가 2개 밖에 없기 때문에 롤링 방식으로 진행한다.
run: |
docker stop realjeans;docker rm realjeans;docker rmi ${{ secrets.DOCKERHUB_USERNAME }}/realjeans:realjeans
docker pull ${{ secrets.DOCKERHUB_USERNAME }}/realjeans:realjeans
docker run -i -t --env-file /home/ubuntu/newJeans.env -d -p 3000:3000 --name realjeans ${{ secrets.DOCKERHUB_USERNAME }}/realjeans:realjeans