자바생
article thumbnail
728x90

 

YAPP20기를 진행하면서 GitHub Actions + Docker를 이용하여 CI/CD를 구축하게 됐다

CI/CD를 해보고 싶었는데 마침 같이 BE를 맡으신 분은 이미 CI/CD를 경험해보셔서 나에게 맡겨주셨다

어떻게 진행했는지 기록하기 위해서 이 글을 써보려고 한다,,

 

EC2, RDS 생성

  • 이동욱 님의 “스프링 부트와 AWS로 혼자 구현하는 웹 서비스"라는 책을 보면서 했다

 

암호화

  • 실제 배포하기 위해서는 property 파일에 RDS, Docker, IP의 ID, PW를 입력해야한다
  • 이는 노출되면 안되기 때문에 “jasypt”라는 것을 이용하여 암호화를 해준다
  • 이때 암호화 key는 우리가 나중에 Docker를 실행할 때 환경변수로 지정해주면 된다
  • 참고 : jasypt 사용
spring:
  datasource:
    url: ENC(LbJ/mHuNdf8ev0K55UK22Fu1IG78TZT6PPMNQTp3Qr8f6F6imvQ0WYkZNx2kkq3RWxkdviucv4dTVqRZ7zKFhAluy1tk4kO1xQvPk5L2/MvHXjR9MQykrbZkROeUz7Ue)
    username: ENC(OTUfXu9X9QBk4lG0mm19+A==)
    password: ENC(8d+CPaIyBQOntW/l/k6WlE9NqDqx5eoR)
    driver-class-name: com.mysql.cj.jdbc.Driver
  • ENC를 감싸서 암호를 작성하면 된다
  • 키 값은 나중에 Docker를 실행할 때 환경변수로 지정

 

오류

  • jasypt를 사용하면서 생겼던 오류는 아니지만 해당 부분에서 오류가 생겨 적어본다
  • url을 처음 적었을 때는 RDS의 엔드포인트만 적었다,,
  • “Driver com.mysql.cj.jdbc.Driver claims to not accept jdbcUrl” 발생

해결

  • url을 jdbc:mysql://[RDS 엔드포인트]:[포트번호]/[스키마 이름]으로 작성했다

 

Dockerfile 생성

  • 애플리케이션을 Docker를 이용하여 배포를 하기 때문에 Dockerfile을 생성해야한다

 

Dockerfile

FROM openjdk:11 as build
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Dspring.profiles.active=dev","-jar","/app.jar"]
  • Docker 공식문서를 통해서 해당 명령어들의 설명을 볼 수 있다
  • 제일 중요한 부분은 “-Dspring.profiles.actvie=dev”이다
  • 이번에 property 파일을 local과 dev(배포용)을 사용하기 때문에 Docker가 어느 파일을 선택할 지 결정해주는 명령어다

 

오류

  • 초기에는 “application-dev”, “application-local”, “application” 프로퍼티 파일들이 존재했다
  • 하지만 실제로 Docker를 실행했더니 위와 같이 Dockerfile을 설정해도 application 파일을 읽었다

 

해결

  • application 파일을 삭제하니 application dev로 잘 실행이 됐다

 

GitHub Actions을 이용한 CI 구축

 

name: Togather

env:
  TOGATHER_JASYPT_PASSWORD: ${{ secrets.TOGATHER_JASYPT_PASSWORD }}

# main branch에 push를 날릴 경우 GitHub Action을 실행
on:
  push:
    branches: [ main ] 

jobs:
  build:
    runs-on: ubuntu-latest

    # github repository에 접근하기 위해 check-out 하는 GitHub Action 공식 작업
    # link : <https://github.com/actions/checkout>
    steps:
      - name: Checkout
        uses: actions/checkout@v3
				
        # java version을 다운받고 setting 및 다른 부가 기능을 한다
        # link : <https://github.com/actions/setup-java>
      - name: Set up JDK 11
        uses: actions/setup-java@v3
        with:
          distribution: 'adopt' #OpenJDK HotSpot을 사용한다
          java-version: '11'

        # gradlew를 실행시키기 위해 권한 설정
      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

        # 요건 github action이 제공하는 스크립트 가져왔다
        # 기존 build한 파일이 존재한다면 캐싱하여 build 속도를 높일 수 있다~
      - name: cache
        uses: actions/cache@v2
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-

      - name: Build with Gradle
        run: ./gradlew build

        # docker container builder driver를 사용하여 builder를 만들고 부팅
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

        # docker hub 대한 로그인 처리
      - name: Login to DockerHub
        uses: docker/login-action@v1 
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

        # docker image생성하고 DockerHub에 push 한다
      - name: Build and push to DockerHub
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./Dockerfile
          platforms: linux/amd64
          push: true
          tags: ${{ secrets.DOCKER_TAG }}

 

${{ }}

  • 암호화한 정보들을 의미한다
  • github의 repository setting에서 생성할 수 있다

 

GitHub Actions을 이용한 CD 구축

deploy:
  needs: build
  name: Deploy
  runs-on: [ self-hosted, label-development ]
  steps:
    - name: Docker run
      run: |
          sudo docker stop yapp && docker rm yapp && docker rmi ${{ secrets.DOCKER_TAG }}
          sudo docker run -d -p 8080:8080 -e TOGATHER_JASYPT_PASSWORD=${{ secrets.TOGATHER_JASYPT_PASSWORD }} --name yapp ${{ secrets.DOCKER_TAG }}

 

GitHub Actions이 제공하는 Runner 사용

  • repository setting에서 좌측 Actions → Runners → New self-hosted runner를 생성

  • 생성 버튼을 누르면 위와 같은 script의 문장을 하나하나 EC2에 복붙한다
    • echo ~ 부분은 제대로 작동되지 않는데 아마 큰 문제가 없는 듯하다(이거 안됐는데 CI/CD 성공함)
  • 이때 download가 완료한 시점에 뭘 많이(2~3개?) 물어본다(이 때는 성공하려고 캡처 못함,,)
    • 다른 건 enter를 쳐서 넘어갔는데 label~~ 뭐시기 얘기한 게 나온다
    • 이 부분에서 우리가 script를 작성했을 때 사용했던 label을 입력해줘야한다
    • runs on : “label-development”
  • ./run.sh를 입력할 때 백그라운드에서 실행하기 위해 “nohub ./run.sh &”를 사용하자~

 

결과

  • 위와 같은 사진처럼 Idle가 되면 잘 실행됨을 의미한다

 

오류

  • GitHub Actions을 실행할 때 build는 제대로 작동됐는데 계속해서 deploy에서 잘못됐다
  • 나는 label도 잘 입력하고, docker run 명령어도 잘 입력했는데 도대체 뭐가 문제일까라는 생각을 했다

 

해결

  • 당연히 문제는 나에게 있었다 docker run 명령어가 제대로 작동하지 않았다
    • 이 글을 보신 분들은 꼭 Action 실행시키기 전에 EC2에서 직접 docker 명령어가 실행되는지 확인하시길 바랍니다,,
  • 과정을 설명하면 container 중지 → container 삭제 → image 삭제 → docker run
  • 여기서 image를 삭제했는데 docker run이 당연히 작동하지 않나요!!? 라는 생각을 할 수 있다
  • 하지만 DockerHub에 저장된 image를 실행시키는데 만약 image가 없다면 Docker가 DockerHub에 있는 image를 pull해준다(이 부분은 로그 보면서 알 수 있었음)

 


REFERENCES

GitHub Actions - checkout

jasypt 사용

 

 

 

728x90
profile

자바생

@자바생

틀린 부분이 있다면 댓글 부탁드립니다~😀

검색 태그