[CI/CD] Docker + Jenkins + Git Webhook을 활용한 FastAPI 서버 자동 배포 정리
실전 압축 자동 배포 구현하기
내용 정리 중 > 2023년 5월 기준 업데이트 1차 완료 배포 관련 내용은 좀 더 갈무리한 2편을 참고하는 것이 더 좋습니다.
서론
현재 진행하고 있는 프로젝트에서 인공지능 모델을 활용한 Output을 제공하는 서비스를 구축하고 있었다.
해당 기능을 Firebase Cloud Function을 통해서 구축하고 싶었지만 모델을 로드하는 과정 등에 있어서 nodeJS + tensorflow.js의 사용으로 인한 모델의 변형 불가피, 태생적인 무거움으로 인한 시간 초과 등 다양한 방식으로 억까를 당했고 이를 해결하기 위해 인공지능 모델을 통한 결과물을 반환하는 간단한 서버를 구축해보기로 했다.
이에 따라 서버를 구축 및 배포하는 과정이 내 몫으로 남게 되었고 1차적인 목표로 자동 배포의 구현, 이후 추가적인 목표로 무중단 배포까지 내 손으로 진행하고자 했다.
본 포스트에서는 AWS 등의 인스턴스를 기반으로 한 시스템의 구축 및 자동 배포까지만 다루게 된다.
사전 개념 학습
CI: Continuous Integration (지속적 통합)
개발자를 위한 자동화 프로세스로 코드의 변경 사항이 빌드와 테스트를 거쳐서 정기적으로 공유 리포지토리에 병합되는 과정으로 이 과정의 자동화는 개발 과정에 있어서 위험성을 줄이는 방안으로 사용되고 있음
CI Server, Source Control Management, Build Tool, Test Tool 등으로 구성
CD: Continuous Delivery / Deployment (지속적 배포)
배포 자동화 프로세스를 의미하며 파이프라인의 추가 단계에 대한 자동화를 통해 수동적인 개입 없이 변경사항이 product까지 자동적으로 배포되는 것이 가능, 지속적 통합 과정이 뒷받침되어야 하며 신뢰할 수 있는 환경을 구축한다면 하루에도 여러 번의 릴리스가 이루어질 수 있음
결과적으로 이러한 CI/CD 과정을 통해 제품 출시까지 걸리는 시간을 단축시킬 수 있고 인력의 효율성을 증대시키며 점진적이고 지속적인 과정들의 연속이기 때문에 큰 문제가 발생할 확률을 줄여나갈 수 있다.
Docker 환경 세팅
- 인스턴스 정보
EC2 프리티어 대신 상대적으로 조건이 좋은 Oracle Cloud의 프리티어로 결정 arm64 기반의 Ampere A1 Compute 2Core 및 12GB RAM을 할당해서 사용
이 외에도 백업 등의 옵션을 무료로 어느 정도 지원하니 참고!
- 리눅스 세팅 EC2 password로 접속하는 방법 - 로그인 관련 편의사항으로 ssh 세팅에 대해 다루는 글 도커 설치 - 우분투 기준 도커 설치 DOCS
필자가 참고한 자료를 정리했으며 도커 설치하는 과정 및 인스턴스 세팅에 대한 글은 많이 존재하고 있으니 찾아보면서 Docker를 세팅해주면 된다.
Docker in Docker 세팅 (실패 > API를 활용한 Docker out of Docker로 진행)
사용 이유
도커 위에서 추가적으로 도커를 다루는 이유는 컨테이너를 컨테이너를 통해 통제하기 위함이며 기본적으로 해당 컨테이너의 권한이 막강해지기 때문에 보안의 위험성을 제기하기도 하지만 그 자체만으로 매력적인 것은 분명하다.
세팅했던 방법
1. Docker 위에 Jenkins 컨테이너 빌드
먼저 Jenkins 컨테이너를 도커에서 빌드한다. Docker Compose를 사용하면 조금 더 쉽게 빌드할 수 있으니 참고하도록 하자.
docker pull jenkins/jenkins:lts
먼저 젠킨스 LTS 버전의 컨테이너를 받아준다.
vim docker-compose.yml
yml 파일을 해당 명령어를 통해 생성 혹은 열어준다.
version: "2.5.0" # compose 버전을 입력할 것
services:
jenkins:
container_name: jenkins
image: jenkins/jenkins:lts # Jenkins LTS 버전을 사용
restart: always # 자동 재시작 옵션
ports:
- "8181:8080" # host의 8181 포트를 Jenkins의 8080 포트로 연결
volumes: # host의 volume을 해당 옵션을 통해 공유할 수 있다.
- /home/opendocs/jenkins:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
user: root
privileged: true # Docker In Docker 사용을 위한 핵심 옵션
yml 파일에 예시 코드와 같이 필요한 내용을 입력한다.
docker-compose -f {파일명} up
해당 명령어를 통해 docker-compose.yml을 기반으로 한 세팅을 진행할 수 있으며 파일명의 변경이 없이 docker-compose.yml이라는 이름 그대로 사용한다면 -f 옵션을 사용하지 않아도 된다. 자세한 것은 Docker Compose Docs를 참고하도록 하자!
+ sudo 없이 docker 사용하는 방법 → Docker 그룹에 현재 사용자를 추가하기
# 해당 명령어를 통해 현재 사용자를 Docker 그룹에 추가할 수 있음
sudo usermod -aG docker $USER
2. Jenkins Container 세팅
- 설정한 IP주소의 Docker를 통해 할당한 Port Number로 브라우저 접속
- Jenkins 설치 로그에 적힌 키를 화면에 입력하기
# 해당 명령어를 통해 컨테이너의 로그를 확인할 수 있음
docker logs jenkins
- 추천 플러그인 설치하기
문제가 발생할 수 있는데 일단 설치 마무리 짓고 이후에 해결하면 된다. 마무리 짓지 않으면 설치되지 않은 플러그인으로 인해 의존성 에러가 계속 발생한다...
- GitHub API Plugin 설치하기
Webhook 트리거로 작동시킬 수 있도록 도와주는 플러그인이다. 설치해주자. 설치 뒤 Secret으로 Git ID/PW 등록해둘 것.
3. Github 설정
-
Settings의 Developer Settings 내의 Token을 생성하도록 한다. 현재 글 쓰는 시점 기준으로 Classic 토큰을 사용하며 repo, admin:repo_hook 정도만 권한 설정해주면 된다.
-
자동 배포할 Repo 설정에서 Webhooks에 Webhook을 추가한다. http://{jenkins_url}/github-webhook/ 정도로 설정하면 된다. 마지막 / 를 빼면 문제가 생길 수 있으니 얌전히 달아두자.
4. Jenkins 프로젝트 세팅
-
프로젝트를 추가한다.
-
빌드 구성 - 소스 코드 관리에서 Git을 선택하고 기존에 등록한 Secret을 골라주면 webhook 신호를 받을 수 있다.
-
GitHub hook trigger for GITScm polling 옵션을 골라줘야 트리거 작동이 된다.
-
필요에 따라 branch 선정도 진행 후 세팅을 마무리 지어주고 테스트를 진행하도록 하자.
댓글 작성
게시글에 대한 의견을 남겨 주세요.