๐ฑ CI/CD Workflow
CICD.yml
name: CI/CD
on:
pull_request:
branches: ["main"]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Build with Gradle
run: |
chmod +x ./gradlew
./gradlew clean build -x test
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build Docker Image
run: docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/ssak:v1 .
- name: Push Docker Image
run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/ssak:v1
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Deploy to Server
uses: appleboy/ssh-action@master
with:
username: ubuntu
host: ${{ secrets.SSAKTIUM_SERVER_IP }}
key: ${{ secrets.EC2_SSH_KEY }}
script_stop: true
script: |
# Pull the latest image from DockerHub
sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/ssak:v1
# Stop and remove the existing container if it exists
if [ "$(sudo docker ps -q -f name=daegyuhan-ssak)" ]; then
sudo docker stop daegyuhan-ssak
fi
if [ "$(sudo docker ps -aq -f status=exited -f name=daegyuhan-ssak)" ]; then
sudo docker rm daegyuhan-ssak
fi
# Run the new container
sudo docker run -d --name daegyuhan-ssak -p 8080:8080 ${{ secrets.DOCKERHUB_USERNAME }}/ssak:v1
on:
pull_request:
branches: ["main"]
๐ main ๋ธ๋์น์ pull request ๊ฐ ์ผ์ด๋ ๋๋ง ์คํ
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
๐ ubuntu ์ต์ ๋ฒ์ ์์ ์คํ์ํค๊ณ , JDK 17 ๋ฒ์ ์ผ๋ก ์คํํ๊ฒ ๋ค๋ ๋ง์ด๋ค.
์ฌ๋งํ๋ฉด ๋ฒ์ ์ ๋ณธ์ธ์ ํ๋ก์ ํธ ์คํ ํ๊ฒฝ๊ณผ ๋์ผํ๊ฒ ๊ฐ์ฃผ๋ ๊ฒ ์ข๋ค.
- name: Build with Gradle
run: |
chmod +x ./gradlew
./gradlew clean build -x test
๐ Gradle ํ๊ฒฝ์ด๊ธฐ ๋๋ฌธ์ ๋๊ฐ์ด ๋ง์ถฐ์คฌ๋ค.
clean ์ ํ ๋ฒ ํ๊ณ build ๋ฅผ ํด์ ์น ๊ฐ์์ฃผ๊ณ , -x test ์ต์ ์ ์จ์ ์ฐ์ test ๋ฅผ ๋๋ฆฌ๋ ๊ณผ์ ์ ์๋ตํ๋ค.
: ํ๋ก์ ํธ ์งํ ์๋๋ฅผ ์ํด์ ์ฐ์ ์ด๋ ๊ฒ ์งํ
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build Docker Image
run: docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/ssak:v1 .
- name: Push Docker Image
run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/ssak:v1
๐ ๋ด ํ๋ก์ ํธ์ jar ํ์ผ์ Docker ์ด๋ฏธ์ง๋ก ๋ง๋ค์ด์ Docker Hub ์ ์ฌ๋ ค๋๊ธฐ ์ํ ์ฝ๋์ด๋ค.
Docker Hub ์ ๋ก๊ทธ์ธ์ ํ๋ค์์ ๊ธฐ์กด์ ์์ฑ๋์ด์๋ Repository ์ ๋ฑ๋ก๋์ด์๋ ์ด๋ฏธ์ง์ ๋ฒ์ ์ ๋ง์ถฐ์ Build, Push ๋ฅผ ์งํํ๋ค.
DOCKERHUB_TOKEN ์ Docker Hub ์ ์ ์ํด์ ๋ฐ์ ์ ์๋ค.
Dockerfile
FROM amazoncorretto:17-alpine-jdk
EXPOSE 8080
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Deploy to Server
uses: appleboy/ssh-action@master
with:
username: ubuntu
host: ${{ secrets.SSAKTIUM_SERVER_IP }}
key: ${{ secrets.EC2_SSH_KEY }}
script_stop: true
๐ deploy ๊ณผ์ ์ด๋ค. ๋๊ฐ์ด ํ๊ฒฝ์ ubuntu ์ต์ ๋ฒ์ ์ผ๋ก ํด์คฌ๊ณ , ๋ด ์ธ์คํด์ค์ ์๋ฒ IP ์ SSH_KEY ๋ฅผ ์ ๋ ฅํจ์ผ๋ก์จ, ๋ด ์ธ์คํด์ค SSH ์ ์ ์์ ์์ผฐ๋ค.
script: |
# Pull the latest image from DockerHub
sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/ssak:v1
# Stop and remove the existing container if it exists
if [ "$(sudo docker ps -q -f name=daegyuhan-ssak)" ]; then
sudo docker stop daegyuhan-ssak
fi
if [ "$(sudo docker ps -aq -f status=exited -f name=daegyuhan-ssak)" ]; then
sudo docker rm daegyuhan-ssak
fi
# Run the new container
sudo docker run -d --name daegyuhan-ssak -p 8080:8080 ${{ secrets.DOCKERHUB_USERNAME }}/ssak:v1
๐ ๋งจ ์์์ build ๋จ๊ณ์์ push ํ๋ ๋ด Docker Hub ์ ์ด๋ฏธ์ง๋ฅผ Pull ๋ก ๋น๊ฒจ์จ๋ค.
๐ ๊ธฐ์กด์ ์คํ๋๊ณ ์๋ ์ปจํ ์ด๋๋ฅผ stop ํ๊ณ , remove ํ๋ค.
๐ Pull ๋ก ๋น๊ฒจ์จ ์ ์ด๋ฏธ์ง๋ฅผ 8080 ํฌํธ๋ก ์๋ก ์คํ์ํจ๋ค.
์์์ ํ๊ฒฝ๋ณ์ ์ค์ ์ github ํ์ด์ง์ Secrets and variables ํญ์ Actions ํญ์ ๋ค์ด๊ฐ๋ณด๋ฉด
์ด๋ ๊ฒ ์ถ๊ฐ๋ฅผ ํด์ค ์ ์๋ค.