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
2 changes: 2 additions & 0 deletions .github/workflows/ci-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ name: IssueDive Docker CI
on:
push:
branches: [ "dev" ] # dev 브랜치에 푸시될 때 실행
pull_request:
branches: [ "dev" ] # PR 보낼 때도 실행

jobs:
build-and-push:
Expand Down
11 changes: 9 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,15 @@ jobs:
docker pull ${{ secrets.DOCKERHUB_USERNAME }}/issuedive:latest

# 3. 기존에 실행 중인 앱 컨테이너가 있다면 중지하고 삭제 (최초 실행 시 오류가 나지 않도록 || true 추가)
docker stop issuedive-app || true
docker rm issuedive-app || true
# docker stop issuedive-app || true
# docker rm issuedive-app || true
# -> 8080 포트를 사용하는 기존 컨테이너를 찾아 중지 및 삭제 로직으로 변경
# 컨테이너 이름과 상관없이 포트 기준으로 찾기 때문에 더 안정적
CONTAINER_ID=$(docker ps -q --filter "publish=8080")
if [ -n "$CONTAINER_ID" ]; then
docker stop $CONTAINER_ID
docker rm $CONTAINER_ID
fi

# 4. 최신 이미지로 새로운 앱 컨테이너 실행
# 이전에 생성한 Docker 네트워크와 .env 파일을 사용합니다.
Expand Down
27 changes: 4 additions & 23 deletions src/main/java/com/issueDive/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package com.issueDive.config;

import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
Expand All @@ -32,12 +28,12 @@
@RequiredArgsConstructor
public class SecurityConfig {

private final CustomUserDetailsService userDetailsService; // DB 기반 인증
private final JwtAuthenticationFilter jwtAuthenticationFilter; // JWT 필터

@Value("${cors.allowed-origins}")
private String allowedOrigins;

// 공개적으로 접근 가능한 URL 목록
//
private static final String[] PUBLIC_URLS = {
"/swagger-ui/**",
"/v3/api-docs/**",
Expand Down Expand Up @@ -69,11 +65,9 @@ public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();

// 프론트엔드 서버 주소 허용
configuration.setAllowedOrigins(Arrays.asList("http://localhost:5173", "http://localhost:5174"));
configuration.setAllowedOrigins(Arrays.asList(allowedOrigins.split(",")));
// 모든 HTTP 메서드 허용
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
// 모든 헤더 허용
// configuration.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept", "Authorization"));
configuration.addAllowedHeader("*");
// 자격 증명(쿠키 등) 허용
configuration.setAllowCredentials(true);
Expand All @@ -88,19 +82,6 @@ public CorsConfigurationSource corsConfigurationSource() {
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

/*
@Bean
public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
UserDetails user = User.withUsername("test")
.password(passwordEncoder.encode("test"))
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}

*/

@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
return config.getAuthenticationManager();
Expand Down
53 changes: 53 additions & 0 deletions src/main/resources/application.properties.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# ===================================================================
# Example Configuration
# -------------------------------------------------------------------
# ? ??? ???? 'application.properties' ??? ??? ?,
# ??? ?? ??? ?? ?? <...> ??? ?????.
# 'application.properties' ??? .gitignore? ??? ????? ???.
# ===================================================================

# --- Database (MySQL) Settings ---
# ?????? ??? ?? URL, ??? ??, ????? ?????.
spring.datasource.url=jdbc:mysql://localhost:3306/issue_dive?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true
spring.datasource.username=<your-db-username>
spring.datasource.password=<your-db-password>
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# --- JPA & Hibernate Settings ---
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
# spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect

# --- Hikari Connection Pool Settings ---
spring.datasource.hikari.connection-test-query=SELECT 1
spring.datasource.hikari.maximum-pool-size=10

# --- Flyway Migration Settings ---
spring.flyway.enabled=true
spring.flyway.locations=classpath:db/migration
spring.flyway.baseline-on-migrate=true

# --- CORS Settings for Local Development ---
# ?? ?? ? ??? ????? ?????.
cors.allowed-origins=http://localhost:5173, http://localhost:5174

# --- Application Logging Settings ---
logging.level.root=INFO
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
logging.level.org.springframework.web=DEBUG
logging.level.com.example.issueDive=DEBUG
logging.file.name=logs/issueDive.log
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n

# --- Application Settings ---
spring.application.name=issueDive

# --- Jackson ---
# spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
# spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false

# --- K6 performance test Profile ---
#spring.profiles.active=performance
2 changes: 2 additions & 0 deletions src/test/resources/application-test.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
cors.allowed-origins=http://localhost:5173, http://localhost:5174

# =================================================================
# H2 ??????? MySQL ?? ??? ???? ?? DB? ???? ????? ??
# ? ?? ??? V1__init.sql? AUTO_INCREMENT ??? ?? ?? ?????.
Expand Down