우주먼지
article thumbnail

1. 💡 Auto Deployment

준비사항

1. Github Actions 생성
2. S3 버킷 & 정적 웹 호스팅 비활성화 & Public Access 차단 해제

3. AWS Code Deploy
4. EC2 & t2.micro Free Tier Memory 증설( https://root-ca.tistory.com/235 )
5. RDS

 

1.1. Github Actions 생성 & 설정

  • java with gradle -> start commit
  • repo -> settings - secrets/actions -> new repository secret
  • AWS_ACCESS_KEY, AWS_SECRET_ACCESS_KEY 등록

 

1.2. gradle.yml 수정

  • Build with Gradle 부분을 설정하여 직접 빌드 방식으로 빌드 진행
  • application.yml & data.sql 을 전부 github actions secret으로 넣는 방식으로 진행
<java />
# This workflow uses actions that are not certified by GitHub. # They are provided by a third-party and are governed by # separate terms of service, privacy policy, and support # documentation. # This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle name: Java CI with Gradle on: push: branches: [ "main" ] permissions: contents: read env: S3_BUCKET_NAME: deploy011-bucket-replicaset jobs: build: defaults: run: working-directory: ./server runs-on: ubuntu-latest steps: # 1. Set-Up JDK - uses: actions/checkout@v3 - name: Set up JDK 11 uses: actions/setup-java@v3 with: java-version: '11' distribution: 'temurin' # 2. init Data 생성 - uses: actions/checkout@v3 - name: create init data run: | touch ./src/main/resources/application.yml echo "${{ secrets.YML }}" > ./src/main/resources/application.yml touch ./src/main/resources/data.sql echo "${{ secrets.INIT_DATA }}" > ./src/main/resources/data.sql - uses: actions/upload-artifact@v3 with: name: application.yml path: ./src/main/resources/application.yml - uses: actions/upload-artifact@v3 with: name: data.sql path: ./src/main/resources/data.sql - name: Run chmod to make gradlew executable run: chmod +x ./gradlew working-directory: ./server # - name: Test Build # run: ./gradlew test -i # working-directory: ./server - name: Build with Gradle run: ./gradlew build working-directory: ./server # - name: Build with Gradle # uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1 # with: # arguments: build - name: Make zip file run: zip -r ./main.zip . shell: bash - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }} aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }} aws-region: ap-northeast-2 - name: Upload to S3 run: aws s3 cp --region ap-northeast-2 ./main.zip s3://$S3_BUCKET_NAME/main.zip - name: Code Deploy run: > aws deploy create-deployment --application-name main --deployment-config-name CodeDeployDefault.AllAtOnce --deployment-group-name main-group --s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=main.zip

 

CI 성공
S3로 빌드 결과물 자동 전송 완료


1.3. AWS CodeDeploy & 배포그룹 생성

  • --- CodeDeploy --- (인스턴스 내에 CodeDeploy-Agent 설치가 되어있어야함)
  • 어플리케이션 - 생성 - 배포그룹 생성
  • IAM & Instance Tag 지정, LoadBalancer 비활성화

어플리케이션 & 배포그룹 생성


1.4. appspec.yml & deploy.sh 작성

<bash />
# appspec.yml version: 0.0 os: linux files: - source: / destination: /root overwrite: yes permissions: - object: / pattern: "**" owner: root group: root hooks: ApplicationStart: - location: scripts/deploy.sh timeout: 60 runas: root

 

<java />
#!/bin/bash # deploy.sh BUILD_JAR=$(ls /root/main/back/build/libs/main-SNAPSHOT.jar) JAR_NAME=main # basename = 확장자,경로 전부 삭제하고 파일명만 반환하므로 주석처리 echo "> 현재 시간: $(date)" >> /root/main/back/log/deploy.log echo "> build 파일명: $JAR_NAME" >> /root/main/back/log/deploy.log echo "> build 파일 복사" >> /root/main/back/log/deploy.log DEPLOY_PATH=/root/main/back/build/libs cp $BUILD_JAR $DEPLOY_PATH echo "> 현재 실행중인 애플리케이션 pid 확인" >> /root/main/back/log/deploy.log CURRENT_PID=$(pgrep -f $JAR_NAME) if [ -z $CURRENT_PID ] then echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다." >> /root/main/back/log/deploy.log else echo "> kill -9 $CURRENT_PID" >> /root/main/back/log/deploy.log sudo kill -9 $CURRENT_PID sleep 5 fi DEPLOY_JAR=$BUILD_JAR echo "> DEPLOY_JAR 배포" >> /root/main/back/log/deploy.log cd /root/main/back/log/build/libs sudo nohup java -jar $DEPLOY_JAR >> /root/main/back/log/deploy.log 2>/root/main/back/log/deploy_err.log &

 

1.5. EC2 인스턴스 생성 (Elastic IP 설정)


1.6. 보안그룹 포트 오픈

  • 3306 - DB Connection Endpoint (Dual Stack 까지 오픈)
  • 3000 - React Connection Endpoint 1
  • 3001 - React Connection Endpoint 2
  • 8080 - Spring Boot Endpoint
  • 22 - SSH Endpoint
  • 6379 - RDS Endpoint
  • 5000 - Docker Private Registry Endpoint

 

1.7. Github SSH Key 등록

 

1.8. EC2 내부 패키지 설치

 

1.8.1. JDK 설치

  • amazon-linux-extra install -y openjdk11

 

1.8.2. GIT 설치

  • yum -y install git

 

1.8.3. AWS CLI 설치


1.8.4. CodeDeploy Agent 설치

  • yum -y update
  • yum -y install gcc (C Compiler)
  • gpg2 --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
  • curl -sSL https://rvm.io/pkuczynski.asc | gpg2 --import -   -> import gpg key 
  • curl -sSL https://get.rvm.io | bash -s stable  (rvm 설치 스크립트)
  • source /etc/profile.d/rvm.sh  (시스템 환경변수 & rvm 정보 업데이트)
  • rvm reload
  • rvm requirements run  (rvm 의존성 패키지 설치)
  • rvm list known
  • rvm install [version] (2.7)
  • rvm list
  • rvm use [version] --default
  • ruby -v
  • gem install aws-sdk  (Ruby용 sdk 설치)
  • wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
  • chmod +x install
  • ./install auto > /tmp/logfile
  • service codedeploy-agent status

Code Deploy Agent 설치


1.9. IAM Role 생성

  • AmazonS3FullAccess
  • AmazonEC2RoleforAWSCodeDeploy
  • AWSCodeDeployRole
  • AmazonSSMFullAccess
  • AmazonEC2FullAccess
  • IAM Role 과 IAM UserGroup의 태그 연결하기

 

추가한 정책 목록

 

신뢰정책에 내 리전의 codedeploy 서비스 추가

 

EC2에 IAM Role 연결


2.  EC2 < - > RDS 연결

RDS 생성
EC2내에 mariadb 설치 후 RDS Endpoint 연결

 

2.1. Application Settings

  • build.gradle
<bash />
runtimeOnly 'com.mysql:mysql-connector-j'
  • application.yml
  • 첫 배포시 ddl-auto = create & sql.init.mode = always
  • 이후 ddl-auto = none & sql.init.mode = never
<java />
server: port: 8080 servlet: context-path: / spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://{RDS-endpoint}:3306/{database-name}?serverTimezone=UTC&characterEncoding=UTF-8 username: root password: pw data: classpath:data.sql # url: jdbc:h2:tcp://localhost/~/test # username: sa # password: # driver-class-name: org.h2.Driver # h2: # console: # enabled: true # path: /h2 jpa: hibernate: ddl-auto: create # 애플리케이션 실행 시 기존 테이블 삭제 후 테이블 새로 생성 # 추후 validate나 none으로 변경할 것 show-sql: true # 콘솔창에 sql 출력 properties: hibernate: format_sql: true # sql 예쁘게 출력 default_batch_fetch_size: 500 # 일대다 컬렉션 조회 시 성능 최적화 # 쿼리에서 조건문 in절로 수행하게됨, n번 쿼리 수행 -> 1번 쿼리에서 수행(n개를 파라미터로 넣어줌) # DB와 애플리케이션 부하를 고려해서 개수를 설정할 것 # oracle의 경우 최대 1000개 # dialect: org.hibernate.dialect.MySQLDialect open-in-view: true # 영속성 컨텍스트의 생존 범위를 트랜잭션 범위로 한정 # 기본값 true -> View 랜더링 또는 API 요청일 경우 클라이언트 응답까지 영속성 컨텍스트 생존 # false 설정 시 -> 생존 범위가 트랜잭션 범위로 줄어들게 됨 # -> 컨트롤러에서 지연로딩으로 연관된 엔티티를 가져오려고 하면 에러 발생 # 영속성 컨텍스트를 오래 유지하면 DB Connection도 오래 갖고 있으므로 DB Connection이 부족할 수 있음 # -> 실시간 트래픽이 중요한 API 애플리케이션에서는 false로 유지할 것 defer-datasource-initialization: true # 스프링부트 2.5버전 이상 사용 시 data.sql 사용 database: mysql database-platform: org.hibernate.dialect.MySQL5InnoDBDialect sql: init: mode: never # 모든 데이터베이스에 sql 스크립트를 동작 data-locations: classpath:data.sql servlet: multipart: max-file-size: 10MB # 파일 업로드 요청 시 하나의 파일 크기를 10MB 제한 max-request-size: 100MB # 파일 업로드 요청 시 모든 파일 크기합을 100MB 제한 mvc: pathmatch: matching-strategy: ant_path_matcher # swagger 사용을 위한 설정 logging: level: org.hibernate.type: debug # 콘솔창에 조건에 바인딩되는 값 및 조회 결과 출력 package com.server.seb41_main_11: debug # todo 패키지 수정 # spring cloud openfeign(외부 API 호출을 쉽게 할 수 있도록 도와줌) # 의 로그를 보기 위해서 프로젝트 루트 패키지 기준으로 debug 설정 feign: client: config: default: connectTimeout: 5000 readTimeout: 5000 # 3-way-handshake 과정의 시간 설정(5초) # 연결은 됐는데 요청한 서버에서 응답이 5초내로 오지 않으면 에러 발생(readTimeout)

 

2.2. 배포 성공 및 Postman 테스트 완료

'Project > Main Project' 카테고리의 다른 글

💻 기능 개발 - 결제  (0) 2023.01.27
💻 기능 개발 - 프로그램  (0) 2023.01.27
💻 기능 개발 - 상담사  (0) 2023.01.27
💻 기능 개발 - 공지사항  (0) 2023.01.26
💻 기능 개발 - 게시물  (0) 2023.01.26
profile

우주먼지

@o귤o

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그