From 2d8540b3e436a1f231c047d24d6bd652f135cce1 Mon Sep 17 00:00:00 2001 From: Yousung Jung Date: Thu, 11 Sep 2025 16:33:48 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=EB=B0=B0=ED=8F=AC=20=EB=AA=85=EB=A0=B9?= =?UTF-8?q?=EC=96=B4=20contribution.md=EC=97=90=20=EC=B6=94=EA=B0=80=20(#8?= =?UTF-8?q?3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CONTRIBUTING.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5cfc8727..ad2e0ed0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,4 +2,25 @@ ## Project root - IDE에서 Final-4team-icebang를 root로 열어야 합니다 - 현재 docker container가 없다면 docker container create 후 spring이 bootstrap되지 않습니다 - - 번거롭겠지만 spring boot restart 부탁드립니다. \ No newline at end of file + - 번거롭겠지만 spring boot restart 부탁드립니다. + +## 배포 방법 +### 공통 +1. main에 checkout +2. tag 발행 +3. remote (origin)에 tag push +### Spring +``` +git tag user-service-v0.0.1 +git push origin user-service-v0.0.1 or git push origin --tags + +``` +#### 네이밍 규칙 +- user-service-v* +### Fast api +``` +git tag pre-processing-v0.0.1 +git push origin pre-processing-v0.0.1 git push origin --tags +``` +#### 네이밍 규칙 +- pre-processing-v* From 0f238eda9461cdeae2d7b2da489d8de1d1d77d63 Mon Sep 17 00:00:00 2001 From: Jihu Kim Date: Thu, 11 Sep 2025 16:56:47 +0900 Subject: [PATCH 2/3] =?UTF-8?q?`@ConfigurationProperties`=EB=A1=9C=20?= =?UTF-8?q?=ED=83=80=EC=9E=85-=EC=95=88=EC=A0=84=ED=95=9C=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EA=B4=80=EB=A6=AC=20=EB=8F=84=EC=9E=85=20(#84)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: health관련 패키지 네이밍 및 파일 네이밍 변경 * feat(config): @ConfigurationProperties로 타입-안전한 설정 관리 도입 기존의 @Value나 하드코딩 방식은 오타에 취약하고, 설정값 누락 시 런타임 오류를 유발할 수 있는 타입 불안전성 문제가 있었습니다. 이를 해결하기 위해 @ConfigurationProperties를 사용하는 `FastApiProperties` 클래스를 도입하여 FastAPI 연동 설정을 중앙화하고, 애플리케이션 시작 시점에 설정값의 타입과 유효성을 검증하도록 개선했습니다. 이를 통해 잠재적인 런타임 장애를 원천 차단하고, 코드의 안정성과 유지보수성을 크게 향상시켰습니다. * refactor: Code Formatting --- .../HealthCheckController.java | 8 ++-- .../common/health/service/FastApiClient.java | 42 ------------------- .../health/service/HealthCheckService.java | 33 +++++++++++++++ .../config/properties/FastApiProperties.java | 25 +++++++++++ .../src/main/resources/application.yml | 8 +++- 5 files changed, 69 insertions(+), 47 deletions(-) rename apps/user-service/src/main/java/site/icebang/common/health/{api => controller}/HealthCheckController.java (80%) delete mode 100644 apps/user-service/src/main/java/site/icebang/common/health/service/FastApiClient.java create mode 100644 apps/user-service/src/main/java/site/icebang/common/health/service/HealthCheckService.java create mode 100644 apps/user-service/src/main/java/site/icebang/global/config/properties/FastApiProperties.java diff --git a/apps/user-service/src/main/java/site/icebang/common/health/api/HealthCheckController.java b/apps/user-service/src/main/java/site/icebang/common/health/controller/HealthCheckController.java similarity index 80% rename from apps/user-service/src/main/java/site/icebang/common/health/api/HealthCheckController.java rename to apps/user-service/src/main/java/site/icebang/common/health/controller/HealthCheckController.java index 8b65e7a0..62365cd6 100644 --- a/apps/user-service/src/main/java/site/icebang/common/health/api/HealthCheckController.java +++ b/apps/user-service/src/main/java/site/icebang/common/health/controller/HealthCheckController.java @@ -1,4 +1,4 @@ -package site.icebang.common.health.api; +package site.icebang.common.health.controller; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -6,13 +6,13 @@ import lombok.RequiredArgsConstructor; -import site.icebang.common.health.service.FastApiClient; +import site.icebang.common.health.service.HealthCheckService; @RestController @RequiredArgsConstructor public class HealthCheckController { - private final FastApiClient fastApiClient; + private final HealthCheckService healthCheckService; /** * Spring Boot와 FastAPI 서버 간의 연결 상태를 확인하는 헬스 체크 API @@ -21,7 +21,7 @@ public class HealthCheckController { */ @GetMapping("/ping") public ResponseEntity pingFastApi() { - String result = fastApiClient.ping(); + String result = healthCheckService.ping(); if (result.startsWith("ERROR")) { // FastAPI 연결 실패 시 503 Service Unavailable 상태 코드와 함께 에러 메시지 반환 diff --git a/apps/user-service/src/main/java/site/icebang/common/health/service/FastApiClient.java b/apps/user-service/src/main/java/site/icebang/common/health/service/FastApiClient.java deleted file mode 100644 index dceca69a..00000000 --- a/apps/user-service/src/main/java/site/icebang/common/health/service/FastApiClient.java +++ /dev/null @@ -1,42 +0,0 @@ -package site.icebang.common.health.service; - -import org.springframework.stereotype.Service; -import org.springframework.web.client.RestClientException; -import org.springframework.web.client.RestTemplate; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Service -@RequiredArgsConstructor -public class FastApiClient { - - // WebConfig에서 생성하고 타임아웃이 설정된 RestTemplate Bean을 주입받습니다. - private final RestTemplate restTemplate; - - // FastAPI 서버의 ping 엔드포인트 URL을 상수로 하드코딩합니다. - private static final String FASTAPI_PING_URL = "http://pre-processing-service:8000"; - - /** - * FastAPI 서버의 /ping 엔드포인트를 호출하여 연결을 테스트합니다. - * - * @return 연결 성공 시 FastAPI로부터 받은 응답, 실패 시 에러 메시지 - */ - public String ping() { - log.info("Attempting to connect to FastAPI server at: {}", FASTAPI_PING_URL); - - try { - // FastAPI 서버에 GET 요청을 보내고, 응답을 String으로 받습니다. - // WebConfig에 설정된 5초 타임아웃이 여기서 적용됩니다. - String response = restTemplate.getForObject(FASTAPI_PING_URL, String.class); - log.info("Successfully received response from FastAPI: {}", response); - return response; - } catch (RestClientException e) { - // RestClientException은 연결 실패, 타임아웃 등 모든 통신 오류를 포함합니다. - log.error( - "Failed to connect to FastAPI server at {}. Error: {}", FASTAPI_PING_URL, e.getMessage()); - return "ERROR: Cannot connect to FastAPI"; - } - } -} diff --git a/apps/user-service/src/main/java/site/icebang/common/health/service/HealthCheckService.java b/apps/user-service/src/main/java/site/icebang/common/health/service/HealthCheckService.java new file mode 100644 index 00000000..30dc6373 --- /dev/null +++ b/apps/user-service/src/main/java/site/icebang/common/health/service/HealthCheckService.java @@ -0,0 +1,33 @@ +package site.icebang.common.health.service; + +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import site.icebang.global.config.properties.FastApiProperties; + +@Slf4j +@Service +@RequiredArgsConstructor +public class HealthCheckService { + + private final RestTemplate restTemplate; + + private final FastApiProperties fastApiProperties; + + /** FastAPI 서버의 /ping 엔드포인트를 호출하여 연결을 테스트합니다. */ + public String ping() { + String url = fastApiProperties.getUrl() + "/ping"; + log.info("Attempting to connect to FastAPI server at: {}", url); + + try { + return restTemplate.getForObject(url, String.class); + } catch (RestClientException e) { + log.error("Failed to connect to FastAPI server at {}. Error: {}", url, e.getMessage()); + return "ERROR: Cannot connect to FastAPI"; + } + } +} diff --git a/apps/user-service/src/main/java/site/icebang/global/config/properties/FastApiProperties.java b/apps/user-service/src/main/java/site/icebang/global/config/properties/FastApiProperties.java new file mode 100644 index 00000000..24fa309d --- /dev/null +++ b/apps/user-service/src/main/java/site/icebang/global/config/properties/FastApiProperties.java @@ -0,0 +1,25 @@ +package site.icebang.global.config.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; +import org.springframework.validation.annotation.Validated; + +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +/** FastAPI 연동을 위한 설정값을 application.yml에서 바인딩하는 클래스 */ +@Getter +@Setter +@Component // Component로 등록하여 Spring이 Bean으로 관리하도록 함 +@ConfigurationProperties(prefix = "api.fastapi") // yml의 "api.fastapi" 접두사를 가진 설정을 매핑 +@Validated // 아래의 유효성 검사 어노테이션을 활성화 +public class FastApiProperties { + + /** FastAPI 서버의 기본 URL */ + @NotBlank // 값이 비어있을 수 없음을 검증 + private String url; + + /** API 호출 시 적용될 타임아웃 (밀리초 단위) */ + private int timeout = 5000; // 기본값 5초 설정 +} diff --git a/apps/user-service/src/main/resources/application.yml b/apps/user-service/src/main/resources/application.yml index d0357684..d6f68b0e 100644 --- a/apps/user-service/src/main/resources/application.yml +++ b/apps/user-service/src/main/resources/application.yml @@ -10,4 +10,10 @@ spring: mybatis: # Mapper XML 파일 위치 mapper-locations: classpath:mapper/**/*.xml - type-handlers-package: site.icebang.config.mybatis.typehandler \ No newline at end of file + type-handlers-package: site.icebang.config.mybatis.typehandler + +# 외부 API 연동을 위한 설정 섹션 +api: + fastapi: + url: http://pre-processing-service:8000 # FastAPI 서버의 기본 URL + timeout: 10000 # API 요청 타임아웃 (밀리초 단위) \ No newline at end of file From ebe212979a1653d2ff76a703e63a2a72b2369561 Mon Sep 17 00:00:00 2001 From: Yousung Jung Date: Thu, 11 Sep 2025 17:26:09 +0900 Subject: [PATCH 3/3] Https caddy set up (#85) --- docker/production/Caddyfile | 3 +++ docker/production/docker-compose.yml | 25 +++++++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 docker/production/Caddyfile diff --git a/docker/production/Caddyfile b/docker/production/Caddyfile new file mode 100644 index 00000000..e379de10 --- /dev/null +++ b/docker/production/Caddyfile @@ -0,0 +1,3 @@ +api.icebang.site { + reverse_proxy user-service:8080 +} \ No newline at end of file diff --git a/docker/production/docker-compose.yml b/docker/production/docker-compose.yml index 13866087..659934c7 100644 --- a/docker/production/docker-compose.yml +++ b/docker/production/docker-compose.yml @@ -1,13 +1,26 @@ version: "3.9" services: + caddy: + image: caddy:latest + container_name: caddy + restart: unless-stopped + ports: + - "80:80" + - "443:443" + volumes: + - ./Caddyfile:/etc/caddy/Caddyfile + - caddy_data:/data + - caddy_config:/config + networks: + - app-network + user-service: image: ghcr.io/kernel180-be12/final-4team-icebang/user-service:latest container_name: user-service restart: on-failure:3 ports: - - "80:8080" - - "443:8080" + - "8080:8080" networks: - app-network env_file: @@ -25,7 +38,11 @@ services: - app-network env_file: - .env.prod - + +volumes: + caddy_data: + caddy_config: + networks: app-network: - driver: bridge + driver: bridge \ No newline at end of file