๋ค์ด๊ฐ๋ฉฐ
์ด๋ฒ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ ๊ณผ์ ์์, ๋ฐฐํฌ ์์ ์ค ์๋ฒ ๋ค์ด ๋ฌธ์ ๋ฅผ ๊ฒฝํํ๊ฒ ๋์์ต๋๋ค. ์ด์ ๊น์ง๋ ์๋ก์ด ๋ฒ์ ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐฐํฌํ ๋๋ง๋ค ๋ถ๊ฐํผํ๊ฒ ํธ๋ํฝ ์ค๋จ์ด๋ ์๋ฌ ๋ฐ์์ด ๋๋ฐ๋์์ต๋๋ค. ํนํ, ์๋น์ค๊ฐ ์ค์๊ฐ์ผ๋ก ์ด์๋๋ ์ํฉ์์ ์ฌ์ฉ์๊ฐ ์ ์์ค์ผ ๋ ๋ฐฐํฌ๊ฐ ์ด๋ฃจ์ด์ง๋ฉด, ์ ์ ๋์ ์๋น์ค ์ด์ฉ์ ๋ถํธ์ ๊ฒช๊ฑฐ๋, ์ผ๋ถ ์์ฒญ์ด ์ฒ๋ฆฌ๋์ง ์๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ๊ธฐ๋ ํ์ต๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด, ๋ฐฐํฌ ๊ณผ์ ์์ ๋ฐ์ํ ์ ์๋ ๋ค์ดํ์์ ์ต์ํํ ์ ์๋ ๋ฐฉ๋ฒ์ ๊ณ ๋ฏผํ๊ฒ ๋์์ต๋๋ค. ์ฌ๋ฌ ๋ฐฐํฌ ์ ๋ต์ ์ดํด๋ณธ ๊ฒฐ๊ณผ, ๋ฌด์ค๋จ ๋ฐฐํฌ ๋ฐฉ์์ ์ ์ฉํ๋ ๊ฒ์ด ํจ๊ณผ์ ์ด๋ผ ํ๋จํ์๊ณ , ์ด๋ฅผ ๊ตฌํํ๊ธฐ ์ํด GitHub Actions์ Blue-Green ๋ฐฐํฌ ๋ฐฉ์์ ๋์ ํ๊ฒ ๋์์ต๋๋ค.
CI/CD ๋๊ตฌ ์ ์ ์ด์
๋ฐฐํฌ ์๋ํ๋ฅผ ๊ตฌํํ๋๋ฐ ์์ด, Jenkins์ GitHub Actions ๋๊ฐ์ง ์ต์ ์ ๋น๊ตํ์์ต๋๋ค.
Jenkins๋ ๋ค์ํ ์ธ์ด์ ์์ค์ฝ๋ ๋ฆฌํฌ์งํ ๋ฆฌ์ ๋ํด ์ง์์ ์ธ ํตํฉ(CI)๊ณผ ๋ฐฐํฌ(CD)๋ฅผ ์ง์ํ๋ฉฐ, ์์ ๋๊ฐ ๋๊ณ ์ปค์คํฐ๋ง์ด์ง์ด ์ฉ์ดํ ์ฅ์ ์ด ์์ต๋๋ค. ํ์ง๋ง, Jenkins๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๋ณ๋์ ์๋ฒ๋ฅผ ๊ตฌ์ถํ๊ณ ๊ด๋ฆฌํด์ผ ํ๊ณ , ์ด๊ธฐ ์ค์ ์ด ๋ค์ ๋ฌด๊ฒ๋ค๋ ๋จ์ ์ด ์์ต๋๋ค.
๋ฐ๋ฉด, GitHub Actions๋ GitHub์์ ๊ณต์์ ์ผ๋ก ์ ๊ณตํ๋ ์ํฌํ๋ก์ฐ ์๋ํ ๋๊ตฌ๋ก, ๋ณ๋์ ์ธํ๋ผ๋ฅผ ๊ตฌ์ฑํ ํ์์์ด ์ฝ๋ ํธ์, PR, Release ๋ฑ GitHub๋ด์ ์ด๋ฒคํธ์ ๋ฐ์ํ์ฌ ์๋์ผ๋ก ๋น๋ ๋ฐ ๋ฐฐํฌ ์์ ์ ์คํํ ์ ์์ต๋๋ค.
์ด๋ฒ ํ๋ก์ ํธ๋ ๊ท๋ชจ๊ฐ ํฌ์ง ์๊ณ , ๋ณต์กํ ์ปค์คํฐ๋ง์ด์ง์ด ํ์ํ์ง ์์ ์ํฉ์ด์๊ธฐ ๋๋ฌธ์, ๋ณด๋ค ๊ฐ๋จํ๊ณ ์ค์ ์ด ๋น ๋ฅธ GitHub Actions๋ฅผ ์ ํํ๊ฒ ๋์์ต๋๋ค.
๋ฐฐํฌ ์ ๋ต ์ ์ ์ด์
๊ฐ์ฅ ์ค์ํ ๊ณผ์ ์ค ํ๋๋ ์๋น์ค ์ค๋จ ์์ด ์๋ก์ด ๋ฒ์ ์ ์์ ์ ์ผ๋ก ๋ฐฐํฌํ๋ ๋ฐฉ๋ฒ์ด์์ต๋๋ค. ์ด๋ฅผ ์ํด ๋ค์ํ ๋ฌด์ค๋จ ๋ฐฐํฌ ์ ๋ต์ ๊ฒํ ํ์๊ณ , ์ค์ ํ๋ก์ ํธ ์ํฉ์ ๊ฐ์ฅ ์ ํฉํ ๋ฐฉ์์ ์ ํํ๊ณ ์ ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ๋ฒ๋ค์ ๊ณ ๋ คํ์์ต๋๋ค.
Rolling ๋ฐฐํฌ
Rolling ๋ฐฐํฌ ๋ฐฉ์์ ๊ธฐ์กด ์๋ฒ๋ฅผ ์์ฐจ์ ์ผ๋ก ๊ต์ฒดํ๋ ๋ฐฉ์์ผ๋ก ๋ฆฌ์์ค ์ฌ์ฉ๋์ด ์ ๊ณ ๊ฐ๋จํ๊ฒ ๊ตฌํํ ์ ์๋ ์ฅ์ ์ด ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ฐฐํฌ ์ค ๊ตฌ๋ฒ์ ๊ณผ ์ ๋ฒ์ ์ด ๋์์ ์๋น์ค๋๋ ๊ตฌ๊ฐ์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์, ์ด๋ก ์ธํ ํธํ์ฑ ๋ฌธ์ ๋ ์๊ธฐ์น ๋ชปํ ์ค๋ฅ ๋ฐ์ ๊ฐ๋ฅ์ฑ์ ์์ ํ ๋ฐฐ์ ํ ์ ์๋ค๋ ์ ์ด ๋ฆฌ์คํฌ๋ก ์์ฉํ์ต๋๋ค.
Canary ๋ฐฐํฌ
Canary ๋ฐฐํฌ ๋ฐฉ์์ ์ผ๋ถ ์๋ฒ๋ ์ฌ์ฉ์์๊ฒ๋ง ์ ๋ฒ์ ์ ๋จผ์ ๋ฐฐํฌํ๊ณ ๋ฌธ์ ๊ฐ ์์ ๊ฒฝ์ฐ ์ ์ฒด๋ก ํ์ฅํ๋ ์ ๋ต์ผ๋ก, ๋ฐฐํฌ ๋ฆฌ์คํฌ๋ฅผ ์ต์ํํ ์ ์์ต๋๋ค. ํ์ง๋ง ์ด๊ธฐ์๋ ํธ๋ํฝ ๋ถ๊ธฐ ๋ก์ง์ด๋ ์กฐ๊ฑด ์ฒ๋ฆฌ์ ๋ํ ์ถ๊ฐ์ ์ธ ๊ตฌํ ๋ณต์ก๋๊ฐ ์กด์ฌํ๊ณ , ํ๋ก์ ํธ ๊ท๋ชจ์ ์ธํ๋ผ ๊ตฌ์ฑ ์ ์ด๋ฅผ ์ ์ฉํ๊ธฐ์๋ ๋ค์ ๊ณผํ๋ค๋ ํ๋จ์ ๋ด๋ ธ์ต๋๋ค.
Blue-Green ๋ฐฐํฌ
Blue-Green ๋ฐฐํฌ ๋ฐฉ์์ ๊ธฐ์กด ์๋น์ค(Blue)์ ์๋ก์ด ๋ฒ์ (Green)์ ๋์์ ๊ตฌ๋์ํจ ๋ค, ๊ธฐ๋ฅ ๊ฒ์ฆ์ ๋ง์น๊ณ ๋ก๋ ๋ฐธ๋ฐ์๋ฅผ ํตํด ํธ๋ํฝ์ Green์ผ๋ก ์ผ๊ด ์ ํํ๋ ๋ฐฉ์์ ๋๋ค. ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋๋ผ๋ ๋ค์ Blue๋ก ๋น ๋ฅด๊ฒ ์ ํ์ด ๊ฐ๋ฅํด ์์ ์ฑ๊ณผ ๋ณต๊ตฌ ๊ฐ๋ฅ์ฑ์ด ๊ฐ์ฅ ๋์ ๋ฐฉ์์ด๋ผ๊ณ ํ๋จํ์ต๋๋ค.
๋ฌด์๋ณด๋ค Blue-Green ๋ฐฐํฌ ์ ๋ต ์์ฒด๊ฐ ๊ฐ๋จํ๊ณ ๋ช ํํ์ฌ, ๊ธฐ์กด์ ์๋ํ ํ์ดํ๋ผ์ธ๊ณผ ํตํฉํ๊ธฐ ์ฌ์ด ๋ฐฉ๋ฒ์ด๋ผ ํ๋จํด ํด๋น ๋ฐฉ์์ ์ต์ข ์ ์ผ๋ก ์ ํํ๊ฒ ๋์์ต๋๋ค.
EC2 ์๋ฒ ํ์ผ ๊ตฌ์กฐ
/wegotoo # ํ๋ก์ ํธ ๋ฃจํธ ๋๋ ํ ๋ฆฌ
โ
โโโ /nginx # Nginx ๊ด๋ จ ์ค์ ๋๋ ํ ๋ฆฌ
โ โโโ /conf # Nginx ์ค์ ํ์ผ ๋๋ ํ ๋ฆฌ
โ โ โโโ wegotoo.conf # Nginx ์๋ฒ ์ค์ ํ์ผ
โ โ
โ โโโ docker-compose.yml # Nginx ๋ฐ ๊ธฐํ ์๋น์ค ์ปจํ
์ด๋ ์ค์ ํ์ผ
โ
โโโ deploy.sh # ๋ฐฐํฌ ์๋ํ ์คํฌ๋ฆฝํธ
NGINX
NGINX๋ฅผ ์ฌ์ฉํ ์ด์ ๋ ํธ๋ํฝ ์ ํ์ ์์ ํ๊ณ ๋น ๋ฅด๊ฒ ํ๊ธฐ ์ํด ์ฌ์ฉํ์ต๋๋ค.
Blue-Green ๋ฐฐํฌ์ ํต์ฌ์ ํ์ฌ ์ด์์ค์ธ ์ธ์คํด์ค์ ์ ์ธ์คํด์ค๋ฅผ ๋์์ ๋์๋๊ณ , ํธ๋ํฝ๋ง ์ ํํ๋ ๊ฒ์ ๋๋ค. ์ด๋ ํธ๋ํฝ์ ์ด๋ป๊ฒ ์ ํํ ๊ฒ์ธ๊ฐ๊ฐ ํต์ฌ์ธ๋ฐ, ๊ทธ ์ญํ ์ NGINX์ ๋ฆฌ๋ฒ์ค ํ๋ก์๋ก ์ํํฉ๋๋ค.
docker-compose.yml
services:
nginx:
image: nginx:latest
container_name: nginx
ports:
- 80:80
volumes:
- ./conf:/etc/nginx/conf.d
์ด ์ค์ ํ์ผ์ ๋ก์ปฌ ๋๋ ํ ๋ฆฌ ./conf
์ ์๋ ํ์ผ๋ค์ NGINX ์ปจํ
์ด๋ ๋ด๋ถ์ /etc/nginx/conf.d
๊ฒฝ๋ก์ ๋ง์ดํธํ๋๋ก ๊ตฌ์ฑํ ๊ฒ์
๋๋ค. ์ฆ, NGINX๊ฐ ์ค์ ๋ก ์ฌ์ฉํ๋ ์ค์ ํ์ผ์ ํธ์คํธ ์์คํ
์์ ๊ด๋ฆฌํ๊ณ ์์ ํ ์ ์๋ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค์ด ์ค๋๋ค.
wegotoo.conf
server {
listen 80;
listen [::]:80;
server_name api.wegotoo.net;
location / {
proxy_pass http://172.17.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
}
์ด ์ค์ ํ์ผ์ api.wegotoo.net
์ผ๋ก ๋ค์ด์ค๋ ๋ชจ๋ ์์ฒญ์ Docker ํธ์คํธ์ ํน์ ํฌํธ๋ก ์ ๋ฌํ๋ ์ญํ ์ ํฉ๋๋ค. NGINX ์ปจํ
์ด๋๋ ์ด ์ค์ ํ์ผ์ ์ฝ์ด, ์์ฒญ์ ์ด๋๋ก ์ ๋ฌํ ์ง(๋ฆฌ๋ฒ์ค ํ๋ก์ ๋์)๋ฅผ ๊ฒฐ์ ํ๊ฒ ๋ฉ๋๋ค.
deploy.sh
์ด ์ฝ๋๋ Docker์ NGINX๋ฅผ ํ์ฉํ Blue-Green ๋ฐฐํฌ ์๋ํ ์คํฌ๋ฆฝํธ์ ๋๋ค. ๊ธฐ์กด ์ปจํ ์ด๋์ ์ ์ปจํ ์ด๋๋ฅผ ๋ฒ๊ฐ์๊ฐ๋ฉฐ ์ฌ์ฉํ๋ฉฐ, ๋ฌด์ค๋จ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ๋ฐ์ดํธํ ์ ์๋๋ก ํฉ๋๋ค.
# ์ ํ๋ฆฌ์ผ์ด์
์ด๋ฆ ๋ฐ ํฌํธ ์ค์
APP_NAME="wegotoo"
BLUE_PORT=8081
GREEN_PORT=8082
# ์ปจํ
์ด๋ ์ด๋ฆ ์ค์
BLUE_CONTAINER="wegotoo_blue"
GREEN_CONTAINER="wegotoo_green"
# ํฌ์ค ์ฒดํฌ๋ฅผ ์ํ URL ๊ธฐ๋ณธ ์ฃผ์
HEALTH_CHECK_URL="http://localhost"
echo "1๏ธโฃ ํ์ฌ ์คํ์ค์ธ ์ปจํ
์ด๋ ํ์ธ ์ค..."
# ํ์ฌ ์คํ ์ค์ธ ์ปจํ
์ด๋๊ฐ BLUE์ธ์ง ํ์ธ
if docker ps --format '{{.Names}}' | grep -q "$BLUE_CONTAINER"; then
ACTIVE=$BLUE_CONTAINER
ACTIVE_PORT=$BLUE_PORT
IDLE=$GREEN_CONTAINER
IDLE_PORT=$GREEN_PORT
else
ACTIVE=$GREEN_CONTAINER
ACTIVE_PORT=$GREEN_PORT
IDLE=$BLUE_CONTAINER
IDLE_PORT=$BLUE_PORT
fi
echo "2๏ธโฃ $IDLE ์ปจํ
์ด๋์ ์ต์ ์ด๋ฏธ์ง๋ก ๋ฐฐํฌ ์์..."
# ์ด๋ฏธ์ง ์ด๋ฆ ์ค์
IMAGE="$APP_NAME/prod:latest"
# ๊ธฐ์กด IDLE ์ปจํ
์ด๋๊ฐ ์คํ์ค์ด๋ฉด ์ข
๋ฃ
docker rm -f $IDLE || true
# ์ ์ปจํ
์ด๋ ์คํ
docker run -d --name $IDLE -p $IDLE_PORT:8080 $IMAGE
echo "3๏ธโฃ ํฌ์ค ์ฒดํฌ ์์..."
# ์ ์ปจํ
์ด๋๊ฐ ์ ์ ์๋ํ๋์ง ํ์ธ
for i in {1..10}; do
sleep 5
STATUS=$(curl -s "$HEALTH_CHECK_URL:$IDLE_PORT/health-check" | jq -r '.status')
if [ "$STATUS" == "OK" ]; then
echo "โ
ํฌ์ค ์ฒดํฌ ์ฑ๊ณต!"
break
fi
if [ $i -eq 10 ]; then
echo "โ ํฌ์ค ์ฒดํฌ ์คํจ! ๋กค๋ฐฑํฉ๋๋ค."
docker rm -f $IDLE || true
exit 1
fi
done
echo "4๏ธโฃ NGINX ์ค์ ํ์ผ ํฌํธ ์ค์์นญ ์ค..."
NGINX_CONTAINER_NAME="nginx"
# NGINX ์ค์ ํ์ผ์์ ํฌํธ๋ฅผ ACTIVE → IDLE๋ก ๋ณ๊ฒฝ
docker exec $NGINX_CONTAINER_NAME sed -i "s/$ACTIVE_PORT/$IDLE_PORT/g" /etc/nginx/conf.d/wegotoo.conf
# NGINX ์ฌ์์ (๋ฆฌ๋ก๋)
docker exec $NGINX_CONTAINER_NAME nginx -s reload
echo "5๏ธโฃ ์ด์ ACTIVE ์ปจํ
์ด๋ ์ข
๋ฃ..."
# ์ด์ ACTIVE ์ปจํ
์ด๋ ์ข
๋ฃ
docker rm -f $ACTIVE || true
echo "โ
๋ฐฐํฌ ์๋ฃ! ํ์ฌ ์๋น์ค ํฌํธ๋ $IDLE_PORT ์
๋๋ค."
- ํ์ฌ ์คํ์ค์ธ ์ปจํ
์ด๋ ํ์
- ํ์ฌ ์คํ์ค์ธ ์ปจํ ์ด๋๊ฐ BLUE์ธ์ง GREEN์ธ์ง ํ์ ํฉ๋๋ค.
- ๊ทธ์ ๋ฐ๋ผ ACTIVE(ํ์ฌ ์๋น์ค ์ค), IDLE(๋๊ธฐ ์ค)๋ฅผ ์ค์ ํฉ๋๋ค.
- IDLE ์ปจํ
์ด๋์ ์ต์ ์ด๋ฏธ์ง๋ก ๋ฐฐํฌ ์์
- ์ด์ IDLE ์ปจํ ์ด๋๊ฐ ์คํ์ค์ผ ์๋ ์๋ ์ํฉ์ด ์๊ธฐ ๋๋ฌธ์ ์ ๊ฑฐํ๊ณ ์ต์ ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํด ์ ์ปจํ ์ด๋๋ฅผ ์คํํฉ๋๋ค.
- ํฌ์ค ์ฒดํฌ
- ์ง์ ํ ํฌ์ค ์ฒดํฌ ์๋ ํฌ์ธํธ๋ฅผ ํตํด ์ปจํ ์ด๋๊ฐ ์ ์์ ์ผ๋ก ๋์ํ๋์ง ์ต๋ 10ํ ํ์ธํฉ๋๋ค.
- ์ฑ๊ณต ์ ๋ฃจํ๋ฅผ ๋น ์ ธ ๋์ค๊ณ , ์คํจ ์ ๋ฐฐํฌ๋ฅผ ์ค๋จํฉ๋๋ค.
- NGINX ์ค์ ์ค์์นญ
- ํ์ฌ ์๋น์ค ์ค์ธ ํฌํธ๋ฅผ ์ ์ปจํ ์ด๋์ ํฌํธ๋ก ๋ณ๊ฒฝํฉ๋๋ค.
- ์ด ์ค์ ์ NGINX ๋ด๋ถ์ wegotoo.conf ํ์ผ์ ์์ ํ๋ ๋ฐฉ์์ ๋๋ค.
- ์ดํ NGINX๋ฅผ reloadํ์ฌ ์ค์ ์ ๋ฐ์ํฉ๋๋ค.
- ์ด์ ์ปจํ
์ด๋ ์ ๋ฆฌ
- ์ด์ ์ปจํ ์ด๋(ACTIVE)๋ฅผ ์ข ๋ฃ ๋ฐ ์ญ์ ํ์ฌ ๋ฆฌ์์ค๋ฅผ ์ ๋ฆฌํฉ๋๋ค.
GitHub Actions
GitHub Actions workflows ํ๋ฆ
- ์ฝ๋๊ฐ main ๋ธ๋์น์ push ๋๋ฉด, GitHub Actions๊ฐ ํธ๋ฆฌ๊ฑฐ ๋ฉ๋๋ค.
- Gradle์ ํตํด ์ ํ๋ฆฌ์ผ์ด์ ์ ๋น๋ํ๊ณ , Docker ์ด๋ฏธ์ง๋ฅผ Docker Hub์ push ํฉ๋๋ค.
- EC2 ์๋ฒ๋ก SSH ์ ์ ํ, deploy.sh ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ์ฌ Blue-Green ๋ฐฐํฌ๋ฅผ ์ํํฉ๋๋ค.
- ๋ฐฐํฌ๊ฐ ์๋ฃ๋๋ฉด NGINX ์ค์ ์ ๋ณ๊ฒฝํ์ฌ ํธ๋ํฝ์ ์๋ก์ด ์ปจํ ์ด๋๋ก ์ ํํฉ๋๋ค.
wegotoo_prod.yml
name: wegotoo_prod
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
develop:
# ์คํ ํ๊ฒฝ
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
# JDK 17
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
# Gradle Caching
- name: Gradle Caching
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
# application-prod.yml
- name: Copy prod Secret
env:
DEV_SECRET: ${{ secrets.APPLICATION_PROD_YML }}
DEV_SECRET_DIR: src/main/resources
DEV_SECRET_DIR_FILE_NAME: application-prod.yml
run: echo $DEV_SECRET | base64 --decode >> $DEV_SECRET_DIR/$DEV_SECRET_DIR_FILE_NAME
# application-jwt.yml
- name: Copy jwt Secret
env:
DEV_SECRET: ${{ secrets.APPLICATION_JWT_YML }}
DEV_SECRET_DIR: src/main/resources
DEV_SECRET_DIR_FILE_NAME: application-jwt.yml
run: echo $DEV_SECRET | base64 --decode >> $DEV_SECRET_DIR/$DEV_SECRET_DIR_FILE_NAME
# application-oauth.yml
- name: Copy oauth Secret
env:
DEV_SECRET: ${{ secrets.APPLICATION_OAUTH_YML }}
DEV_SECRET_DIR: src/main/resources
DEV_SECRET_DIR_FILE_NAME: application-oauth.yml
run: echo $DEV_SECRET | base64 --decode >> $DEV_SECRET_DIR/$DEV_SECRET_DIR_FILE_NAME
# ./gradlew ๊ถํ ์ค์
- name: ./gradlew ๊ถํ ์ค์
run: chmod +x ./gradlew
# Gradle Build
- name: Build with Gradle
run: |
./gradlew clean
./gradlew compileJava
./gradlew build
# Docker Buildํ๊ณ DockerHub์ Push - name: Docker Build & Push to DockerHub
run: |
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
docker build -t ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_PROD_REPO }}:latest .
docker push ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_PROD_REPO }}:latest
# GitHub IP๋ฅผ ์์ฒญ
- name: Get GitHub IP
id: ip
uses: haythem/public-ip@v1.2
# AWS ์ธํ
- name: AWS Setting
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
aws-region: ap-northeast-2
# GitHub IP๋ฅผ AWS์ ์ถ๊ฐ
- name: Add GitHub IP to AWS
run: |
aws ec2 authorize-security-group-ingress --group-id ${{ secrets.AWS_SG_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
# SSH Key๋ก ์๋ฒ์ ์ ์ํ๊ณ deploy.sh ์คํ
- name: Run deploy.sh on EC2
uses: appleboy/ssh-action@v0.1.6
with:
host: ${{ secrets.EC2_PROD_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.KEY }}
port: 22
script: |
cd wegotoo
chmod +x deploy.sh
./deploy.sh
# Security Group์์ Github IP๋ฅผ ์ญ์
- name: Remove Github IP From Security Group
run: |
aws ec2 revoke-security-group-ingress --group-id ${{ secrets.AWS_SG_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
๊ฒฐ๊ณผ
์คํ ์
์ปจํ ์ด๋ ์ํ
NGINX ์ค์ ํ์ผ
GitHub Actions๋ฅผ ํตํด ์ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๊ธฐ ์ ์๋ wegotoo_blue
์ปจํ
์ด๋๊ฐ :8081
๋ฒ ํฌํธ์์ ์๋น์ค ์ค์ด๊ณ , NGINX ์ค์ ํ์ผ ์ญ์ proxy_pass http://172.17.0.1:8081;
๋ก ์ง์ ๋์ด ์์ต๋๋ค.
์คํ ํ
์ปจํ ์ด๋ ์ํ
NGINX ์ค์ ํ์ผ
์คํ๋ ํ์๋ ์๋กญ๊ฒ ๊ธฐ๋๋ wegotoo_green
์ปจํ
์ด๋๊ฐ :8082
๋ฒ ํฌํธ์์ ์ ์์ ์ผ๋ก ๊ตฌ๋๋ ์ดํ, NGINX ์ค์ ์ด ์๋์ผ๋ก proxy_pass http://172.17.0.1:8082;
๋ก ์ ํ๋์์ต๋๋ค. ๊ทธ ๊ฒฐ๊ณผ ํธ๋ํฝ์ด ๊ธฐ์กด์ wegotoo_blue
์ปจํ
์ด๋๊ฐ ์๋ wegotoo_green
์ปจํ
์ด๋๋ก ๋ฌธ์ ์์ด ์ด๋ํจ์ ํ์ธํ ์ ์์์ต๋๋ค.
'Project' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์ฑํ ๋ฉ์ธ์ง ์ฝ์ ์ฒ๋ฆฌ ๊ธฐ๋ฅ ๊ตฌ์กฐ ๊ฐ์ ๊ธฐ (0) | 2024.12.18 |
---|---|
Embedded Mongo/Redis ์ ์ฉํ๊ธฐ (0) | 2024.11.26 |
๋ณ์ ์ค๋ณต ์์ฑ ๋์์ฑ ์ด์ ํด๊ฒฐ (0) | 2024.10.27 |
CompletableFuture๋ฅผ ํ์ฉํ ์ฑ๋ฅ ๊ฐ์ ๊ธฐ (0) | 2024.08.01 |