스프링부트 프로젝트를 도커와 깃허브 액션을 통해 CI/CD를 구성했던 과정을 간단히 기록해보려고 한다.
먼저 사전에 준비물이 필요하다.
위에 언급된 내용들이 준비된 상태에서 진행하면 된다.
먼저 스프링부트 프로젝트 루트 디렉토리에 도커 파일을 생성하고 스크립트를 작성한다.
docker build . --file Dockerfile --tag 도커허브ID/프로젝트이름:태그
docker build . --file Dockerfile --tag jhpark0131/coboard:latest
터미널에서 위 명령어를 실행해서 도커 이미지가 제대로 생성되는지 확인해본다.
or 도커 파일에 FROM 옆에 보이는 실행 버튼을 눌러서 테스트 해볼 수도 있다.
정상적으로 빌드가 되었다면 도커 데스크탑에서 Image가 생성된 모습을 확인할 수 있다.
EC2에서 Docker Hub에 접속하거나 Github Actions에서 Docker 이미지를 빌드한 후 Docker Hub에 push하거나, pull 받을 때 AccessToken이 필요하다.
계정 설정의 Personal access tokens를 생성하고 복사해서 잘 보관해주자.
이제 깃허브 액션을 적용할 레포지토리 설정으로 이동해서 환경 변수를 등록해 줘야한다.
Secretes and variables -> Actions를 확인해보면
사진에 보이는 것과 같이 Secrets와 Variables 설정할 수 있다. DB와 EC2관련 환경변수는 secrets로 설정했고 variables로 도커 유저 이름과 도커 이미지 이름을 설정해 두었지만 모두 secrets로 설정해도 무방하다.
프로젝트 루트 디렉토리에서 .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 탭을 눌러보면 진행 상황을 확인할 수 있고
워크플로우를 눌러 안으로 들어가게 되면 상세한 로그들을 확인할 수 있다.