오늘은 개발자들의 생산성을 확 높여주는 마법, CI/CD에 대해 이야기해보려고 합니다. 매번 코드를 수정하고, 빌드하고, 서버에 접속해서 파일을 올리는 반복 작업에 지치셨나요? CI/CD는 이런 과정을 자동화해서 우리가 더 중요한 일에 집중할 수 있게 도와줍니다.
🤔 CI/CD, 도대체 뭔가요?
CI/CD는 두 가지 개념의 조합입니다.
CI (Continuous Integration, 지속적 통합):
- 핵심: 개발자들이 각자 작업한 코드를 자주 중앙 저장소(GitLab의 main, stage, prod 브랜치 같은 곳)에 합치는(merge) 것입니다.
- 자동화: 코드가 합쳐질 때마다 자동으로 빌드되고 테스트됩니다.
- 장점: 코드 충돌이나 숨어있는 버그를 조기에 발견하고 수정할 수 있어, 전체 프로젝트의 안정성이 높아집니다. "어? 내 컴퓨터에선 잘 됐는데!" 같은 상황이 줄어들죠.
- YAML 파일에서: build-job, prod-build-job 부분이 바로 CI 단계입니다. 코드가 특정 브랜치로 푸시(push)되면, GitLab이 알아서 Node.js 환경을 만들고(image: node:18-alpine3.21), 필요한 라이브러리를 설치(npm install)한 뒤, 프론트엔드 코드를 웹 브라우저가 이해할 수 있는 파일들(HTML, CSS, JS)로 변환(npm run build...)합니다.
CD (Continuous Delivery/Deployment, 지속적 제공/배포):
- 핵심: CI 단계를 성공적으로 통과한 결과물(빌드된 파일)을 자동으로 실제 사용자가 접속하는 서버 환경까지 전달하는 과정입니다.
- 종류:
- 지속적 제공(Delivery): 운영 서버 배포 직전까지만 자동화하고, 실제 배포는 사람이 버튼을 눌러 승인하는 방식입니다. (안정성이 중요할 때!)
- 지속적 배포(Deployment): 모든 과정이 자동으로 진행되어, 코드가 합쳐지고 테스트를 통과하면 즉시 운영 서버에 반영되는 방식입니다. (빠른 업데이트가 중요할 때!)
- YAML 파일에서: deploy-job, prod-deploy-job 부분이 CD 단계입니다. CI에서 만들어진 build 폴더 안의 파일들을 AWS S3라는 저장소로 복사(aws s3 sync)해서 웹사이트를 업데이트합니다.
- prod-build-job과 prod-deploy-job에 when: manual 보이시죠? 이건 "운영(prod) 환경 빌드와 배포는 자동으로 하지 말고, 사람이 GitLab 화면에서 직접 실행 버튼을 눌러줘!"라는 뜻입니다. 즉, 지속적 제공(Delivery) 방식을 사용하고 있는 거죠.
- main(개발)이나 stage(테스트) 브랜치는 when: manual이 없으니, 코드 변경 시 자동으로 빌드되고 배포될 가능성이 높습니다 (설정에 따라 **지속적 배포(Deployment)**에 가깝게 운영).
🧐 잠깐, image: docker:latest는 뭐죠?
파일 상단과 deploy-job 등에서 image: docker:latest를 사용하는 것을 볼 수 있습니다. 이는 해당 CI/CD 작업을 수행할 때 기본적으로 도커(Docker) 명령어를 사용할 수 있는 환경을 사용하겠다는 의미입니다. deploy-job에서는 이 도커 환경 안에서 apk add 명령어로 AWS CLI 도구를 설치하고 S3 및 CloudFront 명령어를 실행합니다.
✨ 캐시 무효화(Invalidation), 왜 필요할까요? (feat. CloudFront)
deploy-job과 prod-deploy-job을 보면 aws cloudfront create-invalidation이라는 명령어가 있습니다. 이게 바로 '무효화' 부분인데요, 왜 필요할까요?
- S3 + CloudFront = 빠른 웹사이트: 이 프로젝트는 빌드된 웹사이트 파일(HTML, CSS, JS 등)을 AWS S3라는 파일 저장소에 저장합니다. 그리고 AWS CloudFront라는 CDN(콘텐츠 전송 네트워크) 서비스를 이용해 사용자에게 파일을 더 빠르게 전달합니다.
- CDN의 똑똑한 캐싱: CloudFront는 전 세계 여러 지역에 있는 서버(엣지 로케이션)에 우리 웹사이트 파일의 복사본을 미리 저장(캐싱)해 둡니다. 사용자가 접속하면 가장 가까운 서버에서 파일을 받으니 로딩 속도가 빨라지는 원리죠.
- 캐시의 함정: 그런데 문제가 있습니다! S3에 새 버전의 파일을 업로드(배포)해도, CloudFront 서버에는 아직 이전 버전의 파일이 캐시되어 있을 수 있습니다. 그러면 사용자는 분명 배포가 끝났는데도 옛날 화면을 보게 되는 거죠. 😱
- 무효화 마법 주문!: aws cloudfront create-invalidation --distribution-id $DISTRIBUTION_ID --paths "/*" 명령어는 CloudFront에게 "야, $DISTRIBUTION_ID 배포판에 캐시된 모든 파일(/*) 이제 유효하지 않아! 새로 가져가!" 라고 알려주는 역할을 합니다.
- 결과: 이 명령어를 실행하면, CloudFront는 캐시된 옛날 파일 대신 원본 저장소(S3)에서 최신 파일을 가져와 사용자에게 보여주고, 그 최신 파일을 다시 캐싱합니다. 덕분에 사용자는 배포 즉시 최신 웹사이트를 볼 수 있게 됩니다!
- "완료될 때까지 기다려!" 루프: while true; do ... done 부분은 CloudFront가 무효화 작업을 완료할 때까지 (상태가 Completed가 될 때까지) 10초마다 확인하는 코드입니다. 무효화는 즉시 끝나지 않기 때문에, 완료를 확인하고 파이프라인을 성공적으로 마무리하기 위한 장치입니다.
정리: 이 YAML 파일은 무슨 일을 하나요?
이 .gitlab-ci.yml 파일은 GitLab CI/CD를 통해 다음과 같은 멋진 자동화 흐름을 만듭니다.
- 개발/테스트/운영 브랜치(main, stage, prod)에 코드 변경이 감지되면:
- (CI) 자동으로 해당 환경에 맞는 프론트엔드 코드를 빌드합니다. (단, prod는 수동 실행)
- (CD) 빌드된 결과물을 각 환경의 AWS S3 버킷으로 업로드(배포)합니다. (단, prod는 수동 실행)
- (CD - 무효화) AWS CloudFront 캐시를 무효화하여 사용자가 즉시 최신 버전을 볼 수 있도록 합니다.
- 안정성 확보: 운영(prod) 환경 배포는 수동으로 실행하도록 하여(Continuous Delivery), 실수로 잘못된 코드가 배포되는 것을 방지합니다.
이제 CI/CD가 어떻게 돌아가는지, 그리고 왜 캐시 무효화가 중요한지 감이 오시나요? 이 자동화 파이프라인 덕분에 개발팀은 코드 작성에 더 집중하고, 사용자는 더 빠르고 안정적으로 새로운 기능을 만날 수 있게 됩니다! ✨
'GitHub' 카테고리의 다른 글
프론트엔드 Github Flow 관리 (3) | 2024.09.04 |
---|---|
깃허브 다운 후 브랜치 생성 및 다운 (0) | 2023.08.08 |