Continuous Deployment - 100-hours-a-week/3-team-ssammu-wiki GitHub Wiki
GitHub Push
โ
GitHub Actions (CI)
โ
๋ฐฑ์๋ JAR / ํ๋ก ํธ ์ ์ ํ์ผ / AI ์์ค GCS ์
๋ก๋
โ
Self-Hosted Runner
โ
deploy.sh ์คํ
โ
๋ฐฑ์๋ JAR ๊ต์ฒด ๋ฐ ์คํ
ํ๋ก ํธ ์ ์ ํ์ผ ๋ณต์ฌ
AI ์๋ฒ ์ฌ์์
ํญ๋ชฉ | ์๋ ๋ฐฐํฌ | CD(์ง์์ ๋ฐฐํฌ) |
---|---|---|
ํจ์จ์ฑ | ๋ฐฐํฌํ ๋๋ง๋ค ์๋ ๋ช
๋ น์ด ์
๋ ฅ ํ์ โ ๋ฐ๋ณต์ ์ด๊ณ ์๋ชจ์ |
ํธ์ ํ ์๋์ผ๋ก ๋ฐฐํฌ๋์ด ๋ฐ๋ณต ์์ ์ ๊ฑฐ |
์๋ | ๋ฐฐํฌ ์๋ ๋ด๋น์ ์ญ๋์ ์์กด โ ๋ณ๋ชฉ ๋ฐ์ ๊ฐ๋ฅ |
์ผ๊ด๋ ์๋๋ก ์๋ ๋ฐฐํฌ ๊ฐ๋ฅ โ ๋ฆด๋ฆฌ์ฆ ์ฃผ๊ธฐ ๋จ์ถ |
์ ๋ขฐ์ฑ | ์์ ์ ์ค์(ํ์ผ ๋๋ฝ, ์์ ์ค๋ฅ ๋ฑ) ๋ฐ์ ๊ฐ๋ฅ | ์คํฌ๋ฆฝํธ ๊ธฐ๋ฐ ์๋ ์ฒ๋ฆฌ๋ก ์ ๋ขฐ๋ ์์น |
ํ์ฅ์ฑ | ์๋ฒ/ํ๊ฒฝ ์ ์ฆ๊ฐ ์ ์์์ ๊ด๋ฆฌ ํ๊ณ ๋ฐ์ | ํ๊ฒฝ ์์ ๊ด๊ณ์์ด ์ผ๊ด๋ ๋ฐฐํฌ ๊ฐ๋ฅ |
๋ชจ๋ํฐ๋ง | ๋ฐฐํฌ ์คํจ ์ฌ๋ถ ํ์ธ ์ด๋ ค์ | ์คํจ ์ ๋กค๋ฐฑ, ์๋ฆผ, ์ํ ์ฒดํฌ ๊ฐ๋ฅ |
- ์์์ ๋๋น ๋ฐฐํฌ ์๊ฐ ๋ํญ ๊ฐ์ (15๋ถ โ 3~5๋ถ)
- GCS ํ์ฉ์ผ๋ก ๋น๋ ์ฐ์ถ๋ฌผ ๋ฒ์ ๊ด๋ฆฌ ๋ฐ ์ธ๋ถ ๋ ธ์ถ ์ต์ํ
- ๋ค์ดํ์ ์ต์ํ (๊ฐ ํ๋ก์ธ์ค ๊ต์ฒด ์ 1~2๋ถ ์ด๋ด)
- ๋กค๋ฐฑ ์๋ํ ๊ธฐ๋ฐ ํ๋ณด
- CI-CD ๊ตฌ์กฐ ๋ถ๋ฆฌ๋ก ์ญํ ๋ช ํํ ๋ฐ ๋ณด์/์ ์ง๋ณด์ ์ฉ์ด์ฑ ์์น
name: CD on Self-Hosted Runner
on:
workflow_dispatch: # ๋๋ push, deploy tag ๋ฑ
jobs:
deploy:
runs-on: self-hosted
steps:
- name: Run deploy.sh from local repo
run: |
chmod +x ./scripts/deploy.sh
./scripts/deploy.sh
!/bin/bash
# ๐ ๊ฒฝ๋ก ์ค์
GCS_BUCKET_NAME=careerbee-deploy-artifacts
RELEASE_DIR=~/release
BACKEND_DIR=$RELEASE_DIR/backend
FRONTEND_DIR=$RELEASE_DIR/frontend
AI_DIR=$RELEASE_DIR/ai
LOG_DIR=~/logs
mkdir -p $BACKEND_DIR $FRONTEND_DIR $AI_DIR $LOG_DIR
echo GCS์์ ์ต์ ๋น๋ ํ์ผ ๋ค์ด๋ก๋
echo ๋ฐฑ์๋ JAR ๋ค์ด๋ก๋...
gsutil cp gs://$GCS_BUCKET_NAME/backend/app-latest.jar $BACKEND_DIR/app.jar
echo ํ๋ก ํธ์๋ ์ ์ ํ์ผ ๋ค์ด๋ก๋...
gsutil -m cp -r gs://$GCS_BUCKET_NAME/frontend/* $FRONTEND_DIR/
echo AI ์๋ฒ ์์ถ ํ์ผ ๋ค์ด๋ก๋ ๋ฐ ํด์ ...
gsutil cp gs://$GCS_BUCKET_NAME/ai/ai-latest.zip $AI_DIR/
unzip -o $AI_DIR/ai-latest.zip -d $AI_DIR/
echo ๋ฐฑ์๋ ํ๋ก์ธ์ค ๊ต์ฒด
pkill -f 'app.jar' || echo ๊ธฐ์กด ๋ฐฑ์๋ ํ๋ก์ธ์ค ์์
nohup java -jar $BACKEND_DIR/app.jar $LOG_DIR/backend.log
echo ํ๋ก ํธ์๋ ์ ์ ํ์ผ ๋ฎ์ด์ฐ๊ธฐ
sudo cp -r $FRONTEND_DIR/* /var/www/html/
echo AI ์๋ฒ ์ฌ์์
cd $AI_DIR
source venv/bin/activate || python3 -m venv venv source venv/bin/activate
pip install -r requirements.txt
pkill -f 'uvicorn' || echo ๊ธฐ์กด AI ํ๋ก์ธ์ค ์์
nohup uvicorn main:app --host 0.0.0.0 --port 8000 $LOG_DIR/ai.log
echo โ
๋ฐฐํฌ ์๋ฃ
- GitHub Actions ์์์ ๋น๋์ ๋ฐฐํฌ๋ ์ฑ๊ณตํ๋๋ผ๋, ์ค์ ๋ฐฐํฌ๋ ์๋น์ค์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์
- ex) ๋ก๊ทธ์ธ ์คํจ, AI ์๋ต ์ค๋ฅ, ํ๊ฒฝ๋ณ์ ๋๋ฝ ๋ฑ
- GCS์ Git ์ปค๋ฐ ํด์ ๊ธฐ์ค์ผ๋ก ๋ฒ์ ๋ ์ฐ์ถ๋ฌผ์ ์ ๋ก๋ํจ์ผ๋ก์จ, ๐ ์๋น์ค ์ฅ์ ๋ฐ์ ์ ํน์ ๋ฒ์ ์ผ๋ก ๋น ๋ฅด๊ฒ ๋ณต์ ๊ฐ๋ฅ
์ฆ, GitHub Actions์๋ ์ฑ๊ณต์ด๋ผ ํ๊ธฐ๋์ง๋ง ์ฌ์ฉ์๋ ์ฅ์ ๋ฅผ ๊ฒช๋ ๊ฒฝ์ฐ์๋ ๋น ๋ฅด๊ฒ ๋์ ๊ฐ๋ฅํ๋๋ก ํ๋ ์ฌํ ๋ณต๊ตฌ ์ ๋ต
ํญ๋ชฉ | ์ ์ฅ ๊ฒฝ๋ก ์์ | ์ค๋ช |
---|---|---|
Backend | gs://careerbee-deploy-artifacts/backend/app-.jar | ์ปค๋ฐ ๊ธฐ์ค์ผ๋ก JAR ๋ฒ์ ๋ณด๊ด |
Frontend | gs://careerbee-deploy-artifacts/frontend// | ์ ์ ๋ฆฌ์์ค ์ ์ฒด ๋๋ ํ ๋ฆฌ ๋ณด๊ด |
AI Server | gs://careerbee-deploy-artifacts/ai/ai-.zip | ์์ถ๋ ์์ค ์ฝ๋ ๋ฐ venv ํฌํจ |
- ์๋น์ค ๋ฐฐํฌ ์ดํ ์ฅ์ ๋ฐ์ ์, ๊ฐ๋ฐ์๋ GCS์ ์ ์ฅ๋ ์ด์ ์ปค๋ฐ ๊ธฐ๋ฐ์ ๋น๋ ์ฐ์ถ๋ฌผ์ ๊ธฐ์ค์ผ๋ก ๋น ๋ฅด๊ฒ ๋กค๋ฐฑ์ ์งํํ๋ค
-
Cloud Storage์์๋ ๊ฐ์ฅ ์ต๊ทผ ์ฑ๊ณตํ ์ปค๋ฐ ํด์ ๊ธฐ์ค์ผ๋ก ๋ฒ์ ์ ํ์ธ
-
Compute Engine์ SSH ์ ์ํ์ฌ
./rollback.sh <์ปค๋ฐํด์>
๋ฅผ ์คํ
Self-Hosted Runner ํ๊ฒฝ ๋ด ์๋ํ๋ GitHub Actions ๊ธฐ๋ฐ ๋ฐฐํฌ ์์คํ ๊ณผ ์ฐ๊ณ๋์ด ์๊ธฐ ๋๋ฌธ์, ๋กค๋ฐฑ ์ดํ์๋ ๋์ผํ ๋ฐฐํฌ ํ๋ก์ฐ๋ฅผ ๋ฐ๋ผ ์๋ํ๋ ์ฌ๋ฐฐํฌ๊ฐ ๊ฐ๋ฅ
# ๐ ๋กค๋ฐฑ ๋์ ์ปค๋ฐ ํด์ ์๋ ์ง์
COMMIT_HASH=$1
if [ -z "$COMMIT_HASH" ]; then
echo "๋กค๋ฐฑํ ์ปค๋ฐ ํด์๋ฅผ ์ธ์๋ก ์
๋ ฅํ์ธ์"
echo "์: ./rollback.sh 1a2b3c4d"
exit 1
fi
GCS_BUCKET_NAME=careerbee-deploy-artifacts
RELEASE_DIR=~/release
BACKEND_DIR=$RELEASE_DIR/backend
FRONTEND_DIR=$RELEASE_DIR/frontend
AI_DIR=$RELEASE_DIR/ai
LOG_DIR=~/logs
mkdir -p $BACKEND_DIR $FRONTEND_DIR $AI_DIR $LOG_DIR
echo "๐ GCS์์ ์ปค๋ฐ $COMMIT_HASH ๊ธฐ์ค์ผ๋ก ๋น๋ ํ์ผ ๋ค์ด๋ก๋"
echo "๐ ๋ฐฑ์๋ JAR ๋ค์ด๋ก๋..."
gsutil cp gs://$GCS_BUCKET_NAME/backend/app-${COMMIT_HASH}.jar $BACKEND_DIR/app.jar
echo "๐ ํ๋ก ํธ์๋ ์ ์ ํ์ผ ๋ค์ด๋ก๋..."
gsutil -m cp -r gs://$GCS_BUCKET_NAME/frontend/${COMMIT_HASH}/* $FRONTEND_DIR/
echo "๐ AI ์๋ฒ ์์ถ ํ์ผ ๋ค์ด๋ก๋ ๋ฐ ํด์ ..."
gsutil cp gs://$GCS_BUCKET_NAME/ai/ai-${COMMIT_HASH}.zip $AI_DIR/
unzip -o $AI_DIR/ai-${COMMIT_HASH}.zip -d $AI_DIR/
echo "๐ ๋ฐฑ์๋ ์ฌ์์"
pkill -f 'app.jar' || echo "๊ธฐ์กด ๋ฐฑ์๋ ์์"
nohup java -jar $BACKEND_DIR/app.jar > $LOG_DIR/backend_rollback.log 2>&1 &
echo "๐ ํ๋ก ํธ์๋ ์ฌ๋ฐฐํฌ"
sudo cp -r $FRONTEND_DIR/* /var/www/html/
echo "๐ AI ์๋ฒ ์ฌ์์"
cd $AI_DIR
source venv/bin/activate || python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
pkill -f 'uvicorn' || echo "๊ธฐ์กด AI ์์"
nohup uvicorn main:app --host 0.0.0.0 --port 8000 > $LOG_DIR/ai_rollback.log 2>&1 &
echo "โ
๋กค๋ฐฑ ์๋ฃ - ์ปค๋ฐ $COMMIT_HASH"
์ํฉ | ๋์ ์ ๋ต |
---|---|
๋ฐฐํฌ ์ดํ ๋ก๊ทธ์ธ ์ค๋ฅ ๋ฑ ๊ธฐ๋ฅ ์ฅ์ ๋ฐ์ |
./rollback.sh <๋ฌธ์ ์๋ ์ปค๋ฐ ํด์> ์คํ |
๋ฐฐํฌ ์งํ ์ฌ์ดํธ ์ ์ ์๋จ | GCS์์ ์ด์ ๋ฒ์ ๋ค์ด๋ก๋ โ ์๋น์ค ๊ต์ฒด |
FastAPI ์ค๋ฅ | AI ์๋ฒ๋ง ๋กค๋ฐฑ ๊ฐ๋ฅ (๋ค๋ฅธ ์๋น์ค๋ ์ ์ง) |
๐ ๋ณธ ํ์ด์ง๋ 2025๋ 4์ 22์ผ์ ๋ง์ง๋ง์ผ๋ก ์ ๋ฐ์ดํธ๋์์ต๋๋ค.