
프로젝트 자체 빌드와 Docker를 사용하여 프로젝트를 배포하는 프로세스 방식을 진행했었다.
아직 CI/CD 배포 프로세스를 제대로 하지 못해 다음 번에 이 블로그를 통해서 계속 복습을 하려고 한다.
자동화 배포 프로세스까지 완료하는 것까지 블로그를 작성할 것이다.
다시 한번
💧 CI : 지속적 통합. 여러 개발자들이 협업을 하고 있는 경우 발생하는 불일치를 최소화 해주는 개념. 브랜치에 PR 요청이 오면 빌드, 테스트하여 코드의 수준을 체크 가능.
💧 CD : 지속적 배포. 프로젝트의 변경사항을 가상 환경 (AWS, IDC)에 배포하는 것.
즉 배포의 자동화가 이루어지는 환경.
💧 Github Actions : github에서 공식적으로 제공하는 개발워크플로우 자동화 툴.
Github Repository와 위에서 소개한 서드파티 CI/CD툴의 연동을 통해서 진행했던 CI 작업을 일원화된 개발 환경에서 진행할 수 있게 됨.
Jar 빌드 -> Docker Image 생성 -> Docker Hub.
Gitgub Action에서는 Push, PR을 했을 때 미리 지정해둔 work flow가 실행된다.
원하는 브랜치를 설정해서 Push, PR을 할 시 JAR 빌드, Docker 이미지 빌드, Docker Hub Push까지 진행할 것이다.
Test를 수행해서 코드 품질도 체크할 수 있다고 하지만 보통 프로젝트에서 DB와 연결을 통해 Test를 수행하지만 보통 DB는 프로젝트 외부에서 프로젝트와 연결되어 있기 때문에 동작하지 않는 경우가 많다.
그래서 이전에 실습 때 DB가 로컬에 있어 컨테이너에 접근이 불가능했던 것.
작업한 프로젝트 GitHub Repository -> Actions -> Java with Gradle -> Configure 선택.

그러면 이러저러한 코드가 나옴.
Github Action은 event, job, step을 정의하기 위해 YAML 파일을 사용한다. workflow를 구성할 레포지토리에 .github/workflows 디렉토리 안에 test-github-actions.yml 형태로 파일을 생성한다. 
# 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" ]
  pull_request:
    branches: [ "main" ]
jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
    - uses: actions/checkout@v4
    - name: Set up JDK 17
      uses: actions/setup-java@v4
      with:
        java-version: '17'
        distribution: 'temurin'
    ~~~~
이 파일을 생성하고 수정해야 함. 일단 위 코드는 어떤 Push, PR 등 이벤트가 발생했을 때, 어떤 작업을 수행할 것인지를 명시하는 파일.
주석 전부 삭제하고 수정.
name: Java CI with Gradle
# master 브랜치에 push, PR 이벤트 발생시 동작.
on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      # Java 및 Docker 빌드를 위한 환경 설정
      - uses: actions/checkout@v3
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'
      # Java 빌드를 위한 ./gradlew 파일 권한 변경
      - name: Run chmod to make gradlew executable
        run: chmod +x ./gradlew
      # Java 빌드
      - name: Spring Boot Build
        run: ./gradlew clean build
      # DockerFile 을 기반으로 Docker Image 빌드
      - name: docker image build
        run: docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/github-actions-demo .
      # Docker Hub 에 Login
      - name: docker login
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_PW }}
      # Docker Hub 에 빌드된 이미지 push
      - name: docker Hub push
        run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/github-actions-demo허나 Github Action 스크립트는 구동되지 않음. 아직 값들이 채워지지 않았기 때문에.
gradle.yml 파일의 Steps Flow
(1) JAva Build가 일어날 환경을 설정. -> Java 버전을 맞추는 행위.
(2) Java Build를 위해 ./gradlew 파일의 설정 권한을 변경.
(3) Spring 프로젝트에 있는 .java 파일들을 JAR 파일로 빌드하는 것.
(4) 프로젝트에 있는 JAR 파일과 Docker File을 통해 Docker Build를 진행. -> Docker Image를 생성.
(5) Docker Registory에 Docker Image를 Push하기 위해 Docker Hub에 로그인하는 과정.
(6) 로그인 한 Docker Registory에 Docker Image를 Push하는 과정.
이전 실습에서 했던 것처럼 Docker File 생성.
FROM amazoncorretto:17-alpine
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]각각에 대한 내용은 노션에 정리했음.
꼭 확인해야 하는 점.
🏷️ 위의 Steps의 Flow를 확인할 때 Docker Login을 진행하는 과정에서 with 부분을 보면 Docker hub의 username, password 가 존재하는데, 이는 GitHub Actions의 Secret Key를 설정해줘야 한다. 해당 항목이 존재하지 않는다면, Actions = Fail 상태가 될것이다.
🏷️ 이처럼 외부에 공개되면 안되는 ID/Password(추후 AWS 계정 관련된 내용)은 Secret key로 생성하여 외부에 노출되지 않게 해야 한다.
해당 프로젝트 Settings -> Secrets and Variable -> 왼쪽에 Actions -> Repository secrets
New Repository secret 클릭하고 이름과 내용 작성 및 저장하면 이제 생성한 List가 생성되고 gradle.yml에서 사용할 수 있게 된다.
username과 password만 설정하고 username의 경우 Docker에 로그인하여 My Profile을 클릭하면 나오는 이름이다.
password의 경우 Docker에 로그인할 때 사용하는 패스워드를 등록하면 된다.
이렇게 하면 Github Actions를 사용하기 위한 설정은 끝났다. 실제 "on: " 부분에 설정한 이벤트를 동작시켜서 Github Actions가 동작하는지 보면 된다.
해당 flow 상세페이지에 들어가서, 어떤부분에서 실패했는지 확인 할 수 있고, 해당 flow를 재시작 할 수도 있다.
실패했을 경우 name 부분에 설정한 step마다 성공했는지 실패했는지 알수 있기 때문에 어느 부분에서 잘못되었는지 확인하자.
따라서 name을 설정하고 step을 나누는 것은 매우 중요한 과정이라고 할 수 있다.
동작이 성공했을 경우 설정한 모든 것을 끝냈다고 할 수 있으니 이제 Docker Image가 생성되어 Docker Hub에 Push 되었다고 할 수 있다.
한번 더 주의 : 비밀번호, 민감한 값들이 Github Action 스크립트에 그대로 입력되어있으면 아무나 읽고 탈취 가능!!!
먼저 Docker Hub 회원가입 후 My Profile 에서 Security 에 Access Token 을 생성.
Docker Registry(도커 이미지 저장소) 로 Docker Hub 로컬 스토리지를 사용할것이기 때문에 Docker Hub 에 왜 회원가입 필요.

그 다음 Docker Hub 회원가입 및 발행한 Access Token 을 Github 프로젝트 설정에 주입.
Github 프로젝트에서 Settings → Security → Secrets and Variable → Actions
노션 순서대로 ~~~ 진행.
이름 및 태그는 맘대로, 인스턴스 유형 또한 간단한 구동 확인을 위함이니 프리티어, 키 페어는 Local 터미널에서 ssh로 접근하려면 설정하면 되지만 EC2 인스턴스 연결을 통해서 할 것이면 설정 X. 이유??
EC2 인스턴스 연결을 위해 Public IP 설정의 경우 활성화로.
보안 그룹은 기존 22번 포트 외에 "8080 포트의 모든 IP" 인바운드 규칙을 추가.
연결한 사진.
EC2 내 인스턴스에 있는 모든 패키지 업데이트 함. 
sudo yum update -y를 통해 패키지 업데이트를 진행.
EC2 인스턴스 내 Docker Engine 설치 후 구동해야 함. 
sudo yum install docker -y 명령어로 EC2 내 Docekr Engine을 설치.
sudo sevice docker start 명령어로 EC2 내 Docerk Engine을 구종.
Docker Hub 내 Image Pull 후 확인. 
docker pull ~~/github-actions-demo 명령어를 통해 Docker Hub에 있는 Docker Iamge를 다운로드.
docker images로 pull이 성공적으로 진행되었는지 확인.
알아서 사진.
EC2 내에서 Docker Run을 통한 Docker Container 구동 및 서버 확인 
docker run -p 8080:8080 ~~/github-actions-demo 로 Docker Image를 구동시켜 Docekr Container를 구동.
docker run할 때 -d 옵션을 추가하면 EC2 연결이 끊어져도 EC2가 자동으로 서버를 구동시킬 수 있다. 그리고 spring 서버가 구동되면서도 다른 커맨드를 입력하게 daemon으로 돌아가게 한다고 한다.
docker 컨테이너 정상 동작 및 크롬과 같은 웹 브라우저로 {EC2의 퍼블릭IP}:8080 로 접속해보면 실제로 서버가 구동 중인 것을 확인할 수 있다.
여기까지가 CI 프로세스다.
CD 자동화를 한번 다음 포스팅에서 정리해보자.
AWS 어렵지만 배포 관련해서 알아두면 이점이 크겠지!!!
🔗 Docker 개념, 역할
🔗 Docker 기본
🔗 https://zzsza.github.io/development/2020/06/06/github-action/ - Github Action 사용법
🔗 https://lucas-owner.tistory.com/48
🔗 https://lucas-owner.tistory.com/49