Skip to content
85 changes: 84 additions & 1 deletion .github/workflows/ci-java.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,87 @@ jobs:

- name: Run Spotless Check
run: ./gradlew spotlessCheck
working-directory: apps/user-service
working-directory: apps/user-service

build:
name: Build
runs-on: ubuntu-latest
needs: spotless-check
strategy:
matrix:
java-version: [ "21" ]

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

- name: Set up JDK ${{ matrix.java-version }}
uses: actions/setup-java@v4
with:
java-version: '${{ matrix.java-version }}'
distribution: 'temurin'
cache: 'gradle'

- name: Grant execute permission for Gradle wrapper
run: chmod +x ./gradlew
working-directory: apps/user-service

- name: Run Gradle Build
run: ./gradlew build -x test
working-directory: apps/user-service

# - name: Run Tests
# run: |
# if [ "${{ github.base_ref }}" == "main" ]; then
# ./gradlew test
# else
# ./gradlew prTest
# fi
# working-directory: apps/user-service
- name: Upload build artifacts
if: matrix.java-version == '21' && github.ref == 'refs/heads/main' && github.event_name == 'push'
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: apps/user-service/build/libs/

docker:
name: Build Spring Boot Docker Image and push to registry
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
needs:
- build

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

- name: Download build artifacts (JAR)
uses: actions/download-artifact@v4
with:
name: build-artifacts
path: apps/user-service/build/libs/

- name: Login to Docker Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set repo lowercase
run: echo "REPO_LC=${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./apps/user-service
push: true
tags: |
ghcr.io/${{ env.REPO_LC }}/user-service:latest
ghcr.io/${{ env.REPO_LC }}/user-service:${{ github.sha }}

- name: Analyze image layers
run: |
echo "=== Image Layer Analysis ==="
docker history ghcr.io/${{ env.REPO_LC }}/user-service:latest --human --no-trunc
74 changes: 74 additions & 0 deletions .github/workflows/deploy-java.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Deploy

on:
workflow_dispatch:
push:
tags:
- 'v*'

jobs:
deploy:
name: Deploy to AWS EC2
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set repo lowercase
run: echo "REPO_LC=${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV

- name: Copy docker compose files to EC2
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
source: "docker/production/docker-compose.yml"
target: "~/app"

- name: Deploy on EC2
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.SERVER_HOST }}
# username: ${{ secrets.SERVER_USER }}
username: ubuntu
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
cd ~/app/docker/production
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin

docker pull ghcr.io/${{ env.REPO_LC }}/user-service:latest

docker compose down
docker compose up -d

sleep 10
docker compose ps

docker image prune -f

# - name: Send Discord notification - Success
# if: success()
# uses: Ilshidur/action-discord@master
# env:
# DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_URL }}
# with:
# args: |
# **배포 성공**
# **Repository:** ${{ env.REPO_LC }}
# **Tag:** ${{ github.ref_name }}
# **Server:** ${{ secrets.SERVER_HOST }}
# **Status:** Success!
#
# - name: Send Discord notification - Failure
# if: failure()
# uses: Ilshidur/action-discord@master
# env:
# DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_URL }}
# with:
# args: |
# **배포 실패**
# **Repository:** ${{ env.REPO_LC }}
# **Tag:** ${{ github.ref_name }}
# **Error:** 배포 중 오류가 발생했습니다.
# **Check:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
39 changes: 3 additions & 36 deletions apps/user-service/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,42 +1,9 @@
# 1단계: 빌드 스테이지
# Java 21 JDK가 포함된 경량 이미지를 사용합니다.
# 이 단계에서 애플리케이션을 빌드합니다.
FROM openjdk:21-jdk-slim AS builder
FROM eclipse-temurin:21-jre

# 컨테이너 내부에 작업 디렉토리를 생성하고 설정합니다.
WORKDIR /app

# Gradle Wrapper, 설정 파일, 소스 코드를 복사합니다.
# Docker의 레이어 캐싱을 활용하여 빌드 속도를 높입니다.
COPY gradlew .
COPY gradle/ gradle/
COPY build.gradle .
COPY settings.gradle .
COPY build/libs/*.jar app.jar

# 애플리케이션 소스 코드를 복사합니다.
COPY src src

# 애플리케이션을 빌드하여 실행 가능한 JAR 파일을 만듭니다.
# `-x test`는 이미지 빌드 시 테스트를 건너뛰는 명령입니다.
RUN ./gradlew clean build -x test

---

# 2단계: 실행 스테이지
# 애플리케이션 실행에 필요한 Java 21 JRE만 포함된 경량 이미지를 사용합니다.
FROM openjdk:21-jre-slim

# 컨테이너 내부의 작업 디렉토리를 설정합니다.
WORKDIR /app

# 빌드 스테이지에서 생성된 JAR 파일을 복사합니다.
# `--from=builder` 옵션을 사용하여 첫 번째 단계에서 빌드된 JAR만 가져옵니다.
# 파일명은 `group`, `version`에 따라 `glt-korea-0.0.1-SNAPSHOT.jar`가 되므로,
# 이를 `app.jar`라는 간단한 이름으로 변경합니다.
COPY --from=builder /app/build/libs/glt-korea-0.0.1-SNAPSHOT.jar ./app.jar

# 애플리케이션이 외부 요청을 받을 포트를 노출합니다.
EXPOSE 8080

# 컨테이너 시작 시 실행될 명령어를 정의합니다.
CMD ["java", "-jar", "app.jar"]
CMD ["java", "-jar", "app.jar"]
17 changes: 17 additions & 0 deletions docker/production/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: "3.9"

services:
user-service:
image: ghcr.io/kernel180-be12/final-4team-icebang/user-service:latest
container_name: user-service
restart: always
ports:
- "80:8080"
env_file:
- .env
networks:
- app-network

networks:
app-network:
driver: bridge