Skip to content

Commit b9ed798

Browse files
committed
Deploy: write dockerfile & deploy flow files
1 parent 9efa940 commit b9ed798

File tree

4 files changed

+261
-0
lines changed

4 files changed

+261
-0
lines changed

.DS_Store

6 KB
Binary file not shown.

.github/workflows/deploy.yml

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
name: Deploy with Docker Hub
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main]
8+
9+
env:
10+
DOCKER_IMAGE: leeeunda/blockcloud-server
11+
12+
jobs:
13+
test:
14+
runs-on: ubuntu-latest
15+
continue-on-error: true # 급배포용(테스트 실패해도 다음 진행)
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Set up JDK 21
20+
uses: actions/setup-java@v4
21+
with:
22+
java-version: '21'
23+
distribution: temurin
24+
25+
- name: Cache Gradle
26+
uses: actions/cache@v3
27+
with:
28+
path: |
29+
~/.gradle/caches
30+
~/.gradle/wrapper
31+
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
32+
restore-keys: ${{ runner.os }}-gradle-
33+
34+
- name: Run tests (non-blocking)
35+
run: ./gradlew test || true
36+
37+
build-and-push:
38+
needs: test
39+
runs-on: ubuntu-latest
40+
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop'
41+
steps:
42+
- uses: actions/checkout@v4
43+
44+
- name: Login to Docker Hub
45+
uses: docker/login-action@v3
46+
with:
47+
username: ${{ secrets.DOCKER_USERNAME }} # <<< CHANGE(secrets): Docker Hub ID
48+
password: ${{ secrets.DOCKER_PASSWORD }} # <<< CHANGE(secrets): Docker Hub PAT/비번
49+
50+
- name: Set up Docker Buildx
51+
uses: docker/setup-buildx-action@v3
52+
53+
# 만약 EC2가 Graviton(ARM64)이면 platform 지정 필요
54+
# with: platforms: linux/arm64
55+
- name: Build and push Docker image
56+
uses: docker/build-push-action@v5
57+
with:
58+
context: .
59+
push: true
60+
tags: |
61+
${{ env.DOCKER_IMAGE }}:latest
62+
${{ env.DOCKER_IMAGE }}:${{ github.sha }}
63+
${{ env.DOCKER_IMAGE }}:${{ github.ref_name }}
64+
cache-from: type=gha
65+
cache-to: type=gha,mode=max
66+
# platforms: linux/amd64 # <<< CHANGE(옵션): EC2가 x86_64면 유지, ARM이면 linux/arm64 로
67+
68+
deploy-to-ec2:
69+
needs: build-and-push
70+
runs-on: ubuntu-latest
71+
if: github.ref == 'refs/heads/main'
72+
steps:
73+
- name: Deploy to EC2 (pull & replace container)
74+
uses: appleboy/ssh-action@v1.2.0
75+
with:
76+
host: ${{ secrets.EC2_HOST }} # <<< CHANGE(secrets): EC2 퍼블릭 도메인/IP
77+
username: ${{ secrets.EC2_USER }} # <<< CHANGE(secrets): 일반 ubuntu
78+
key: ${{ secrets.EC2_SSH_KEY }} # <<< CHANGE(secrets): PEM 본문
79+
script: |
80+
set -e
81+
IMAGE="${{ env.DOCKER_IMAGE }}:${{ github.sha }}"
82+
echo "Pull $IMAGE"
83+
docker pull "$IMAGE"
84+
85+
echo "Stop & remove old container"
86+
docker stop blockcloud-app || true
87+
docker rm blockcloud-app || true
88+
89+
echo "Run new container (bind only localhost)"
90+
docker run -d \
91+
--name blockcloud-app \
92+
--restart unless-stopped \
93+
--env-file /srv/app/.env \
94+
-p 127.0.0.1:8080:8080 \
95+
"$IMAGE"
96+
97+
echo "Health check"
98+
# <<< CHANGE(필요시): 액추에이터 경로가 다르면 아래 URL 수정
99+
for i in {1..20}; do
100+
if curl -fsS http://127.0.0.1:8080/actuator/health >/dev/null 2>&1; then
101+
echo "UP"
102+
exit 0
103+
fi
104+
sleep 3
105+
done
106+
107+
echo "App failed to start. Logs:"
108+
docker logs --tail=200 blockcloud-app || true
109+
exit 1

Dockerfile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# 멀티스테이지 빌드
2+
FROM gradle:8.5-jdk21 AS build
3+
4+
# 작업 디렉토리 설정
5+
WORKDIR /app
6+
7+
# Gradle 파일들 복사 (캐시 최적화)
8+
COPY gradlew .
9+
COPY gradle gradle
10+
COPY build.gradle .
11+
COPY settings.gradle .
12+
13+
# 의존성 다운로드
14+
RUN ./gradlew dependencies --no-daemon
15+
16+
# 소스 코드 복사
17+
COPY src src
18+
19+
# JAR 파일 빌드
20+
RUN ./gradlew build -x test --no-daemon
21+
22+
# 실행 스테이지
23+
FROM openjdk:21-jdk-slim
24+
25+
# 메타데이터
26+
LABEL maintainer="BlockCloud Team"
27+
LABEL version="1.0"
28+
LABEL description="BlockCloud Backend Application"
29+
30+
# 작업 디렉토리 설정
31+
WORKDIR /app
32+
33+
# JAR 파일 복사
34+
COPY --from=build /app/build/libs/*.jar app.jar
35+
36+
# 포트 노출
37+
EXPOSE 8080
38+
39+
# 헬스체크
40+
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
41+
CMD curl -f http://localhost:8080/actuator/health || exit 1
42+
43+
# 애플리케이션 실행
44+
ENTRYPOINT ["java", "-jar", "app.jar"]

scripts/deploy.sh

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#!/bin/bash
2+
3+
# BlockCloud Docker Hub 배포 스크립트
4+
set -e
5+
6+
# 색상 정의
7+
RED='\033[0;31m'
8+
GREEN='\033[0;32m'
9+
YELLOW='\033[1;33m'
10+
NC='\033[0m' # No Color
11+
12+
# 로그 함수
13+
log_info() {
14+
echo -e "${GREEN}[INFO]${NC} $1"
15+
}
16+
17+
log_warn() {
18+
echo -e "${YELLOW}[WARN]${NC} $1"
19+
}
20+
21+
log_error() {
22+
echo -e "${RED}[ERROR]${NC} $1"
23+
}
24+
25+
# 환경 변수 설정
26+
ENVIRONMENT=${1:-dev}
27+
DOCKER_USERNAME=${DOCKER_USERNAME:-your-dockerhub-username}
28+
DOCKER_IMAGE=${DOCKER_IMAGE:-$DOCKER_USERNAME/blockcloud-backend}
29+
EC2_HOST=${EC2_HOST:-your-ec2-host}
30+
EC2_USERNAME=${EC2_USERNAME:-ubuntu}
31+
32+
log_info "🚀 BlockCloud Docker Hub 배포 시작 (환경: $ENVIRONMENT)"
33+
34+
# 1. 테스트 실행
35+
log_info "🧪 테스트 실행 중..."
36+
./gradlew test
37+
38+
# 2. Docker 이미지 빌드
39+
log_info "🐳 Docker 이미지 빌드 중..."
40+
docker build -t $DOCKER_IMAGE:latest .
41+
42+
# 3. 이미지 태깅
43+
IMAGE_TAG=$(git rev-parse --short HEAD)
44+
docker tag $DOCKER_IMAGE:latest $DOCKER_IMAGE:$IMAGE_TAG
45+
46+
log_info "📦 이미지 태그: $IMAGE_TAG"
47+
48+
# 4. Docker Hub 로그인 확인
49+
if [ -z "$DOCKER_PASSWORD" ]; then
50+
log_error "DOCKER_PASSWORD 환경 변수가 설정되지 않았습니다."
51+
log_info "다음 명령어로 설정하세요:"
52+
log_info "export DOCKER_PASSWORD=your-dockerhub-password"
53+
exit 1
54+
fi
55+
56+
# 5. Docker Hub에 로그인
57+
log_info "🔐 Docker Hub 로그인 중..."
58+
echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin
59+
60+
# 6. 이미지 푸시
61+
log_info "📤 Docker Hub에 이미지 푸시 중..."
62+
docker push $DOCKER_IMAGE:latest
63+
docker push $DOCKER_IMAGE:$IMAGE_TAG
64+
65+
log_info "✅ Docker Hub 푸시 완료!"
66+
67+
# 7. EC2 배포 (프로덕션 환경인 경우)
68+
if [ "$ENVIRONMENT" = "prod" ]; then
69+
log_info "🖥️ EC2에 배포 중..."
70+
71+
# EC2에 SSH로 접속하여 배포
72+
ssh -o StrictHostKeyChecking=no $EC2_USERNAME@$EC2_HOST << EOF
73+
# Docker Hub에서 이미지 풀
74+
docker pull $DOCKER_IMAGE:$IMAGE_TAG
75+
76+
# 기존 컨테이너 중지 및 제거
77+
docker stop blockcloud-app || true
78+
docker rm blockcloud-app || true
79+
80+
# 새 컨테이너 실행
81+
docker run -d \\
82+
--name blockcloud-app \\
83+
--restart unless-stopped \\
84+
-p 8080:8080 \\
85+
-e SPRING_PROFILES_ACTIVE=prod \\
86+
-e DB_HOST=\$DB_HOST \\
87+
-e DB_USERNAME=\$DB_USERNAME \\
88+
-e DB_PASSWORD=\$DB_PASSWORD \\
89+
-e JWT_SECRET=\$JWT_SECRET \\
90+
$DOCKER_IMAGE:$IMAGE_TAG
91+
92+
# 헬스체크
93+
sleep 30
94+
if curl -f http://localhost:8080/actuator/health; then
95+
echo "✅ 배포 성공!"
96+
else
97+
echo "❌ 배포 실패!"
98+
docker logs blockcloud-app
99+
exit 1
100+
fi
101+
EOF
102+
else
103+
log_info "🔄 로컬 환경 배포 완료"
104+
fi
105+
106+
log_info "✅ 배포 완료!"
107+
log_info "📊 이미지: $DOCKER_IMAGE:$IMAGE_TAG"
108+
log_info "🔗 Docker Hub: https://hub.docker.com/r/$DOCKER_USERNAME/blockcloud-backend"

0 commit comments

Comments
 (0)