Skip to content

Commit c79b82c

Browse files
authored
Merge pull request #139 from Central-MakeUs/dev
deploy: 배포 스크립트 수정
2 parents a945271 + 4dde573 commit c79b82c

File tree

1 file changed

+93
-66
lines changed

1 file changed

+93
-66
lines changed

.github/workflows/deploy.yml

Lines changed: 93 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Deploy To EC2 (Blue-Green via SSM)
1+
name: Deploy To EC2 (Blue-Green via Bastion)
22

33
on:
44
push:
@@ -8,10 +8,12 @@ permissions:
88
contents: read
99

1010
jobs:
11+
# 1️⃣ BUILD JOB
1112
build:
1213
runs-on: ubuntu-latest
1314
steps:
1415
- uses: actions/checkout@v4
16+
1517
- uses: actions/setup-java@v4
1618
with:
1719
distribution: temurin
@@ -42,80 +44,105 @@ jobs:
4244
docker tag forday:latest 839983937363.dkr.ecr.ap-northeast-2.amazonaws.com/forday:latest
4345
docker push 839983937363.dkr.ecr.ap-northeast-2.amazonaws.com/forday:latest
4446
47+
# 2️⃣ DEPLOY JOB
4548
deploy:
4649
needs: build
4750
runs-on: ubuntu-latest
4851
steps:
49-
- name: Configure AWS Credentials
50-
uses: aws-actions/configure-aws-credentials@v4
51-
with:
52-
aws-region: ap-northeast-2
53-
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
54-
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
52+
- name: Configure SSH (Bastion → Private)
53+
run: |
54+
mkdir -p ~/.ssh
55+
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
56+
chmod 600 ~/.ssh/id_rsa
57+
58+
cat <<EOF >> ~/.ssh/config
59+
Host bastion
60+
HostName ${{ secrets.BASTION_HOST }}
61+
User ubuntu
62+
IdentityFile ~/.ssh/id_rsa
63+
StrictHostKeyChecking no
64+
65+
Host private
66+
HostName ${{ secrets.EC2_PRIVATE_HOST }}
67+
User ubuntu
68+
IdentityFile ~/.ssh/id_rsa
69+
ProxyJump bastion
70+
StrictHostKeyChecking no
71+
EOF
5572
56-
- name: Blue-Green Deploy via SSM
73+
- name: Blue-Green Deploy
5774
run: |
58-
COMMAND_ID=$(aws ssm send-command \
59-
--document-name "AWS-RunShellScript" \
60-
--instance-ids "${{ secrets.EC2_INSTANCE_ID }}" \
61-
--parameters '{
62-
"commands": [
63-
"set -e",
64-
"ENV_FILE=/etc/nginx/conf.d/service-env.inc",
65-
"if [ ! -f $ENV_FILE ]; then sudo sh -c \"printf '\''set \\$service_url blue;'\'' > $ENV_FILE\"; fi",
75+
ssh private << 'EOF'
76+
set -e
6677
67-
"if grep -q \"green\" $ENV_FILE; then TARGET=\"blue\"; TARGET_PORT=8080; OLD_TARGET=\"green\"; else TARGET=\"green\"; TARGET_PORT=8081; OLD_TARGET=\"blue\"; fi",
78+
echo "▶ Detect current upstream from nginx env file"
79+
if [ -f /etc/nginx/conf.d/service-env.inc ]; then
80+
CURRENT_VAL=$(grep -oP '(?<=set \$service_url ).*(?=;)' /etc/nginx/conf.d/service-env.inc || echo "blue")
81+
else
82+
CURRENT_VAL="blue"
83+
fi
6884
69-
"echo \"▶ 배포 시작: $TARGET (포트: $TARGET_PORT)\"",
70-
"aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 839983937363.dkr.ecr.ap-northeast-2.amazonaws.com",
71-
"docker pull 839983937363.dkr.ecr.ap-northeast-2.amazonaws.com/forday:latest",
85+
echo "현재 서비스 상태: $CURRENT_VAL"
7286
73-
"docker stop $TARGET || true",
74-
"docker rm $TARGET || true",
75-
"docker run -d --name $TARGET --restart=always -e SPRING_PROFILES_ACTIVE=$TARGET -p $TARGET_PORT:8080 -e SPRING_DATA_REDIS_HOST=172.17.0.1 -e SPRING_DATA_REDIS_PORT=6379 839983937363.dkr.ecr.ap-northeast-2.amazonaws.com/forday:latest",
87+
if [ "$CURRENT_VAL" = "blue" ]; then
88+
TARGET="green"
89+
TARGET_PORT=8081
90+
OLD_TARGET="blue"
91+
else
92+
TARGET="blue"
93+
TARGET_PORT=8080
94+
OLD_TARGET="green"
95+
fi
7696
77-
"echo \"▶ 헬스 체크 시작...\"",
78-
"HEALTH_OK=false",
79-
"for i in {1..20}; do",
80-
" # curl 실패 시에도 스크립트가 중단되지 않도록 || true 추가",
81-
" HTTP_CODE=$(curl -s -o /dev/null -w \"%{http_code}\" http://localhost:$TARGET_PORT/health_check || echo \"000\")",
82-
" if [ \"$HTTP_CODE\" = \"200\" ] || [ \"$HTTP_CODE\" = \"401\" ]; then",
83-
" echo \"✅ 서비스 응답 확인 (코드: $HTTP_CODE)\"",
84-
" HEALTH_OK=true",
85-
" break",
86-
" fi",
87-
" echo \"대기 중... ($i/20) 응답: $HTTP_CODE\"",
88-
" sleep 10",
89-
"done",
97+
echo "▶ Deploy target: $TARGET (port: $TARGET_PORT)"
98+
echo "▶ Old container: $OLD_TARGET"
9099
91-
"if [ \"$HEALTH_OK\" = \"true\" ]; then",
92-
" echo \"▶ Nginx 스위칭 실행\"",
93-
" sudo sh -c \"printf '\''set \\$service_url $TARGET;'\'' > $ENV_FILE\"",
94-
" sudo nginx -t && sudo nginx -s reload",
95-
" echo \"▶ 이전 컨테이너 정리\"",
96-
" docker stop $OLD_TARGET || true",
97-
" docker rm $OLD_TARGET || true",
98-
" docker image prune -af",
99-
" echo \"✅ 배포 성공: $TARGET\"",
100-
"else",
101-
" echo \"❌ 헬스 체크 최종 실패\"",
102-
" docker logs --tail 50 $TARGET",
103-
" exit 1",
104-
"fi"
105-
]
106-
}' --query "Command.CommandId" --output text)
107-
108-
echo "Command ID: $COMMAND_ID"
109-
110-
# EC2 내부 실행 완료 대기
111-
aws ssm wait command-executed --command-id "$COMMAND_ID" --instance-id "${{ secrets.EC2_INSTANCE_ID }}" || true
112-
113-
# 상세 로그 출력 (스위칭 여부 확인용)
114-
aws ssm list-command-invocations --command-id "$COMMAND_ID" --details --query "CommandInvocations[0].CommandPlugins[0].Output" --output text
100+
# ECR 로그인
101+
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 839983937363.dkr.ecr.ap-northeast-2.amazonaws.com
102+
103+
echo "▶ Pull image"
104+
docker pull 839983937363.dkr.ecr.ap-northeast-2.amazonaws.com/forday:latest
105+
106+
echo "▶ Stop & remove current $TARGET (if exists)"
107+
docker stop $TARGET || true
108+
docker rm $TARGET || true
109+
110+
echo "▶ Run new $TARGET"
111+
docker run -d \
112+
--name $TARGET \
113+
--restart=always \
114+
-e SPRING_PROFILES_ACTIVE=$TARGET \
115+
-p $TARGET_PORT:8080 \
116+
-e SPRING_DATA_REDIS_HOST=172.17.0.1 \
117+
-e SPRING_DATA_REDIS_PORT=6379 \
118+
839983937363.dkr.ecr.ap-northeast-2.amazonaws.com/forday:latest
119+
120+
echo "▶ Health Check"
121+
for i in {1..20}; do
122+
if curl -sf http://localhost:$TARGET_PORT/health_check; then
123+
echo "Health OK"
124+
HEALTH_OK=true
125+
break
126+
fi
127+
echo "Waiting... ($i/20)"
128+
sleep 5
129+
done
130+
131+
if [ "$HEALTH_OK" != "true" ]; then
132+
echo "❌ Health check failed. Rollback."
133+
docker logs $TARGET
134+
exit 1
135+
fi
136+
137+
echo "▶ Switching Nginx upstream to $TARGET"
138+
echo "set \$service_url $TARGET;" | sudo tee /etc/nginx/conf.d/service-env.inc
139+
140+
sudo nginx -t
141+
sudo nginx -s reload
142+
143+
echo "▶ Stopping OLD container: $OLD_TARGET"
144+
docker stop $OLD_TARGET || true
145+
docker rm $OLD_TARGET || true
115146
116-
# 최종 상태 확인
117-
FINAL_STATUS=$(aws ssm get-command-invocation --command-id "$COMMAND_ID" --instance-id "${{ secrets.EC2_INSTANCE_ID }}" --query "Status" --output text)
118-
if [ "$FINAL_STATUS" != "Success" ]; then
119-
echo "Deployment failed with status: $FINAL_STATUS"
120-
exit 1
121-
fi
147+
echo "✅ Deployment complete. Now running: $TARGET"
148+
EOF

0 commit comments

Comments
 (0)