SpringBoot - Docker와 Github Actions로 CI/CD 환경 구성하기

J_log·2024년 12월 31일
0

스프링부트 프로젝트를 도커와 깃허브 액션을 통해 CI/CD를 구성했던 과정을 간단히 기록해보려고 한다.
먼저 사전에 준비물이 필요하다.

  • EC2 인스턴스
  • RDS
  • Docker 설치, 계정 및 DockerHub에 레포지토리 만들기

위에 언급된 내용들이 준비된 상태에서 진행하면 된다.

도커 파일 작성

먼저 스프링부트 프로젝트 루트 디렉토리에 도커 파일을 생성하고 스크립트를 작성한다.

docker build . --file Dockerfile --tag 도커허브ID/프로젝트이름:태그
docker build . --file Dockerfile --tag jhpark0131/coboard:latest

터미널에서 위 명령어를 실행해서 도커 이미지가 제대로 생성되는지 확인해본다.
or 도커 파일에 FROM 옆에 보이는 실행 버튼을 눌러서 테스트 해볼 수도 있다.

정상적으로 빌드가 되었다면 도커 데스크탑에서 Image가 생성된 모습을 확인할 수 있다.

도커 AccessToken

EC2에서 Docker Hub에 접속하거나 Github Actions에서 Docker 이미지를 빌드한 후 Docker Hub에 push하거나, pull 받을 때 AccessToken이 필요하다.

계정 설정의 Personal access tokens를 생성하고 복사해서 잘 보관해주자.

Github Actions에 환경 변수 등록

이제 깃허브 액션을 적용할 레포지토리 설정으로 이동해서 환경 변수를 등록해 줘야한다.

Secretes and variables -> Actions를 확인해보면

사진에 보이는 것과 같이 Secrets와 Variables 설정할 수 있다. DB와 EC2관련 환경변수는 secrets로 설정했고 variables로 도커 유저 이름과 도커 이미지 이름을 설정해 두었지만 모두 secrets로 설정해도 무방하다.

  • DOCKERHUB_TOKEN : 도커 AccessToken
  • EC2_KEY : EC2에 접속할 때 사용하는 ssh key (id_rsa)의 내용을 복사해서 채워준다.
  • EC2_USER : EC2에 접속할 때 사용하는 유저 이름을 채워주면 된다. ex) ubuntu
  • EC2_HOST : EC2인스턴스의 퍼블릭 주소를 입력해준다.
    • 퍼블릭 IPv4 주소와 퍼블릭 IPv4 DNS 모두 외부에서 접근할 수 있게 해주므로, 어느 것을 사용해도 괜찮지만, 퍼블릭 IPv4 DNS를 사용하는 것이 일반적으로 더 안전하고, IP주소가 변경될 때 DNS 이름을 그대로 사용할 수 있다는 장점이 있다.
  • DB_HOST : RDS 퍼블릭 엔드포인트
  • DB_USER : RDS 유저 이름
  • DB_PASSWORD : RDS 패스워드

Github Actions 스크립트(yml) 작성

프로젝트 루트 디렉토리에서 .github -> workflows 패키지를 생성하고 안에다 yml 파일을 작성해준다. yml파일 이름은 아무렇게나 지어도 무방하지만 어떤 기능을 할 것인지 명확하게 해주는 쪽이 좋아보인다.

name: build to github

on:
  push:
    branches: [main, develop] # 해당 branch에 push 되었을 경우

jobs:
  github-build-and-push:
    runs-on: ubuntu-22.04

    # 실행 스텝 지정
    # https://github.com/marketplace/actions/build-with-gradle
    steps:
      - name: Checkout sources
        uses: actions/checkout@v4

      # java version 지정
      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4

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


      # https://github.com/marketplace/actions/build-and-push-docker-images
      # 로그인
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ vars.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      # 관련 설적 적용
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      # Build 및 Push
      - name: Build and push
        uses: docker/build-push-action@v6
        with:
          context: . # 지정하지 않으면 기본적으로 현재 디렉토리가 빌드 컨텍스트로 사용됩니다.
          file: ./Dockerfile
          push: true
          tags: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest

  deploy-to-ec2:
    needs: github-build-and-push
    runs-on: ubuntu-22.04
    # https://github.com/marketplace/actions/ssh-remote-commands
    steps:
      - name: Deploy to EC2
        uses: appleboy/ssh-action@v1.2.0
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ${{ secrets.EC2_USER }}
          key: ${{ secrets.EC2_KEY }}
          script: |
            CONTAINER_ID=$(sudo docker ps -q --filter "publish=8080-8080")

            if [ ! -z "$CONTAINER_ID" ]; then
              sudo docker stop $CONTAINER_ID
              sudo docker rm $CONTAINER_ID
            fi

            sudo docker pull ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest
            sudo docker run -d -p 8080:8080 \
                -e DB_USER=${{secrets.DB_USER}} \
                -e DB_PASSWORD=${{secrets.DB_PASSWORD}} \
                -e DB_HOST=${{secrets.DB_HOST}} \
                ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest

yml파일의 내용을 살펴보면 main, develop 브랜치에 push를 하고 병합이 이뤄지게 되면
jobs에 있는 'github-build-and-push' 그리고 'deploy-to-ec2'가 순차적으로 실행되게 된다. 방금 위에서 설정해준 환경 변수들이 yml 파일에서 쓰이는 모습을 확인할 수 있다.

결과 확인

이제 개발한 내용을 commit -> push 하고 main or develop 브랜치에서 merge하게 되면 Github Actions가 동작하게 된다.

레포지토리에서 Actions 탭을 눌러보면 진행 상황을 확인할 수 있고

워크플로우를 눌러 안으로 들어가게 되면 상세한 로그들을 확인할 수 있다.

0개의 댓글