Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Runtime image (JRE만)
FROM eclipse-temurin:21-jre

# 애플리케이션 실행 디렉토리
WORKDIR /app

# CI에서 만든 JAR 복사
COPY build/libs/*.jar /app/app.jar

# 실행
ENTRYPOINT ["java","-jar","/app/app.jar"]
46 changes: 46 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: CD

on:
workflow_run:
workflows: ["CI with Gradle"] # CI 워크플로 이름과 정확히 일치해야 함
types: [completed] # CI가 끝났을 때 트리거
branches: [main] # 특정 브랜치에서만

permissions:
contents: read

env:
IMAGE: ${{ secrets.DOCKER_USERNAME }}/[소문자로 시작하는 프로젝트명]

jobs:
deploy:
name: Deploy to Server
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

# SSH로 서버에 접속해 배포
- name: Deploy over SSH
uses: appleboy/[email protected]
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
port: 22
script: |
echo "${{ secrets.ENV_FILE }}" > /home/${{ secrets.SERVER_USER }}/.env
echo "[1/3] Pull latest Docker image..."
docker pull ${{ env.IMAGE }}:latest

echo "[2/3] Restart container with new image..."
docker stop [이미지명(소문자로 시작하는 프로젝트명)] || true
docker rm [이미지명(소문자로 시작하는 프로젝트명)] || true
docker run -d --name [이미지명(소문자로 시작하는 프로젝트명)] \
--env-file /home/${{ secrets.SERVER_USER }}/.env \
-p 8080:8080 \
${{ env.IMAGE }}:latest


echo "[3/3] Cleanup unused images..."
docker image prune -f
83 changes: 83 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: CI with Gradle

on:
pull_request:
branches: ["main"] # 특정 브랜치에 PR 이벤트 발생 시(열림/수정/리오픈 등) CI 실행
push:
branches: ["main"] # 특정 브랜치로 직접 push될 때도 CI 실행
workflow_dispatch: # Actions 탭에서 수동 실행 버튼 제공(필요할 때 수동으로 돌릴 수 있게)

# 같은 브랜치에서 중복 실행되면 이전 빌드 취소(리소스 절약/레이스 방지)
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read # 코드 읽기 권한

# 전역 환경변수
env:
JAVA_VERSION: '21' # 사용할 JDK 버전(프로젝트에 맞게 조정)
IMAGE: ${{ secrets.DOCKER_USERNAME }}/[leafly] # Docker Hub 이미지명(소문자 필수)

jobs:
build: # 1) 빌드 전용 Job — PR과 push 모두 실행
name: Build
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Temurin JDK
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: ${{ env.JAVA_VERSION }}

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4

- name: Grant execute permission for gradlew
run: chmod +x gradlew # gradlew 실행 권한 부여(권한 문제 예방)

- name: Build JAR
run: ./gradlew bootJar -x test --no-daemon # 테스트 건너뛰고 배포용 JAR 빌드

- name: Upload JAR artifact
uses: actions/upload-artifact@v4 # 아티팩트로 업로드
with:
name: app-jar
path: build/libs/*.jar

docker-push: # 2) Docker 이미지 빌드/푸시 Job — PR에서는 실행 X
name: Docker Build & Push
# 조건: PR 이벤트가 아니고 && 대상 브랜치가 main일 때만 이미지 푸시
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
needs: build # 빌드 Job 성공 후에만 실행
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Download JAR artifact # build에서 맏느 아티팩트 다운로드
uses: actions/download-artifact@v4
with:
name: app-jar
path: build/libs

- name: Login to Docker Hub
uses: docker/login-action@v3 # Docker Hub 로그인
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build & Push image
uses: docker/build-push-action@v6
with:
context: . # 현재 디렉토리를 빌드 컨텍스트로 사용
push: true # 빌드한 이미지를 Docker Hub에 푸시
tags: |
${{ env.IMAGE }}:latest
${{ env.IMAGE }}:${{ github.sha }}