-
Notifications
You must be signed in to change notification settings - Fork 0
224 lines (195 loc) · 8.33 KB
/
cd.yml
File metadata and controls
224 lines (195 loc) · 8.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
name: CD - Docker Build & Deploy
on:
push:
branches: [ "main", "master" ]
workflow_dispatch:
env:
REGISTRY: ghcr.io
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: 코드 체크아웃
uses: actions/checkout@v4
- name: Java 17 설정
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: 'gradle'
- name: Gradle 실행 권한 부여
run: chmod +x ./gradlew
- name: 애플리케이션 JAR 빌드
run: ./gradlew bootJar --no-daemon -x test
- name: QEMU 설정 (ARM64 크로스 컴파일)
uses: docker/setup-qemu-action@v3
with:
platforms: linux/amd64
- name: 이미지 이름 소문자 변환
id: image_name
run: |
IMAGE_NAME=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
echo "name=${IMAGE_NAME}" >> $GITHUB_OUTPUT
echo "소문자 변환된 이미지 이름: ${IMAGE_NAME}"
- name: Docker Buildx 설정
uses: docker/setup-buildx-action@v3
- name: GitHub Container Registry 로그인
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker 메타데이터 추출
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ steps.image_name.outputs.name }}
tags: |
type=ref,event=branch
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Docker 이미지 빌드 및 푸시
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
platforms: linux/amd64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=eod-build
cache-to: type=gha,scope=eod-build,mode=max
build-args: |
BUILDKIT_INLINE_CACHE=1
- name: 이미지 다이제스트 출력
run: echo ${{ steps.meta.outputs.digest }}
deploy:
needs: build-and-push
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
steps:
- name: 서버에 SSH 접속 및 Docker Compose 배포
uses: appleboy/[email protected]
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.SSH_PORT || 22 }}
script: |
# 배포 디렉토리 생성 및 이동
mkdir -p ~/eod
cd ~/eod
# GitHub Repository Clone 또는 Pull
if [ -d ".git" ]; then
echo "기존 저장소 업데이트 중..."
git fetch origin main
git reset --hard origin/main
else
echo "저장소 복제 중..."
rm -rf * .* 2>/dev/null || true
git clone https://github.com/${{ github.repository }}.git .
fi
# .env 파일 생성 (GitHub Secrets 사용)
REPO_LOWERCASE=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
cat > .env << EOF
GITHUB_REPOSITORY=${REPO_LOWERCASE}
SPRING_DATASOURCE_URL=${{ secrets.DB_URL }}
SPRING_DATASOURCE_USERNAME=${{ secrets.DB_USERNAME }}
SPRING_DATASOURCE_PASSWORD=${{ secrets.DB_PASSWORD }}
MYSQL_ROOT_PASSWORD=${{ secrets.MYSQL_ROOT_PASSWORD }}
MYSQL_DATABASE=${{ secrets.MYSQL_DATABASE }}
MYSQL_USER=${{ secrets.DB_USERNAME }}
MYSQL_PASSWORD=${{ secrets.DB_PASSWORD }}
GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}
GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }}
JWT_SECRET=${{ secrets.JWT_SECRET }}
BASE_URL=${{ secrets.BASE_URL }}
FRONTEND_BASE_URL=${{ secrets.FRONTEND_BASE_URL }}
LOG_DIR=${{ secrets.LOG_DIR }}
BSM_CLIENT_ID=${{ secrets.BSM_CLIENT_ID }}
BSM_CLIENT_SECRET=${{ secrets.BSM_CLIENT_SECRET }}
BSM_OAUTH_BASE_URL=${{ secrets.BSM_OAUTH_BASE_URL }}
BSM_REDIRECT_URI=${{ secrets.BSM_REDIRECT_URI }}
FILE_UPLOAD_BASE_URL=${{ secrets.FILE_UPLOAD_BASE_URL }}
EOF
# GitHub Container Registry 로그인
echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
# 환경 변수 확인 (디버깅)
echo "GITHUB_REPOSITORY (소문자): ${REPO_LOWERCASE}"
# MySQL 볼륨 존재 여부 확인 및 생성
echo "========================================="
echo "📦 MySQL 볼륨 확인 중..."
if ! docker volume inspect eod_mysql-data-dev >/dev/null 2>&1; then
echo "⚠️ 볼륨이 존재하지 않습니다. 새로 생성합니다..."
docker volume create eod_mysql-data-dev
echo "✅ 볼륨 생성 완료: eod_mysql-data-dev"
else
echo "✅ 볼륨이 이미 존재합니다: eod_mysql-data-dev"
fi
echo "========================================="
# Docker Compose로 배포
echo "========================================="
echo "🚀 Docker Compose 배포 시작"
echo "========================================="
for i in 1 2 3; do
echo "Docker 이미지 pull 시도 ${i}/3..."
docker compose -f docker-compose.yml pull && break
echo "Pull 실패, 30초 후 재시도..."
[ $i -lt 3 ] && sleep 30 || { echo "❌ Pull 최종 실패"; exit 1; }
done
docker compose -f docker-compose.yml down
docker compose -f docker-compose.yml up -d --remove-orphans
# 배포 직후 상태 확인
echo "========================================="
echo "📊 배포 직후 컨테이너 상태:"
docker compose -f docker-compose.yml ps
echo "========================================="
# 컨테이너 시작 대기
echo "컨테이너 시작 대기 중..."
sleep 10
# 사용하지 않는 이미지 정리
docker image prune -af
- name: 배포 상태 확인
uses: appleboy/[email protected]
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.SSH_PORT || 22 }}
script: |
cd ~/eod
echo "========================================="
echo "📋 환경 변수 확인 (민감 정보 마스킹):"
cat .env | sed 's/PASSWORD=.*/PASSWORD=***/g' | sed 's/SECRET=.*/SECRET=***/g'
echo "========================================="
echo "🐳 컨테이너 실행 상태:"
docker compose -f docker-compose.yml ps
# 컨테이너 실행 검증 (app 컨테이너가 반드시 떠있어야 함)
if ! docker compose -f docker-compose.yml ps | grep -q "eod-app-dev.*Up"; then
echo "❌ ERROR: app 컨테이너가 실행되지 않았습니다!"
docker compose -f docker-compose.yml logs --tail=100 app
exit 1
fi
echo "✅ app 컨테이너 정상 실행 확인"
echo "========================================="
echo "📊 Docker 이미지 확인:"
docker images | grep eod || true
echo "========================================="
echo "📝 MySQL 로그 (최근 20줄):"
docker compose -f docker-compose.yml logs --tail=20 mysql || true
echo "========================================="
echo "📝 애플리케이션 로그 (최근 50줄):"
docker compose -f docker-compose.yml logs --tail=50 app || true
echo "========================================="
echo "🔍 포트 사용 확인:"
netstat -tuln | grep -E ':(8000|3306)' || true
- name: 배포 완료 알림
if: success()
run: |
IMAGE_NAME=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
echo "✅ Docker Compose 배포 완료!"
echo "서버: ${{ secrets.SSH_HOST }}"
echo "이미지: ${{ env.REGISTRY }}/${IMAGE_NAME}:latest"