Discover us

About us

Projects

Blog

Events

Members

Development Blog

GDGoC CAU 개발자와 디자이너의 작업 과정과
결과물을 공유하는 공간입니다.

어떻게 프로젝트를 시작하게 되었고,
진행하면서 느낀 개발자와 디자이너의
생생한 스토리를 직접 확인해보세요!

Development

Travis CI 배포 자동화

  • #Back-End
  • hwikyung kim
  • 2023. 9. 18.

Travis CI 배포 자동화

스프링 스터디 7주차(챕터9)

CI & CD 란?

  • CI(Continuous Integration-지속적 통합)은 코드 버전 관리를 하는 VCS 시스템(git, svn 등)에 PUSH가 되면 자동으로 테스트와 빌드가 수행되어 안정적인 배포 파일을 만드는 과정
  • CD(Continuous Deployment-지속적인 배포)은 이 빌드 경과를 자동으로 운영 서버에 무중단 배포까지 진행되는 과정

Github와 Travis CI 연동

  • Travis CI는 깃허브에서 제공하는 무료 CI 서비스
  • 젠킨스와 같은 CI 도구도 있지만, 젠킨스는 설치형이기 때문에 이를 위한 EC2 인스턴스가 하나 더 필요
    • 프로젝트에 Travis CI(.travis.yml) 설정
      • Travis CI의 상세한 설정은 프로젝트에 존재하는 .travis.yml 파일 로 할 수 있습니다. build.gradle과 같은 위치에 해당 파일 생성
  • Travis CI에 접속해서 깃허브 계정으로 로그인을 한 뒤, 왼쪽 위에 계정명 > Setting 을 클릭, 그리고 해당 프로젝트를 활성화 시킨다 * Travis CI Web Service 에서 Github 계정 로그인 * Travis Settins 에서 연동할 Github repository 활성화
사진 수정하기!!!!
notion image

프로젝트 설정

  • travis.yml 추가
    • build.gradle 동일한 위치에 추가 ``` language: java jdk: openjdk8

Travis CI 를 어느 branch 가 push 될 때 수행할지 설정

branches: only: master

gradle 통해 의존서을 받게 되면 해당 디렉토리에 cache 하여,

같은 의존성은 다음 배포 때부터 받지 않도록 설정

cache: directories: - ‘HOME/.m2/repository′ − ′HOME/.gradle’
before_install: - chmod +x gradlew

branch 에 push 되었을 때 수행하는 명령어

script: “./gradlew clean build”

Travis CI 실행 완료 후 자동 알림 설정

notifications: email: recipients: - [메일 주소] ``` * Travis CI + AWS S3 연동 * AWS S3는 일종의 파일 서버d * 정적 파일이나 배포 파일들을 관리하는 기능을 지원하며, 보통 이미지 업로드를 구현한다면 이 S3를 이용하여 구현하는 경우가 많음
 
  • IAM 사용자 만들기
    • 사용자 세부 정보 설정
    • 사용자 이름 > jimmyberg-travis-deploy
    • AWS 액세스 유형 선택 > 프로그래밍 방식 액세스
    • 권한 설정 및 기존 정책 직접 연결
    • AmazonS3FullAccess, AmazonCodeDeployFullAccess 태그 추가
    • 키 : Name, 값 : jimmyberg-travis-deploy
  • Travis CI에 S3 액세스 키 등록
    • 연동한 repository 의 settings 에서 키 등록
    • AWS_ACCESS_KEY(액세스 키)
    • AWS_SECRET_KEY(비밀 액세스 키)
    • .travis.yml 에서 $AWS_ACCESS_KEY, $AWS_SECRET_KEY 으로 사용
  • S3 버킷 생성
  • 버킷 이름 > spring-study
  • .travis.yml 수정
... script: "./gradlew clean build" # 수정 start # deploy 가 실행되기 전에 수행 # CodeDeploy 는 Jar 파일 인식하지 못하므로 # 프로젝트를 압축한 zip 파일로 전달 before_deploy: - zip -r rest-api ./* - mkdir -p deploy - mv rest-api.zip deploy/rest-api.zip # 외부 서비스와 연동될 명령어 정의 deploy: - provider: s3 access_key_id: $AWS_ACCESS_KEY secret_access_key: $AWS_SECRET_KEY bucket: spring-study region: ap-northeast-2 skip_cleanup: true acl: private local_dir: deploy # 지정한 위치의 파일들만 S3로 전송 wait_until_deployed: true # 수정 end notifications: ...
모든 퍼블릭 엑세스 차단
notion image
notion image
S3 버킷 생성 완료
  • Travis CI, S3, CodeDeploy 연동
  • EC2 에 IAM 역할 추가 * EC2 > 인스턴스 설정 > IAM 역할 연결/바꾸기 * ec2-codedeploy-role 역할 선택 * EC2 인스턴스 재부팅
  • EC2 에 CodeDeploy agent 설치
$ aws s3 cp s3://aws-codedeploy-ap-northeast-2/latest/install ./s3 --resion ap-northeast-2 # 설치 디렉토리 이동 $ cd s3 # 실행 권한 추가 $ chmod +x ./install # install 파일 설치 $ sudo ./install auto # CodeDeploy agent 상태 확인 $ sudo service codedeploy-agent status
  • 연동 설정 파일 추가 및 수정
    • EC2 에 zip 파일 저장 디렉토리 생성
    • $ mkdir /home/ec2-user/s3/zip/rest-api
    • appspec.yml 추가
    • version: 0.0 os : linux files : # CodeDeploy 에서 전달해준 파일 중 destination 으로 이동시킬 대상 지정 - source : / # source 에서 지정된 파일을 저장할 위치 destination: /home/ec2-user/s3/zip/rest-api/ # 덮어쓰기 여부 overwrite : yes
    • .travis.yml 수정
    • deploy: ... - provider: codedeploy access_key_id: $AWS_ACCESS_KEY secret_access_key: $AWS_SECRET_KEY bucket: jimmyberg-rest-api key: rest-api.zip bundle_type: zip application: rest-api deployment_group: rest-api-group region: ap-northeast-2 wait_until_deployed: true
  • EC2 에 저장된 zip 디렉토리 확인
  • 배포 자동화 구성
  • 프로젝트에 deploy.sh 추가
# project > scripts > deploy.sh #!/bin/bash REPOSITORY=/home/ec2-user/apps DEPLOY_DIRECTORY=/home/ec2-user/deploy PROJECT_NAME=rest-api echo "> Build 파일 복사" cp $DEPLOY_DIRECTORY/$PROJECT_NAME/*.jar $REPOSITORY/$PROJECT_NAME/ echo "> 현재 구동중인 애플리케이션 pid 확인" CURRENT_PID=$(pgrep -fl $PROJECT_NAME | grep jar | awk '{print $1}') echo "> 현재 구동 중인 애플리케이션 pid: $CURRENT_PID" if [ -z "$CURRENT_PID" ]; then echo "> 현재 구동 중인 애플리케이션이 없으므로 종료하지 않습니다." else echo "> kill -15 $CURRENT_PID" kill -15 $CURRENT_PID sleep 5 fi echo "> 새 애플리케이션 배포" JAR_NAME=$(ls -tr $REPOSITORY/$PROJECT_NAME/*.jar | tail -n 1) echo "> JAR Name: $JAR_NAME" echo "> $JAR_NAME 에 실행권한 추가" chmod +x $JAR_NAME echo "> $JAR_NAME 실행" rm $REPOSITORY/$PROJECT_NAME/nohup.out nohup java -jar -Dspring.profiles.active=alpha -Dfile.encoding=UTF-8 $JAR_NAME > $REPOSITORY/$PROJECT_NAME/nohup.out 2>&1 &
  • .travis.yml 수정
language: java jdk: - openjdk8 branches: only: - master cache: directories: - '$HOME/.m2/repository' - '$HOME/.gradle' before_install: - chmod +x gradlew script: "./gradlew clean build" before_deploy: - echo $(pwd) - mkdir -p before-deploy - cp scripts/*.sh before-deploy/ - cp appspec.yml before-deploy/ - cp build/libs/*.jar before-deploy/ - cd before-deploy && zip -r before-deploy * - cd ../ && mkdir -p deploy - mv before-deploy/before-deploy.zip deploy/rest-api.zip deploy: - provider: s3 access_key_id: $AWS_ACCESS_KEY secret_access_key: $AWS_SECRET_KEY bucket: jimmyberg-rest-api region: ap-northeast-2 skip_cleanup: true acl: private local_dir: deploy wait-until-deployed: true - provider: codedeploy access_key_id: $AWS_ACCESS_KEY secret_access_key: $AWS_SECRET_KEY bucket: jimmyberg-rest-api key: rest-api.zip bundle_type: zip application: rest-api deployment_group: rest-api-group region: ap-northeast-2 wait-until-deployed: true notifications: slack: [slack accesss key]
  • appspec.yml 수정
version: 0.0 os : linux files : - source : / destination: /home/ec2-user/deploy/rest-api overwrite : yes # CodeDeploy 에서 EC2 로 넘겨준 파일 모두 ec2-user 권한 설정 permissions: - object: / pattern: "**" owner: ec2-user group: ec2-user # CodeDeploy 배포 단계에서 실행할 명령어 설정 # ApplicationStart 단계 : ec2-user 권한으로 deploy.sh 실행 hooks: ApplicationStart: - location: deploy.sh timeout: 60 runas: ec2-user
  • 배포 Log 확인 방법
  • CodeDeploy 관련 Log
$ cd /opt/codedeploy-agent/deploayment-root/ $ vi ./deployment-logs
  • 프로젝트 관련 Log
$ cd ~/apps/rest-api/ $ vi ./nohup.out
EC2에 RDS 접근 확인
notion image