Skip to content

Commit fbf3493

Browse files
authored
Merge pull request #288 from KW-ClassLog/Chore/#276-deploy
📦 Chore/#276 배포 테스트 2
2 parents 157f20c + f118dce commit fbf3493

File tree

14 files changed

+433
-88
lines changed

14 files changed

+433
-88
lines changed

.github/workflows/CD.yml

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
name: ClassLog CD
2+
3+
on:
4+
push:
5+
branches: ["test-deploy"]
6+
7+
permissions:
8+
contents: read
9+
packages: write
10+
11+
env:
12+
IMAGE_TAG: ${{ github.sha }}
13+
BACKEND_IMAGE: ${{ secrets.DOCKER_USERNAME }}/classlog-backend
14+
FRONTEND_IMAGE: ${{ secrets.DOCKER_USERNAME }}/classlog-frontend
15+
jobs:
16+
build-and-push:
17+
runs-on: ubuntu-latest
18+
19+
steps:
20+
- name: Checkout
21+
uses: actions/checkout@v4
22+
23+
- name : Set up JDK 17
24+
uses: actions/setup-java@v4
25+
with:
26+
java-version: '17'
27+
distribution: 'temurin'
28+
29+
- name: Grant execute permission for gradlew
30+
working-directory: ./backend
31+
run: chmod +x gradlew
32+
33+
- name: Build with Gradle
34+
working-directory: ./backend
35+
run: ./gradlew clean bootJar
36+
37+
- name: Login to Docker Hub
38+
uses: docker/login-action@v3
39+
with:
40+
username: ${{ secrets.DOCKER_USERNAME }}
41+
password: ${{ secrets.DOCKER_PASSWORD }}
42+
43+
- name: Build & Push Backend Image
44+
run: |
45+
docker build -t ${BACKEND_IMAGE}:latest -t ${BACKEND_IMAGE}:${IMAGE_TAG} ./backend
46+
docker push ${BACKEND_IMAGE}:latest
47+
docker push ${BACKEND_IMAGE}:${IMAGE_TAG}
48+
49+
- name: Build & Push Frontend Image
50+
run: |
51+
docker build -t ${FRONTEND_IMAGE}:latest -t ${FRONTEND_IMAGE}:${IMAGE_TAG} ./frontend
52+
docker push ${FRONTEND_IMAGE}:latest
53+
docker push ${FRONTEND_IMAGE}:${IMAGE_TAG}
54+
deploy:
55+
needs: build-and-push
56+
runs-on: ubuntu-latest
57+
58+
steps:
59+
- name: Create backend/.env on server
60+
uses: appleboy/[email protected]
61+
with:
62+
host: ${{ secrets.SSH_HOST }}
63+
username: ${{ secrets.SSH_USER }}
64+
key: ${{ secrets.SSH_KEY }}
65+
script: |
66+
mkdir -p /home/ubuntu/classlog/backend
67+
cat > /home/ubuntu/classlog/backend/.env <<EOF
68+
DB_USERNAME=${{ secrets.DB_USERNAME }}
69+
DB_PASSWORD=${{ secrets.DB_PASSWORD }}
70+
DB_NAME=${{ secrets.DB_NAME }}
71+
DB_HOST=${{ secrets.DB_HOST }}
72+
DB_PORT=${{ secrets.DB_PORT }}
73+
REDIS_HOST=${{ secrets.REDIS_HOST }}
74+
REDIS_PORT=${{ secrets.REDIS_PORT }}
75+
JWT_SECRET=${{ secrets.JWT_SECRET }}
76+
MAIL_HOST=${{ secrets.MAIL_HOST }}
77+
MAIL_PORT=${{ secrets.MAIL_PORT }}
78+
MAIL_USERNAME=${{ secrets.MAIL_USERNAME }}
79+
MAIL_PASSWORD=${{ secrets.MAIL_PASSWORD }}
80+
AWS_REGION=${{ secrets.AWS_REGION }}
81+
AWS_ACCESS_KEY=${{ secrets.AWS_ACCESS_KEY }}
82+
AWS_SECRET_KEY=${{ secrets.AWS_SECRET_KEY }}
83+
AWS_S3_BUCKET_NAME=${{ secrets.AWS_S3_BUCKET_NAME }}
84+
AI_SERVER_URL=${{ secrets.AI_SERVER_URL }}
85+
OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}
86+
KAKAO_API_KEY=${{ secrets.KAKAO_API_KEY }}
87+
KAKAO_REDIRECT_URI=${{ secrets.KAKAO_REDIRECT_URI }}
88+
CORS_ORIGIN=${{ secrets.CORS_CORIGIN}}
89+
EOF
90+
91+
- name: Create frontend/.env on server
92+
uses: appleboy/[email protected]
93+
with:
94+
host: ${{ secrets.SSH_HOST }}
95+
username: ${{ secrets.SSH_USER }}
96+
key: ${{ secrets.SSH_KEY }}
97+
script: |
98+
mkdir -p /home/ubuntu/classlog/frontend
99+
cat > /home/ubuntu/classlog/frontend/.env <<EOF
100+
NEXT_PUBLIC_API_BASE_URL=${{secrets.NEXT_PUBLIC_API_BASE_URL}}
101+
EOF
102+
103+
- name: Deploy containers
104+
uses: appleboy/[email protected]
105+
with:
106+
host: ${{ secrets.SSH_HOST }}
107+
username: ${{ secrets.SSH_USER }}
108+
key: ${{ secrets.SSH_KEY }}
109+
script: |
110+
cd /home/ubuntu/classlog
111+
export DOCKERHUB_USERNAME="${{ secrets.DOCKER_USERNAME }}"
112+
export IMAGE_TAG="${{ github.sha }}"
113+
114+
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${DOCKERHUB_USERNAME}" --password-stdin
115+
docker compose pull
116+
docker compose up -d
117+
docker image prune -f

.github/workflows/CI-backend.yml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
name: ClassLog CI - Backend
2+
on:
3+
pull_request:
4+
paths:
5+
- 'backend/**'
6+
branches: ["dev"]
7+
8+
permissions:
9+
contents: read
10+
checks: write
11+
pull-requests: write
12+
13+
jobs:
14+
backend-test:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v4
19+
20+
- name : Set up JDK 17
21+
uses: actions/setup-java@v4
22+
with:
23+
java-version: '17'
24+
distribution: 'temurin'
25+
26+
- name : Set up redis
27+
uses: supercharge/[email protected]
28+
with:
29+
redis-version: 7
30+
31+
- name: Grant execute permission for gradlew
32+
working-directory: ./backend
33+
run: chmod +x gradlew
34+
35+
- name: Build with Gradle
36+
working-directory: ./backend
37+
env:
38+
DB_USERNAME: ${{ secrets.DB_HOST }}
39+
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
40+
DB_NAME: ${{ secrets.DB_NAME }}
41+
DB_HOST: ${{ secrets.DB_HOST }}
42+
DB_PORT: ${{ secrets.DB_PORT }}
43+
REDIS_HOST: ${{ secrets.REDIS_HOST }}
44+
REDIS_PORT: ${{ secrets.REDIS_PORT }}
45+
JWT_SECRET: ${{ secrets.JWT_SECRET }}
46+
MAIL_HOST: ${{ secrets.MAIL_HOST }}
47+
MAIL_PORT: ${{ secrets.MAIL_PORT }}
48+
MAIL_USERNAME: ${{ secrets.MAIL_USERNAME }}
49+
MAIL_PASSWORD: ${{ secrets.MAIL_PASSWORD }}
50+
AWS_REGION: ${{ secrets.AWS_REGION }}
51+
AWS_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY }}
52+
AWS_SECRET_KEY: ${{ secrets.AWS_SECRET_KEY }}
53+
AI_SERVER_URL: ${{ secrets.AI_SERVER_URL }}
54+
AWS_S3_BUCKET_NAME: ${{ secrets.AWS_S3_BUCKET_NAME }}
55+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
56+
KAKAO_API_KEY: ${{ secrets.KAKAO_API_KEY }}
57+
KAKAO_REDIRECT_URI: ${{ secrets.KAKAO_REDIRECT_URI }}
58+
run: ./gradlew build
59+
60+
- name: ✅Passed
61+
if: success()
62+
run: echo "Backend Tests passed"
63+
64+
- name: ❌Failed
65+
if: failure()
66+
run: echo "Backend Tests failed"

.github/workflows/CI-frontend.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: ClassLog CI - Frontend
2+
on:
3+
pull_request:
4+
paths:
5+
- 'frontend/**'
6+
branches: ["dev"]
7+
8+
permissions:
9+
contents: read
10+
checks: write
11+
pull-requests: write
12+
13+
jobs:
14+
frontend-test:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v4
19+
20+
- name: Use Node.js
21+
uses: actions/setup-node@v3
22+
with:
23+
node-version: '20'
24+
25+
- name: Install dependencies
26+
working-directory: ./frontend
27+
run: npm install
28+
29+
- name: Build with npm
30+
working-directory: ./frontend
31+
env:
32+
NEXT_PUBLIC_API_BASE_URL : ${{ secrets.NEXT_PUBLIC_API_BASE_URL }}
33+
run: npm run build
34+
35+
- name: ✅Passed
36+
if: success()
37+
run: echo "Frontend Tests passed"
38+
39+
- name: ❌Failed
40+
if: failure()
41+
run: echo "Frontend Tests failed"

backend/docker-compose.yml

Lines changed: 0 additions & 56 deletions
This file was deleted.

backend/gradlew

100644100755
File mode changed.

backend/src/main/java/org/example/backend/BackendApplication.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public static void main(String[] args) {
3131
System.setProperty("AWS_S3_BUCKET_NAME", dotenv.get("AWS_S3_BUCKET_NAME"));
3232
System.setProperty("KAKAO_API_KEY", dotenv.get("KAKAO_API_KEY"));
3333
System.setProperty("KAKAO_REDIRECT_URI", dotenv.get("KAKAO_REDIRECT_URI"));
34-
System.setProperty("FRONTEND_ORIGIN",dotenv.get("FRONTEND_ORIGIN"));
34+
System.setProperty("CORS_ORIGIN",dotenv.get("CORS_ORIGIN"));
3535

3636
SpringApplication.run(BackendApplication.class, args);
3737
}

backend/src/main/java/org/example/backend/domain/user/controller/UserController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public ApiResponse<String> register(@Valid @RequestBody RegisterRequestDTO regis
3333
return ApiResponse.onSuccess("Register successfully");
3434
}
3535

36-
// 개인정보조회
36+
// 개인 정보 조회
3737
@GetMapping("/me")
3838
public ApiResponse<UserProfileResponseDTO> profile(){
3939
UserProfileResponseDTO response = userService.getProfile();

backend/src/main/java/org/example/backend/global/security/config/SecurityConfig.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.springframework.security.web.authentication.logout.LogoutFilter;
2323
import org.springframework.web.cors.CorsConfiguration;
2424
import org.springframework.web.cors.CorsConfigurationSource;
25+
import org.springframework.web.cors.CorsUtils;
2526
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
2627

2728
import java.util.Arrays;
@@ -36,8 +37,8 @@ public class SecurityConfig {
3637
private final UserRedisService userRedisService;
3738
private final UserRepository userRepository;
3839

39-
@Value("${frontend.origin}")
40-
private String frontendOrigin;
40+
@Value("${cors.origin}")
41+
private String[] corsOrigins;
4142

4243
//AuthenticationManger Bean 등록
4344
@Bean
@@ -65,16 +66,18 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
6566

6667
http
6768
.csrf((auth)->auth.disable()) // csrf disable
68-
.cors((cors) -> cors.configurationSource(corsConfigurationSource())) //cors 설정
69+
.cors(cors -> cors.configurationSource(corsConfigurationSource())) //cors 설정
6970
.formLogin((auth)->auth.disable()) //Form 로그인 방식 disable
7071
.logout((auth)-> auth.disable())
7172
.httpBasic((auth)-> auth.disable()) // http basic 인증방식 disable
7273
.authorizeHttpRequests((auth)->auth // 경로별 인가 작업
73-
.anyRequest().permitAll())
74-
// .requestMatchers("/api/users","/api/users/verify-email","/api/users/login","/api/users/password/temp").permitAll()
75-
// .anyRequest().authenticated())
74+
// .anyRequest().permitAll()
75+
.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
76+
.requestMatchers("/actuator/health").permitAll()
77+
.requestMatchers("/api/users","/api/users/verify-email","/api/users/login","/api/users/password/temp").permitAll()
78+
.anyRequest().authenticated())
7679
.addFilterBefore(new FilterExceptionHandler(), LogoutFilter.class) // 예외처리 필터
77-
.addFilterBefore(jwtFilter(),LoginFilter.class) // 미들웨어
80+
.addFilterBefore(jwtFilter(),UsernamePasswordAuthenticationFilter.class) // 미들웨어
7881
.addFilterAt(loginFilter, UsernamePasswordAuthenticationFilter.class) // custom한 login필터 추가
7982
.sessionManagement((session)->session // 세션설정
8083
.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
@@ -85,7 +88,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
8588
@Bean
8689
public CorsConfigurationSource corsConfigurationSource() {
8790
CorsConfiguration configuration = new CorsConfiguration();
88-
configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000", frontendOrigin));
91+
configuration.setAllowedOrigins(Arrays.asList(corsOrigins));
8992
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
9093
configuration.setAllowedHeaders(Arrays.asList("*"));
9194
configuration.setAllowCredentials(true);

0 commit comments

Comments
 (0)