Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
958bdd5
kubernetes yaml파일 수정
byb0823 Nov 13, 2025
23121bb
Add CI workflow for develop branch
byb0823 Nov 14, 2025
6f0a547
Rename develop CI to pull request CI
byb0823 Nov 14, 2025
3daa345
Modify CI workflow configuration file name
byb0823 Nov 14, 2025
8395619
Add CD workflow for Docker and K3s deployment
byb0823 Nov 20, 2025
63a3649
Add Dockerfile for Gradle build and deployment
byb0823 Nov 20, 2025
5f303f3
Delete .github/workflows/Dockerfile
byb0823 Nov 20, 2025
29b3aea
Add Dockerfile for Gradle build and Java application
byb0823 Nov 20, 2025
0ef4fcf
Rename deployment and service to skill-boost-app
byb0823 Nov 20, 2025
f5283dc
Fix Docker password secret and enhance deployment process
byb0823 Nov 20, 2025
68dbcf2
Implement dynamic IP management for GitHub Actions
byb0823 Nov 20, 2025
d1cdc54
Add conditional execution for IP removal step
byb0823 Nov 20, 2025
f2e5278
add application yml file
byb0823 Nov 20, 2025
1dff829
remove cd command
byb0823 Nov 20, 2025
4ccfdd9
CD comment out
byb0823 Nov 20, 2025
747ccee
add test controller
byb0823 Nov 20, 2025
082b9d6
Add workflow_dispatch trigger to CD workflow
byb0823 Nov 20, 2025
20803c6
Update Docker image name in app.yaml
byb0823 Nov 20, 2025
ce16e0e
modify k3s yaml file
byb0823 Nov 20, 2025
4fd2ddb
modify app.yaml
byb0823 Nov 20, 2025
ee5fa2a
modify app.yaml
byb0823 Nov 20, 2025
e8c92b6
modify mysql.yaml
byb0823 Nov 20, 2025
73b44a5
modify cd
byb0823 Nov 20, 2025
51022cc
modify CD.yaml
byb0823 Nov 20, 2025
0071494
modify CD.yaml
byb0823 Nov 20, 2025
85d8b0d
modify hello controller
byb0823 Nov 20, 2025
8067a18
modify CD.yml
byb0823 Nov 20, 2025
d9dda04
modify image name
byb0823 Nov 20, 2025
c9633ce
change test controller return value
byb0823 Nov 20, 2025
4f7eebd
application yml파일 수정
byb0823 Nov 21, 2025
188a686
CI/CD yml파일 수정
byb0823 Nov 21, 2025
c97e5c8
build: Gradle의존성 추가(Security, OAuth2, JWT, Swagger)(#2)
JONGTAE02 Nov 24, 2025
8304e91
feat: 유저 엔티티 및 레포지토리 구현 (#2)
JONGTAE02 Nov 24, 2025
0e0b112
feat: JWT 토큰 생성 및 인증 필터 구현(#2)
JONGTAE02 Nov 24, 2025
04c5c87
config: Security 및 Swagger 환경 설정(#2)
JONGTAE02 Nov 24, 2025
daaa550
feat: AuthController 구현 및 깃허브 로그인 URL API 추가(#2)
JONGTAE02 Nov 24, 2025
8ef3a91
feat: OAuth2 유저 서비스 및 로그인 성공 핸들러 구현(#2)
JONGTAE02 Nov 24, 2025
5222c30
chore: 의미없는 주석 해제(#2)
JONGTAE02 Nov 24, 2025
3064898
chore: 의미없는 주석 제거(#2)
JONGTAE02 Nov 24, 2025
15742a5
Merge remote-tracking branch 'origin/feature/login-auth-github_new' i…
JONGTAE02 Nov 24, 2025
3ed823f
refactor: JwtProvider 초기화 로직 개선 및 에러 핸들링 강화(#2)
JONGTAE02 Nov 25, 2025
3008bbf
refactor: JwtProvider 초기화 로직 개선 및 에러 핸들링 강화(#2)
JONGTAE02 Nov 25, 2025
111096b
application-test.yml 파일 수정
byb0823 Nov 27, 2025
b25a4c8
CI.yml 파일 수정
byb0823 Nov 27, 2025
15f142b
Merge remote-tracking branch 'origin/feature/login-auth-github_new' i…
JONGTAE02 Nov 27, 2025
20b292e
Merge remote-tracking branch 'origin/main' into feature/login-auth-gi…
JONGTAE02 Nov 27, 2025
edb40e3
fix: Base64 형식으로 JWT secret key Update(#2)
JONGTAE02 Nov 27, 2025
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
135 changes: 135 additions & 0 deletions .github/workflows/CD.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
name: CD

on:
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-latest

steps:
# 코드 체크아웃
- name: Checkout
uses: actions/checkout@v4

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

# Docker 이미지 빌드 & 푸시
- name: Build and Push Docker image
run: |
docker build -t ${{ secrets.DOCKER_USERNAME }}/skill-boost:${{ github.sha }} .
docker push ${{ secrets.DOCKER_USERNAME }}/skill-boost:${{ github.sha }}

# EC2로 yaml 파일 복사
- name: Copy k8s manifests to EC2
uses: appleboy/scp-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
source: "k8s/*.yaml"
target: "/home/${{ secrets.EC2_USER }}/k8s-manifests"

# SSH 접속 후 app.yaml의 IMAGE 치환
- name: Replace IMAGE in app.yaml on EC2
uses: appleboy/[email protected]
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
# k8s 매니페스트 디렉토리
MANIFEST_DIR="/home/${{ secrets.EC2_USER }}/k8s-manifests/k8s"

# IMAGE를 GitHub Secret 값으로 치환
sed -i "s|IMAGE|${{ secrets.DOCKER_USERNAME }}/skill-boost:${{ github.sha }}|g" "$MANIFEST_DIR/app.yaml"

echo "✅ app.yaml의 USERNAME 치환 완료"

# # Github Actions IP 가져오기
# - name: Get Github Actions IP
# id: ip
# uses: haythem/[email protected]
#
# # AWS 보안 그룹에 동적으로 IP 추가
# - name: Add Github Actions IP to Security group
# run: |
# aws ec2 authorize-security-group-ingress --group-id ${{ secrets.AWS_SECRET_GROUP_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
# env:
# AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
# AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# AWS_DEFAULT_REGION: ap-northeast-2

# EC2 SSH → k3s에 Secret 생성 & Deployment 업데이트
- name: Deploy to K3s via SSH
uses: appleboy/[email protected]
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
# 기존 db-secret 삭제
kubectl delete secret db-secret

# -- db-secret 생성 --
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: db-secret
namespace: default
type: Opaque
stringData:
MYSQL_ROOT_PASSWORD: "${{ secrets.DB_PASSWORD }}"
MYSQL_DATABASE: "${{ secrets.DB }}"
MYSQL_USER: "${{ secrets.DB_USERNAME }}"
MYSQL_PASSWORD: "${{ secrets.DB_PASSWORD }}"
EOF

# 기존 app-secret 삭제
kubectl delete secret app-secret

# -- app-secret 생성 --
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: app-secret
namespace: default
type: Opaque
stringData:
MYSQL_URL: "${{ secrets.MYSQL_URL }}"
JWT_SECRET_KEY: "${{ secrets.JWT_SECRET_KEY }}"
GITHUB_CLIENT_SECRET: "${{ secrets.GITHUB_CLIENT_SECRET }}"
EOF

# -- 매니페스트 파일 적용 --
cd /home/${{ secrets.EC2_USER }}/k8s-manifests/k8s
kubectl apply -f .

# -- 롤링 업데이트 완료 대기 --
kubectl rollout status deployment/skill-boost-app --timeout=5m

# -- 배포 결과 확인 --
kubectl get pods -l app=skill-boost-app
echo "✅ Deployment successful!"

# -- 사용하지 않는 이미지 삭제 --
sudo k3s ctr images prune --all

# AWS 보안 그룹에서 IP 제거
# - name: Remove Github Actions IP from security group
# if: always()
# run: |
# aws ec2 revoke-security-group-ingress --group-id ${{ secrets.AWS_SECRET_GROUP_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
# env:
# AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
# AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# AWS_DEFAULT_REGION: ap-northeast-2
45 changes: 45 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: pull request CI

on:
workflow_dispatch:
pull_request:
branches:
- main
- develop

jobs:
build-and-test:
runs-on: ubuntu-latest

steps:
# 코드 체크아웃
- name: Checkout code
uses: actions/checkout@v4

# JDK 21 설정
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
cache: 'gradle'

# Gradle wrapper 실행 권한 부여
- name: Grant execute permission for gradlew
run: chmod +x gradlew

# 빌드 & 테스트
- name: Build and Test
run: ./gradlew clean build
env:
SPRING_PROFILES_ACTIVE: test

# 테스트 결과 업로드
- name: Upload Test Artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: |
build/reports/tests/test/
build/test-results/test/
25 changes: 25 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
FROM gradle:8.8-jdk21 AS builder

WORKDIR /app

# Gradle 캐시 활용
COPY build.gradle settings.gradle gradlew ./
COPY gradle gradle
RUN ./gradlew dependencies || true

# 소스 코드 복사
COPY . .

# 빌드
RUN chmod +x gradlew
RUN ./gradlew clean build -x test

FROM amazoncorretto:21

WORKDIR /app

COPY --from=builder /app/build/libs/*.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "app.jar"]
40 changes: 0 additions & 40 deletions app.yaml

This file was deleted.

9 changes: 9 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,16 @@ dependencies {
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'com.h2database:h2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'

}

tasks.named('test') {
Expand Down
69 changes: 69 additions & 0 deletions k8s/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: skill-boost-app
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: skill-boost-app
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: skill-boost-app
spec:
containers:
- name: skill-boost-app
image: IMAGE
imagePullPolicy: Always
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
envFrom:
- secretRef:
name: db-secret
- secretRef:
name: app-secret
---
apiVersion: v1
kind: Service
metadata:
name: skill-boost-service
namespace: default
labels:
app: skill-boost-app
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: skill-boost-app
sessionAffinity: None
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: skill-boost-app-ingress
namespace: default
spec:
ingressClassName: traefik
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: skill-boost-service
port:
number: 80
3 changes: 2 additions & 1 deletion mysql.yaml → k8s/mysql.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 5Gi
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: default
spec:
selector:
app: mysql
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/com/example/skillboost/TestController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.example.skillboost;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
@GetMapping("/")
public String hello() {
return "Hello World!";
}
}
Loading