GitHub Actions는 GitHub가 제공하는 CI/CD 도구로 소프트웨어 개발 워크플로우를 자동화할 수 있도록 도와준다.
name: Docker Image CI # workflow 이름을 지어준다.
on:
push:
branches:
- "main" # main 브랜치에 push 될 때 해당 workflow를 실행한다.
jobs: # job을 수행한다.
build: # 프로젝트를 빌드(CI)
runs-on: ubuntu-latest # build 할 가상환경을 지정해 준다. 이후의 작업은 이때 설정한 가상환경에서 수행된다.
steps:
- name: Checkout # checkout 액션을 통해 가상환경에서 레포지토리를 다운받은 폴더로 이동
uses: actions/checkout@v4.2.1
with:
ref: ${{ github.ref }}
- name: Set up JDK 17 # java 17 버전을 설치한다.
uses: actions/setup-java@v4.4.0
with:
java-version: '17'
distribution: 'temurin'
- name: Grant permission for gradlew # gradlew 파일에 실행 권한을 부여하여 다음 단계에서 gradlew가 빌드 명령을 수행할 수 있도록 한다.
run: chmod +x ./gradlew
- name: Build with Gradle # 프로젝트를 clean 상태로 정리한 후, test를 생략하고 빌드를 수행.
run: ./gradlew clean build -x test
- name: Docker build and publish # docker 이미지를 생성하고 docker hub에 이미지를 업로드한다.
run: |
echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
docker build -t ${{ secrets.DOCKER_USERNAME }}/${{ vars.APP_NAME }}:${{ github.ref_name }} .
docker push ${{ secrets.DOCKER_USERNAME }}/${{ vars.APP_NAME }}:${{ github.ref_name }}
위 작업이 수행되면 docker hub에 내가 빌드한 프로젝트의 docker image가 올라간 것을 확인할 수 있다.
deploy: # build 된 docker 이미지를 서버에서 배포(CD)
needs: build # build가 정상적으로 수행된 경우에만 배포가 되도록 한다.
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: My Server Login and Docker Image pull and run # 내 서버에 접속해서 docker 이미지를 pull 하고 이를 run 하여 프로젝트 container를 생성/실행한다.
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USERNAME }}
password: ${{ secrets.SERVER_PASSWORD }}
port: ${{ secrets.SERVER_PORT }}
script: |
echo ${{ secrets.SERVER_PASSWORD }} | sudo -S docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
echo ${{ secrets.SERVER_PASSWORD }} | sudo -S docker stop ${{ vars.APP_NAME }}
echo ${{ secrets.SERVER_PASSWORD }} | sudo -S docker rm -f ${{ vars.APP_NAME }}
echo ${{ secrets.SERVER_PASSWORD }} | sudo -S docker network create ${{ vars.APP_NAME }}_net || true # 네트워크 생성
echo ${{ secrets.SERVER_PASSWORD }} | sudo -S docker pull ${{ secrets.DOCKER_USERNAME }}/${{ vars.APP_NAME }}:main
echo ${{ secrets.SERVER_PASSWORD }} | sudo -S docker run -d --name ${{ vars.APP_NAME }} --network ${{ vars.APP_NAME }}_net -p ${{ secrets.SERVER_PORT }}:8080 ${{ secrets.DOCKER_USERNAME }}/${{ vars.APP_NAME }}:main # 네트워크 설정
echo ${{ secrets.SERVER_PASSWORD }} | sudo -S docker image prune -f
내 서버에서 docker ps 명령어로 작업 중인 프로세스를 확인하면 내 프로젝트 docker container가 생성/실행되는 것을 확인할 수 있다.
이 과정에서 서버 정보와 같이 민감한 정보들은 github repository > settings > Secrets and variables > actions에서 저장할 수 있다.