๐ GitHub Actions?
GitHub Actions๋ GitHub์์ ์ ๊ณตํ๋ CI/CD(Continuous Integration/Continuous Deployment) ํ๋ซํผ์ด๋ค. ์ด๋ฅผ ํตํด ๊ฐ๋ฐ์๋ ์ฝ๋๋ฅผ ๋น๋, ํ ์คํธ, ๋ฐฐํฌํ๋ ์๋ํ๋ ์ํฌํ๋ก์ฐ๋ฅผ ์ค์ ํ ์ ์๋ค. GitHub Actions๋ ๋ค์ํ ์ด๋ฒคํธ(์: ์ฝ๋ ํธ์, ํ ๋ฆฌํ์คํธ ์์ฑ ๋ฑ)์ ๋ฐ์ํ์ฌ ์์ ์ ์ํํ ์ ์๋ค.
์ฌ์ด๋ ํ๋ก์ ํธ๋ฅผ ์ ์ํ๋๋ฐ ์ ํจ์ค(Jenkins)๊น์ง๋ ๋ถ๋ด์ค๋ฝ๊ณ , ๊ฐ๋ณ๊ณ ์ฌ์ด ๋ฐฐํฌ ๋ฐฉ์์ ์ ํํ๊ณ ๊ณ ๋ฏผํ๋ค๋ฉด GitHub Actions๋ ๊ด์ฐฎ์ ๋์์ด ๋ ์ ์๋ค๊ณ ์๊ฐํ๋ค.
1. ์ค๋น
ํด๋น ํฌ์คํธ๋ GitHub Actions๋ฅผ ํ์ฉํด์ ํด๋ผ์ฐ๋ VM ์๋ฒ์ ์คํ๋ง ๋ถํธ ์ ํ๋ฆฌ์ผ์ด์ jar ํ์ผ์ ๋ฐฐํฌํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ค๋ช ํ๋ค.
์ค๋น๋ ํ๊ฒฝ์ ์๋์ ๊ฐ๋ค.
- JDK 17
- Spring Boot 3
- Gradle
- Github Actions
- GCP VM ์ธ์คํด์ค (Ubuntu 22 LTS)
- Github Private Repository
ํด๋น ํฌ์คํธ๋ Docker ๋ฐฉ์์ด ์๋ ๊ฐ๋จํ๊ฒ ์คํ๋ง ๋ถํธ jar ํ์ผ์ ์คํ์ํค๋ ๋ฐฐํฌ ๋ฐฉ์์ ๋ค๋ฃฌ๋ค.
Docker ๋ฐฉ์์ผ๋ก ๋ฐฐํฌํ๋ ๊ฑธ ์ํ๋ค๋ฉด ๋ค๋ฅธ ํฌ์คํธ๋ฅผ ์ฐพ์์ผ ํ๋ค.
2. Private Repository ์์ฑ
Spring Boot 3, Gradle, Jdk 17 ํ๊ฒฝ์ผ๋ก ์๋ก์ด Git Repository๋ฅผ Private์ผ๋ก ์์ฑํ๋ค.
3. Secrets ์ค์ ํ๊ธฐ
๋ฐฐํฌ์ฉ yml ํ์ผ ์์ฑ ์ ์ Secret ๊ฐ์ ์ค์ ํด์ผ ํ๋ค.
1) Settings - Security-Sercrets and variables - Actions ํญ ๋ค์ด๊ฐ๊ธฐ
2) Secret ๊ฐ ๋ฑ๋กํ๊ธฐ
์ด 4๊ฐ์ Secret์ ๋ฑ๋กํด์ผ ํ๋ฉฐ ๊ฐ Secret์ ๋ค์ ๊ฐ๋ค์ ์๋ฏธํ๋ค.
GCP_SSH_PRIVATE_KEY : SSH private key
GCP_SSH_USER : SSH๋ก ์ ๊ทผํ ์ ์๋ ๊ณ์
GCP_VM_IP : GCP VM ์ธ์คํด์ค์ IP ์ฃผ์
JAR_NAME : ํ๋ก์ ํธ ๋น๋ํ๋ฉด ๋์ค๋ jar ํ์ผ์ ์ด๋ฆ
๊ฐ Secret์ GCP ํ๊ฒฝ์์ ํ๋ํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์ค๋ช ํ๋ค.
1. GCP_SSH_PRIVATE_KEY
Github Actions์์ SSH๋ฅผ ํตํด ํด๋น ์๋ฒ๋ก ์ ๊ทผํ๊ธฐ ์ํด PRIVATE ๊ฐ์ ํ์๋ก ํ๋ค.
ํด๋น ๊ฐ์ VM ์๋ฒ์์ ssh-keygen ๋ช ๋ น์ด๋ฅผ ์ํํ๋ฉด ํ๋ํ ์ ์๋ค.
ssh-keygen -t ed25519 -f ~/.ssh/id-rsa -C [์ฌ์ฉ์ ๊ณ์ ID]
[์ฌ์ฉ์ ๊ณ์ ID] ์๋ VM ์๋ฒ์ ๋ฐฐํฌํ๋ ์ฌ์ฉ์ ๊ณ์ ์ ID๋ฅผ ์ถ๊ฐํ๋ฉด ๋๋ค.
๋ฐฐํฌ์ฉ ์ฌ์ฉ์๊ฐ ๋ฐ๋ก ์กด์ฌํ๋ค๋ฉด ํด๋น ID๋ฅผ ์ถ๊ฐํ๊ณ , ๋ฐ๋ก ์๋ค๋ฉด SSH ์ ์ ๊ฐ๋ฅํ ๋ค๋ฅธ ๊ณ์ ์ ์ถ๊ฐํ๋ค.
์ดํ ~/.ssh ์์น๋ก ์ด๋ํด์ ํ์ผ ๋ชฉ๋ก์ ์ฐพ์๋ณด๋ฉด authorized_keys, id-rsa, id-rsa.pub 3๊ฐ์ ํ์ผ๋ค์ ํ์ธํ ์ ์๋ค. ๊ทธ์ค id-rsa ํ์ผ ๋ด์ฉ ์ ์ฒด(-----BEGIN OPENSSH ๋ถํฐ PRIVATE KEY ----- ๊น์ง)๋ฅผ ๋ณต์ฌํด์ GCP_SSH_PRIVATE_KEY๋ก ๋ฑ๋กํ๋ฉด ๋๋ค.
๊ทธ๋ฆฌ๊ณ id-rsa.pub ํ์ผ ๋ด์ฉ ์ ์ฒด๋ฅผ ๋ณต์ฌํด์ authorized_keys ํ์ผ์ ๋ถ์ฌ ๋ฃ๊ธฐ ํ๋ค.
2. GCP_SSH_USER
GCP_SSH_PRIVATE_KEY ์์ฑํ ๋ [์ฌ์ฉ์ ๊ณ์ ID]๋ก ์ ๋ ฅํ ๊ณ์ ์ ๋ฑ๋กํ๋ฉด ๋๋ค.
3. GCP_VM_IP
GCP VM ์ธ์คํด์ค์ ์ ์ ๊ฐ๋ฅํ ์ธ๋ถ IP๋ฅผ ๋ฑ๋กํ๋ฉด ๋๋ค.
4. JAR_NAME
์คํ๋ง ๋ถํธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋น๋ํ๋ฉด ๋์ค๋ ์ด๋ฆ jar ํ์ผ์ ์ด๋ฆ์ ์ ์ผ๋ฉด ๋๋ค.
ํ๋ก์ ํธ์ ์๋ฌด ๊ฒ๋ ์ค์ ํ์ง ์์๋ค๋ฉด ๋น๋ ํ์ build/libs์ ์๋ jar ํ์ผ ์ด๋ฆ์ ์ ๋๋ค.
4. CI ๊ตฌ์ถ
์์ฑํ ์๋ฐ ํ๋ก์ ํธ๋ฅผ jar ํ์ผ๋ก ๋น๋ํ๋ ์์ ์ ์๋ํํ ๊ฒ์ด๋ค.
1) Actions - Java with Gradle์ Configure๋ฅผ ์ ํํ๋ค.
2) Deploy.yml์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ๋ค.
name: Java CI with Gradle
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
# ๊ธฐ๋ณธ ์ฒดํฌ์์
- name: Checkout
uses: actions/checkout@v4
# Gradlew ์คํ ํ์ฉ
- name: Run chmod to make gradlew executable
run: chmod +x ./gradlew
# JDK 17 ์ธํ
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
# Gradle ์ค์
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
# Gradle ๋น๋
- name: Build with Gradle
run: ./gradlew build
# ๋ฐฐํฌ ํจํค์ง ์ค๋น
- name: Prepare deployment package
run: |
mkdir -p deploy
cp build/libs/${{ secrets.JAR_NAME }}.jar deploy/
# SSH ํค ์ค๋น
- name: Add SSH key
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.GCP_SSH_PRIVATE_KEY }}
# GCP VM์ ๋ฐฐํฌ
- name: Deploy to GCP VM
run: |
ssh -o StrictHostKeyChecking=no ${{ secrets.GCP_SSH_USER }}@${{ secrets.GCP_VM_IP }} 'sudo service shiba stop'
scp -o StrictHostKeyChecking=no deploy/${{ secrets.JAR_NAME }}.jar ${{ secrets.GCP_SSH_USER }}@${{ secrets.GCP_VM_IP }}:/home/${{ secrets.GCP_SSH_USER }}/app/
ssh -o StrictHostKeyChecking=no ${{ secrets.GCP_SSH_USER }}@${{ secrets.GCP_VM_IP }} 'sudo service shiba start'
ํด๋น ์ํฌํ๋ก์ฐ๋ ๋ค์๊ณผ ๊ฐ์ ๋จ๊ณ๋ฅผ ์ํํ๋ค.
1. ์ฝ๋ ์ฒดํฌ์์ - actions/checkout@v4 ์ก์ ์ ์ฌ์ฉํ์ฌ ์ ์ฅ์์ ์ฝ๋๋ฅผ ์ฒดํฌ์์ํ๋ค.
2. JDK 17 ์ค์ - actions/setup-java@v4 ์ก์ ์ ์ฌ์ฉํ์ฌ JDK 17์ ์ค์ ํ๋ค.
3. Gradle ์ค์ - gradle/actions/setup-gradle@v3 ์ก์ ์ ์ฌ์ฉํ์ฌ Gradle์ ์ค์ ํ๋ค.
4. Gradle ๋น๋ -./gradlew build ๋ช ๋ น์ด๋ฅผ ์คํํ์ฌ ํ๋ก์ ํธ๋ฅผ ๋น๋ํ๋ค.
5. ๋ฐฐํฌ ํจํค์ง ์ค๋น - ๋น๋๋ jar ํ์ผ์ deploy ๋๋ ํฐ๋ฆฌ๋ก ๋ณต์ฌํ๋ค.
6. SSH ํค ์ถ๊ฐ - webfactory/ssh-agent@v0.9.0 ์ก์ ์ ์ฌ์ฉํ์ฌ SSH ํค๋ฅผ ์ถ๊ฐํ๋ค.
7. GCP VM์ ๋ฐฐํฌ - scp ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ jar ํ์ผ์ GCP VM ์ธ์คํด์ค๋ก ๋ณต์ฌํ๊ณ , ssh ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ์๊ฒฉ ์๋ฒ์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํ๋ค. (๋ฐฉํ๋ฒฝ 22 ํฌํธ๊ฐ ๋ฐ๋์ ์ด๋ ค์์ด์ผ ํ๋ค.)
โ๏ธ ๋ธ๋์น ๋ช ์ด main์ด ์๋ ๊ฒฝ์ฐ์๋, ๋ณธ์ธ ๋ฆฌํฌ์งํ ๋ฆฌ ํ๊ฒฝ์ ๋ง๋ ๋ธ๋์น๋ก ์์ ํด์ผ ํ๋ค.
์ฐ๋ถํฌ ํ๊ฒฝ์์ ์คํ๋ง ๋ถํธ ์ ํ๋ฆฌ์ผ์ด์ ์๋น์ค๋ฅผ ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ์ ๋ค์ ๊ฒ์๋ฌผ์ ์ฐธ๊ณ ํ๋ค.
Ubntu ํ๊ฒฝ์์ Spring Boot Application์ ๋ฑ๋กํ๊ธฐ
์์ฑ ํ์, ์ฐ์ธก ์๋จ์ ์ปค๋ฐ ๋ฒํผ์ ๋๋ฅด๊ณ Actions ํญ์ผ๋ก ๋ค์ด๊ฐ์ ๋น๋๊ฐ ์ํ๋๋์ง ํ์ธํด ๋ณธ๋ค.
๋น๋๊ฐ ์ฑ๊ณตํ๋ค๋ฉด ์ ์ด๋ฏธ์ง์ฒ๋ผ ์ด๋ก์ ๋น๋ ์ฒดํฌ ํ์๊ฐ ๋์จ๋ค.
5. ๋น๋ ํ์ธ
์ดํ VM ์๋ฒ์ ์ ์ํด์ app ๋๋ ํฐ๋ฆฌ์ ์ ๊ทผํ๋ฉด Secret์ผ๋ก ์ค์ ํ SNAPSHOT ํ์ผ์ด ์กด์ฌํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
netstat -tnlp ๋ช ๋ น์ด๋ฅผ ์ํํด์ ์ ์์ ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ํฌํธ๊ฐ ๋ ์๋์ง ํ์ธํด ๋ณด๊ณ , ์ ํ๋ฆฌ์ผ์ด์ ์ปจํธ๋กค๋ฌ์ ๋ฑ๋กํ API๋ฅผ ํธ์ถํด ๋ณด์.
๋๊ธ