From 67fc341fc8c70e18725d231e8f0bd6caac157584 Mon Sep 17 00:00:00 2001 From: htlee Date: Wed, 18 Mar 2026 08:25:33 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix(deploy):=20health=20check=20401=20?= =?UTF-8?q?=EB=8C=80=EC=9D=91=20+=20PressureCollector=20=EC=A4=91=EB=B3=B5?= =?UTF-8?q?=20=EB=B0=A9=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - deploy.yml: health check에서 HTTP 401/403도 정상 기동으로 판정 (인증 필요 엔드포인트) - health check timeout 30초 → 60초 - PressureCollector: save 전 existsByStationAndReadingTime으로 중복 확인 (JPA unique constraint 예외 → Hibernate 세션 오염 방지) Co-Authored-By: Claude Opus 4.6 (1M context) --- .gitea/workflows/deploy.yml | 9 ++++---- .../collector/sensor/PressureCollector.java | 23 ++++++++----------- .../sensor/PressureReadingRepository.java | 1 + 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 089ed48..a8ee76e 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -112,10 +112,11 @@ jobs: echo "--- Restarting kcg-backend ---" systemctl restart kcg-backend - # 기동 확인 (최대 30초) - for i in $(seq 1 30); do - if curl -sf http://localhost:8080/api/aircraft > /dev/null 2>&1; then - echo "Backend started successfully (${i}s)" + # 기동 확인 (최대 60초, 401=인증필요=정상 기동) + for i in $(seq 1 60); do + HTTP=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8080/api/aircraft 2>/dev/null) + if [ "$HTTP" = "200" ] || [ "$HTTP" = "401" ] || [ "$HTTP" = "403" ]; then + echo "Backend started successfully (${i}s, HTTP $HTTP)" exit 0 fi sleep 1 diff --git a/backend/src/main/java/gc/mda/kcg/collector/sensor/PressureCollector.java b/backend/src/main/java/gc/mda/kcg/collector/sensor/PressureCollector.java index cb27cff..a95e121 100644 --- a/backend/src/main/java/gc/mda/kcg/collector/sensor/PressureCollector.java +++ b/backend/src/main/java/gc/mda/kcg/collector/sensor/PressureCollector.java @@ -91,19 +91,16 @@ public class PressureCollector { try { // Open-Meteo 시간 형식: "2026-03-18T07:00" (Z 없음) → Z 추가 Instant readingTime = OffsetDateTime.parse(timeStr + "Z").toInstant(); - try { - repository.save(PressureReading.builder() - .station(station) - .lat(lat) - .lng(lng) - .pressureHpa(pressure) - .readingTime(readingTime) - .collectedAt(now) - .build()); - saved++; - } catch (Exception ignored) { - // unique constraint violation = 이미 존재, 무시 - } + if (repository.existsByStationAndReadingTime(station, readingTime)) continue; + repository.save(PressureReading.builder() + .station(station) + .lat(lat) + .lng(lng) + .pressureHpa(pressure) + .readingTime(readingTime) + .collectedAt(now) + .build()); + saved++; } catch (DateTimeParseException e) { log.debug("기압 시간 파싱 실패: {}", timeStr); } diff --git a/backend/src/main/java/gc/mda/kcg/domain/sensor/PressureReadingRepository.java b/backend/src/main/java/gc/mda/kcg/domain/sensor/PressureReadingRepository.java index 3c418c0..d6057d4 100644 --- a/backend/src/main/java/gc/mda/kcg/domain/sensor/PressureReadingRepository.java +++ b/backend/src/main/java/gc/mda/kcg/domain/sensor/PressureReadingRepository.java @@ -6,6 +6,7 @@ import java.time.Instant; import java.util.List; public interface PressureReadingRepository extends JpaRepository { + boolean existsByStationAndReadingTime(String station, Instant readingTime); List findByStationAndReadingTimeAfterOrderByReadingTimeAsc(String station, Instant since); List findByReadingTimeAfterOrderByReadingTimeAsc(Instant since); } -- 2.45.2 From b788ccbb05441279d0414dc913ef48e9a88f2693 Mon Sep 17 00:00:00 2001 From: htlee Date: Wed, 18 Mar 2026 08:31:10 +0900 Subject: [PATCH 2/2] =?UTF-8?q?fix(deploy):=20SSH=20=ED=98=B8=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20IP=20=EB=8F=99=EC=A0=81=20=EA=B0=90=EC=A7=80=20(ip?= =?UTF-8?q?=20route=20default=20gateway)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 하드코딩 172.17.0.1 → ip route에서 default gateway 자동 추출. CI 컨테이너가 services_devnet(172.18.x.x) 사용 시에도 정상 동작. Co-Authored-By: Claude Opus 4.6 (1M context) --- .gitea/workflows/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index a8ee76e..cfe576f 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -89,8 +89,8 @@ jobs: mkdir -p ~/.ssh echo "$DEPLOY_KEY" > ~/.ssh/id_deploy chmod 600 ~/.ssh/id_deploy - # Docker 컨테이너 → 호스트: bridge gateway(172.17.0.1) 경유 - DOCKER_HOST_IP=172.17.0.1 + # Docker 컨테이너 → 호스트: services_devnet gateway 경유 + DOCKER_HOST_IP=$(ip route | awk '/default/ {print $3}') ssh-keyscan $DOCKER_HOST_IP >> ~/.ssh/known_hosts 2>/dev/null || true SSH_CMD="ssh -i ~/.ssh/id_deploy -o StrictHostKeyChecking=no root@$DOCKER_HOST_IP" -- 2.45.2