diff --git a/Dockerfile-prod b/Dockerfile-prod index fdd5b00d..8583f81d 100644 --- a/Dockerfile-prod +++ b/Dockerfile-prod @@ -1,7 +1,12 @@ -# 1단계에서 만든 로컬 베이스 이미지를 사용 -FROM 127.0.0.1:18082/kamco-cd/base-java21-gdal:1.0 +# Stage 1: Build stage (gradle build는 Jenkins에서 이미 수행) +FROM eclipse-temurin:21-jre-jammy + +# GDAL 설치 +RUN apt-get update && apt-get install -y \ + gdal-bin \ + libgdal-dev \ + && rm -rf /var/lib/apt/lists/* -# 사용자 설정 (앱 별로 다를 수 있으므로 여기에 유지) ARG UID=1000 ARG GID=1000 @@ -18,6 +23,7 @@ COPY build/libs/ROOT.jar app.jar # 포트 노출 EXPOSE 8080 + # 애플리케이션 실행 # dev 프로파일로 실행 ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=prod", "app.jar"] diff --git a/Dockerfile-prod_bak b/Dockerfile-prod_bak new file mode 100644 index 00000000..3c330e8a --- /dev/null +++ b/Dockerfile-prod_bak @@ -0,0 +1,23 @@ +# Stage 1: Build stage (gradle build는 Jenkins에서 이미 수행) +FROM kamco-java-gdal:21 + +ARG UID=1000 +ARG GID=1000 + +RUN groupadd -g ${GID} kcomu \ + && useradd -u ${UID} -g ${GID} -m kcomu + +USER kcomu + +# 작업 디렉토리 설정 +WORKDIR /app + +# JAR 파일 복사 (Jenkins에서 빌드된 ROOT.jar) +COPY build/libs/ROOT.jar app.jar + +# 포트 노출 +EXPOSE 8080 + +# 애플리케이션 실행 +# dev 프로파일로 실행 +ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=prod", "app.jar"] diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 295c7ee5..433355c5 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -15,7 +15,7 @@ services: - SPRING_PROFILES_ACTIVE=dev - TZ=Asia/Seoul volumes: - - /kamco-nfs:/kamco-nfs + - /data:/kamco-nfs networks: - kamco-cds restart: unless-stopped diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml index 8c586f5c..dc6ef5ce 100644 --- a/docker-compose-prod.yml +++ b/docker-compose-prod.yml @@ -1,18 +1,31 @@ services: - kamco-changedetection-api: - build: - context: . - dockerfile: Dockerfile-prod - args: - UID: 1000 # manager01 UID - GID: 1000 # manager01 GID - image: kamco-changedetection-api:${IMAGE_TAG:-latest} - container_name: kamco-changedetection-api - user: "1000:1000" + nginx: + image: nginx:alpine + container_name: kamco-cd-api-nginx ports: - - "7100:8080" + - "12013:443" + volumes: + - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro + - ./nginx/conf.d:/etc/nginx/conf.d:ro + - /etc/ssl/certs/globalsign:/etc/ssl/certs/globalsign:ro + networks: + - kamco-cds + restart: unless-stopped + depends_on: + - kamco-cd-api + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost/health"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 10s + + kamco-cd-api: + image: kamco-api-app:260219 + container_name: kamco-cd-api + user: "1000:1000" environment: - - SPRING_PROFILES_ACTIVE=dev + - SPRING_PROFILES_ACTIVE=prod - TZ=Asia/Seoul volumes: - /data:/kamco-nfs diff --git a/nginx/README.md b/nginx/README.md new file mode 100644 index 00000000..2b3a6966 --- /dev/null +++ b/nginx/README.md @@ -0,0 +1,122 @@ +# Nginx HTTPS Configuration for KAMCO Change Detection API + +## SSL Certificate Setup + +### Required Files +GlobalSign SSL 인증서 파일들을 서버의 `/etc/ssl/certs/globalsign/` 디렉토리에 배치해야 합니다: + +``` +/etc/ssl/certs/globalsign/ +├── certificate.crt # SSL 인증서 파일 +├── private.key # 개인 키 파일 +└── ca-bundle.crt # CA 번들 파일 (중간 인증서) +``` + +### Certificate Installation Steps + +1. **디렉토리 생성** +```bash +sudo mkdir -p /etc/ssl/certs/globalsign +sudo chmod 755 /etc/ssl/certs/globalsign +``` + +2. **인증서 파일 복사** +```bash +sudo cp your-certificate.crt /etc/ssl/certs/globalsign/certificate.crt +sudo cp your-private.key /etc/ssl/certs/globalsign/private.key +sudo cp ca-bundle.crt /etc/ssl/certs/globalsign/ca-bundle.crt +``` + +3. **파일 권한 설정** +```bash +sudo chmod 644 /etc/ssl/certs/globalsign/certificate.crt +sudo chmod 600 /etc/ssl/certs/globalsign/private.key +sudo chmod 644 /etc/ssl/certs/globalsign/ca-bundle.crt +``` + +## Configuration Overview + +### Service Architecture +``` +Internet (HTTPS:12013) + ↓ +nginx (443 in container) + ↓ +kamco-changedetection-api (8080 in container) +``` + +### Key Features +- **HTTPS/TLS**: TLSv1.2, TLSv1.3 지원 +- **Port**: 외부 12013 → 내부 443 (nginx) +- **Domain**: aicd-api.e-kamco.com:12013 +- **Reverse Proxy**: kamco-changedetection-api:8080으로 프록시 +- **Security Headers**: HSTS, X-Frame-Options, X-Content-Type-Options 등 +- **Health Check**: /health 엔드포인트 + +## Deployment + +### Start Services +```bash +docker-compose -f docker-compose-prod.yml up -d +``` + +### Check Logs +```bash +# Nginx logs +docker logs kamco-cd-nginx + +# API logs +docker logs kamco-changedetection-api +``` + +### Verify Configuration +```bash +# Test nginx configuration +docker exec kamco-cd-nginx nginx -t + +# Check SSL certificate +docker exec kamco-cd-nginx openssl s_client -connect localhost:443 -servername aicd-api.e-kamco.com +``` + +### Access Service +```bash +# HTTPS Access +curl -k https://aicd-api.e-kamco.com:12013/monitor/health + +# Health Check +curl -k https://aicd-api.e-kamco.com:12013/health +``` + +## Troubleshooting + +### Certificate Issues +인증서 파일이 제대로 마운트되었는지 확인: +```bash +docker exec kamco-cd-nginx ls -la /etc/ssl/certs/globalsign/ +``` + +### Nginx Configuration Test +```bash +docker exec kamco-cd-nginx nginx -t +``` + +### Connection Test +```bash +# Check if nginx is listening +docker exec kamco-cd-nginx netstat -tlnp | grep 443 + +# Check backend connection +docker exec kamco-cd-nginx wget --spider http://kamco-changedetection-api:8080/monitor/health +``` + +## Configuration Files + +- `nginx/nginx.conf`: Main nginx configuration +- `nginx/conf.d/default.conf`: Server block with SSL and proxy settings +- `docker-compose-prod.yml`: Docker compose with nginx service + +## Notes + +- 인증서 파일명이 다를 경우 `nginx/conf.d/default.conf`에서 경로를 수정하세요 +- 인증서 갱신 시 nginx 컨테이너를 재시작하세요: `docker restart kamco-cd-nginx` +- 포트 12013이 방화벽에서 허용되어 있는지 확인하세요 \ No newline at end of file diff --git a/nginx/conf.d/default.conf b/nginx/conf.d/default.conf new file mode 100644 index 00000000..b5819658 --- /dev/null +++ b/nginx/conf.d/default.conf @@ -0,0 +1,60 @@ +upstream kamco_api { + server kamco-cd-api:8080; +} + +server { + listen 443 ssl http2; + server_name aicd-api.e-kamco.com; + + # GlobalSign SSL Certificate + ssl_certificate /etc/ssl/certs/globalsign/certificate.crt; + ssl_certificate_key /etc/ssl/certs/globalsign/private.key; + + # SSL Configuration + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + + # Security Headers + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + + # Client Body Size + client_max_body_size 100M; + + # Proxy Settings + location / { + proxy_pass http://kamco_api; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + + # Timeouts + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + + # WebSocket Support (if needed) + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + + # Health Check Endpoint + location /health { + access_log off; + return 200 "OK"; + add_header Content-Type text/plain; + } + + # Access and Error Logs + access_log /var/log/nginx/kamco-api-access.log; + error_log /var/log/nginx/kamco-api-error.log; +} \ No newline at end of file diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 00000000..a82807c5 --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,33 @@ +user nginx; +worker_processes auto; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json; + + include /etc/nginx/conf.d/*.conf; +} \ No newline at end of file diff --git a/src/main/java/com/kamco/cd/kamcoback/common/utils/FIleChecker.java b/src/main/java/com/kamco/cd/kamcoback/common/utils/FIleChecker.java index 3fb8faf4..b3ac5984 100644 --- a/src/main/java/com/kamco/cd/kamcoback/common/utils/FIleChecker.java +++ b/src/main/java/com/kamco/cd/kamcoback/common/utils/FIleChecker.java @@ -285,12 +285,20 @@ public class FIleChecker { List folderList = List.of(); - try (Stream stream = Files.walk(startPath, maxDepth)) { + log.info("[FIND_FOLDER] DIR : {} {} {} {}", dirPath, sortType, maxDepth, startPath); + int childDirCount = getChildFolderCount(startPath.toFile()); + log.info("[FIND_FOLDER] START_PATH_CHILD_DIR_COUNT : {}", childDirCount); + + try (Stream stream = Files.walk(startPath, maxDepth)) { folderList = stream .filter(Files::isDirectory) - .filter(p -> !p.toString().equals(dirPath)) + .filter( + p -> + !p.toAbsolutePath() + .normalize() + .equals(startPath.toAbsolutePath().normalize())) .map( path -> { int depth = path.getNameCount(); @@ -302,11 +310,6 @@ public class FIleChecker { boolean isShowHide = !parentFolderNm.equals("kamco-nfs"); // 폴더 리스트에 kamco-nfs 하위만 나오도록 처리 - // boolean isValid = - // !NameValidator.containsKorean(folderNm) - // && !NameValidator.containsWhitespaceRegex(folderNm) - // && !parentFolderNm.equals("kamco-nfs"); - File file = new File(fullPath); int childCnt = getChildFolderCount(file); String lastModified = getLastModified(file); @@ -358,22 +361,6 @@ public class FIleChecker { return getFolderAll(dirPath, "name", 1); } - public static List getFolderAll(String dirPath, String sortType) { - return getFolderAll(dirPath, sortType, 1); - } - - public static int getChildFolderCount(String dirPath) { - File directory = new File(dirPath); - File[] childFolders = directory.listFiles(File::isDirectory); - - int childCnt = 0; - if (childFolders != null) { - childCnt = childFolders.length; - } - - return childCnt; - } - public static int getChildFolderCount(File directory) { File[] childFolders = directory.listFiles(File::isDirectory); @@ -385,11 +372,6 @@ public class FIleChecker { return childCnt; } - public static String getLastModified(String dirPath) { - File file = new File(dirPath); - return dttmFormat.format(new Date(file.lastModified())); - } - public static String getLastModified(File file) { return dttmFormat.format(new Date(file.lastModified())); } diff --git a/src/main/java/com/kamco/cd/kamcoback/config/OpenApiConfig.java b/src/main/java/com/kamco/cd/kamcoback/config/OpenApiConfig.java index f8b1653b..e30fdf1f 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/OpenApiConfig.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/OpenApiConfig.java @@ -24,7 +24,7 @@ public class OpenApiConfig { @Value("${swagger.dev-url:https://kamco.dev-api.gs.dabeeo.com}") private String devUrl; - @Value("${swagger.prod-url:https://api.kamco.com}") + @Value("${swagger.prod-url:https://aicd-api.e-kamco.com:12013}") private String prodUrl; @Bean @@ -51,9 +51,9 @@ public class OpenApiConfig { servers.add(new Server().url("http://localhost:" + serverPort).description("로컬 서버")); // servers.add(new Server().url(prodUrl).description("운영 서버")); } else if ("prod".equals(profile)) { - // servers.add(new Server().url(prodUrl).description("운영 서버")); + servers.add(new Server().url(prodUrl).description("운영 서버")); servers.add(new Server().url("http://localhost:" + serverPort).description("로컬 서버")); - servers.add(new Server().url(devUrl).description("개발 서버")); + } else { servers.add(new Server().url("http://localhost:" + serverPort).description("로컬 서버")); servers.add(new Server().url(devUrl).description("개발 서버")); diff --git a/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java b/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java index aa3368ba..efc54ae8 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java @@ -104,14 +104,13 @@ public class SecurityConfig { "/api/change-detection/**", "/api/layer/map/**", "/api/layer/tile-url", - "/api/layer/tile-url-year") + "/api/layer/tile-url-year", + "/api/common-code/clazz") .permitAll() - // 로그인한 사용자만 가능 IAM .requestMatchers( "/api/user/**", "/api/my/menus", - "/api/common-code/**", "/api/members/*/password", "/api/training-data/label/**", "/api/training-data/review/**") diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java index e31b4046..ed092166 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java @@ -238,6 +238,8 @@ public class InferenceResultService { predRequestsAreas.setInput2_scene_path(modelTargetPath.getFilePath()); InferenceSendDto m1 = this.getModelInfo(req.getModel1Uuid()); + + log.info("[INFERENCE] Start m1 = {}", m1); m1.setPred_requests_areas(predRequestsAreas); // ai 추론 실행 api 호출 @@ -429,7 +431,7 @@ public class InferenceResultService { sendDto.setCls_model_path(cdClsModelPath); sendDto.setCls_model_version(modelInfo.getModelVer()); sendDto.setCd_model_type(modelType); - sendDto.setPriority(modelInfo.getPriority()); + sendDto.setPriority(5d); return sendDto; } diff --git a/src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java b/src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java index a8dfb4d9..982aac27 100644 --- a/src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java +++ b/src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java @@ -336,10 +336,9 @@ public class MapSheetMngService { public FoldersDto getFolderAll(SrchFoldersDto srchDto) { - Path startPath = Paths.get(syncRootDir + srchDto.getDirPath()); String dirPath = syncRootDir + srchDto.getDirPath(); - String sortType = "name desc"; + log.info("[FIND_FOLDER] DIR : {}", dirPath); List folderList = FIleChecker.getFolderAll(dirPath).stream() .filter(dir -> dir.getIsValid().equals(true)) diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/trainingdata/TrainingDataLabelRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/trainingdata/TrainingDataLabelRepositoryImpl.java index 82f73c5d..15173730 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/trainingdata/TrainingDataLabelRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/trainingdata/TrainingDataLabelRepositoryImpl.java @@ -307,6 +307,10 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport queryFactory .select(labelingAssignmentEntity.count()) .from(labelingAssignmentEntity) + .innerJoin(mapSheetAnalInferenceEntity) + .on( + labelingAssignmentEntity.analUid.eq(mapSheetAnalInferenceEntity.id), + mapSheetAnalInferenceEntity.analState.ne(LabelMngState.FINISH.getId())) .where(labelingAssignmentEntity.workerUid.eq(userId)) .fetchOne(); @@ -327,6 +331,10 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport queryFactory .select(labelingAssignmentEntity.count()) .from(labelingAssignmentEntity) + .innerJoin(mapSheetAnalInferenceEntity) + .on( + labelingAssignmentEntity.analUid.eq(mapSheetAnalInferenceEntity.id), + mapSheetAnalInferenceEntity.analState.ne(LabelMngState.FINISH.getId())) .where( labelingAssignmentEntity.workerUid.eq(userId), labelingAssignmentEntity.workState.eq("ASSIGNED")) @@ -355,6 +363,10 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport queryFactory .select(labelingAssignmentEntity.count()) .from(labelingAssignmentEntity) + .innerJoin(mapSheetAnalInferenceEntity) + .on( + labelingAssignmentEntity.analUid.eq(mapSheetAnalInferenceEntity.id), + mapSheetAnalInferenceEntity.analState.ne(LabelMngState.FINISH.getId())) .where( labelingAssignmentEntity.workerUid.eq(userId), labelingAssignmentEntity.workState.in( diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/trainingdata/TrainingDataReviewRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/trainingdata/TrainingDataReviewRepositoryImpl.java index 23b43d3a..794fa8b1 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/trainingdata/TrainingDataReviewRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/trainingdata/TrainingDataReviewRepositoryImpl.java @@ -314,6 +314,10 @@ public class TrainingDataReviewRepositoryImpl extends QuerydslRepositorySupport queryFactory .select(labelingAssignmentEntity.count()) .from(labelingAssignmentEntity) + .innerJoin(mapSheetAnalInferenceEntity) + .on( + labelingAssignmentEntity.analUid.eq(mapSheetAnalInferenceEntity.id), + mapSheetAnalInferenceEntity.analState.ne(LabelMngState.FINISH.getId())) .where(labelingAssignmentEntity.inspectorUid.eq(userId)) .fetchOne(); @@ -334,6 +338,10 @@ public class TrainingDataReviewRepositoryImpl extends QuerydslRepositorySupport queryFactory .select(labelingAssignmentEntity.count()) .from(labelingAssignmentEntity) + .innerJoin(mapSheetAnalInferenceEntity) + .on( + labelingAssignmentEntity.analUid.eq(mapSheetAnalInferenceEntity.id), + mapSheetAnalInferenceEntity.analState.ne(LabelMngState.FINISH.getId())) .where( labelingAssignmentEntity.inspectorUid.eq(userId), labelingAssignmentEntity.inspectState.eq("UNCONFIRM")) @@ -362,6 +370,10 @@ public class TrainingDataReviewRepositoryImpl extends QuerydslRepositorySupport queryFactory .select(labelingAssignmentEntity.count()) .from(labelingAssignmentEntity) + .innerJoin(mapSheetAnalInferenceEntity) + .on( + labelingAssignmentEntity.analUid.eq(mapSheetAnalInferenceEntity.id), + mapSheetAnalInferenceEntity.analState.ne(LabelMngState.FINISH.getId())) .where( labelingAssignmentEntity.inspectorUid.eq(userId), labelingAssignmentEntity.inspectState.in("COMPLETE", "EXCEPT"), diff --git a/src/main/java/com/kamco/cd/kamcoback/scheduler/service/MapSheetInferenceJobService.java b/src/main/java/com/kamco/cd/kamcoback/scheduler/service/MapSheetInferenceJobService.java index 328a3d50..3410ddfb 100644 --- a/src/main/java/com/kamco/cd/kamcoback/scheduler/service/MapSheetInferenceJobService.java +++ b/src/main/java/com/kamco/cd/kamcoback/scheduler/service/MapSheetInferenceJobService.java @@ -354,7 +354,7 @@ public class MapSheetInferenceJobService { Paths.get(progressDto.getCdModelClsPath(), progressDto.getCdModelClsFileName()).toString()); m.setCls_model_version(progressDto.getClsModelVersion()); m.setCd_model_type(type); - m.setPriority(progressDto.getPriority()); + m.setPriority(5d); // log.info("InferenceSendDto={}", m); // 추론 실행 api 호출 diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 498806e7..d686e70d 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -97,8 +97,8 @@ file: sync-tmp-dir: /kamco-nfs/requests/temp # image upload temp dir #sync-tmp-dir: ${file.sync-root-dir}/tmp sync-file-extention: tfw,tif - sync-auto-exception-start-year: 2024 - sync-auto-exception-before-year-cnt: 3 +# sync-auto-exception-start-year: 2024 +# sync-auto-exception-before-year-cnt: 3 #dataset-dir: D:/kamco-nfs/model_output/ dataset-dir: /kamco-nfs/model_output/export/ # 마운트경로 AI 추론결과 diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index cce8f913..6a3911b4 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -74,8 +74,8 @@ file: #sync-root-dir: /kamco-nfs/images/ sync-tmp-dir: ${file.sync-root-dir}/tmp/ sync-file-extention: tfw,tif - sync-auto-exception-start-year: 2025 - sync-auto-exception-before-year-cnt: 3 +# sync-auto-exception-start-year: 2025 +# sync-auto-exception-before-year-cnt: 3 dataset-dir: C:/Users/gypark/kamco-nfs/dataset/ #dataset-dir: /kamco-nfs/dataset/export/ @@ -88,6 +88,7 @@ file: pt-path: /kamco-nfs/ckpt/classification/ pt-FileName: v5-best.pt + dataset-response: /kamco-nfs/dataset/response/ inference: url: http://10.100.0.11:8000/jobs @@ -106,5 +107,6 @@ training-data: layer: geoserver-url: https://kamco.geo-dev.gs.dabeeo.com - path: /geoserver/cd/gwc/service/ + wms-path: geoserver/cd + wmts-path: geoserver/cd/gwc/service workspace: cd diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 5b8cd490..f4d0f0c0 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -16,13 +16,9 @@ spring: format_sql: true # ⚠️ 선택 - SQL 포맷팅 (가독성) jdbc: batch_size: 1000 # ✅ 추가 (JDBC batch) - open-in-view: false - mvc: - async: - request-timeout: 300s # 5분 (예: 30s, 120s, 10m 등도 가능) datasource: - url: jdbc:postgresql://127.0.0.1:15432/kamco_cds + url: jdbc:postgresql://kamco-cd-postgis:5432/kamco_cds #url: jdbc:postgresql://localhost:15432/kamco_cds username: kamco_cds password: kamco_cds_Q!W@E#R$ @@ -64,11 +60,15 @@ token: refresh-cookie-name: kamco # 개발용 쿠키 이름 refresh-cookie-secure: true # 로컬 http 테스트면 false +springdoc: + swagger-ui: + persist-authorization: true # 스웨거 새로고침해도 토큰 유지, 로컬스토리지에 저장 + logging: level: root: INFO - org.springframework.web: DEBUG - org.springframework.security: DEBUG + org.springframework.web: INFO + org.springframework.security: INFO # 헬스체크 노이즈 핵심만 다운 org.springframework.security.web.FilterChainProxy: INFO @@ -84,12 +84,9 @@ mapsheet: baseurl: /app/detect/result #현재사용안함 file: - #sync-root-dir: D:/kamco-nfs/images/ sync-root-dir: /kamco-nfs/images/ - sync-tmp-dir: ${file.sync-root-dir}/tmp # image upload temp dir + sync-tmp-dir: /kamco-nfs/repo/tmp # image upload temp dir sync-file-extention: tfw,tif - sync-auto-exception-start-year: 2025 - sync-auto-exception-before-year-cnt: 3 #dataset-dir: D:/kamco-nfs/model_output/ #변경 model_output dataset-dir: /kamco-nfs/model_output/export/ # 마운트경로 AI 추론결과 @@ -100,9 +97,8 @@ file: model-tmp-dir: ${file.model-dir}tmp/ model-file-extention: pth,json,py - pt-path: /kamco-nfs/ckpt/model/v6-cls-checkpoints/ + pt-path: /kamco-nfs/ckpt/v6-cls-checkpoints/ pt-FileName: yolov8_6th-6m.pt - dataset-response: /kamco-nfs/dataset/response/ inference: diff --git a/src/main/resources/application-prod.yml_bak b/src/main/resources/application-prod.yml_bak new file mode 100644 index 00000000..894a055b --- /dev/null +++ b/src/main/resources/application-prod.yml_bak @@ -0,0 +1,120 @@ +spring: + config: + activate: + on-profile: prod + + jpa: + show-sql: true + hibernate: + ddl-auto: validate + properties: + hibernate: + default_batch_fetch_size: 100 # ✅ 성능 - N+1 쿼리 방지 + order_updates: true # ✅ 성능 - 업데이트 순서 정렬로 데드락 방지 + order_inserts: true + use_sql_comments: true # ⚠️ 선택 - SQL에 주석 추가 (디버깅용) + format_sql: true # ⚠️ 선택 - SQL 포맷팅 (가독성) + jdbc: + batch_size: 1000 # ✅ 추가 (JDBC batch) + + datasource: + url: jdbc:postgresql://kamco-cd-postgis:5432/kamco_cds + #url: jdbc:postgresql://localhost:15432/kamco_cds + username: kamco_cds + password: kamco_cds_Q!W@E#R$ + hikari: + minimum-idle: 10 + maximum-pool-size: 20 + connection-timeout: 60000 # 60초 연결 타임아웃 + idle-timeout: 300000 # 5분 유휴 타임아웃 + max-lifetime: 1800000 # 30분 최대 수명 + leak-detection-threshold: 60000 # 연결 누수 감지 + + transaction: + default-timeout: 300 # 5분 트랜잭션 타임아웃 + + data: + redis: + host: 127.0.0.1 + port: 16379 + password: kamco + + servlet: + multipart: + enabled: true + max-file-size: 4GB + max-request-size: 4GB + file-size-threshold: 10MB + +server: + tomcat: + max-swallow-size: 4GB + max-http-form-post-size: 4GB + +jwt: + secret: "kamco_token_9b71e778-19a3-4c1d-97bf-2d687de17d5b" + access-token-validity-in-ms: 86400000 # 1일 + refresh-token-validity-in-ms: 604800000 # 7일 + +token: + refresh-cookie-name: kamco # 개발용 쿠키 이름 + refresh-cookie-secure: true # 로컬 http 테스트면 false + +logging: + level: + root: INFO + org.springframework.web: INFO + org.springframework.security: INFO + + # 헬스체크 노이즈 핵심만 다운 + org.springframework.security.web.FilterChainProxy: INFO + org.springframework.security.web.authentication.AnonymousAuthenticationFilter: INFO + org.springframework.security.web.authentication.Http403ForbiddenEntryPoint: INFO + org.springframework.web.servlet.DispatcherServlet: INFO + + +mapsheet: + upload: + skipGdalValidation: true + shp: + baseurl: /app/detect/result #현재사용안함 + +file: + #sync-root-dir: D:/kamco-nfs/images/ + sync-root-dir: /kamco-nfs/images/ + sync-tmp-dir: ${file.sync-root-dir}/tmp # image upload temp dir + sync-file-extention: tfw,tif + sync-auto-exception-start-year: 2025 + sync-auto-exception-before-year-cnt: 3 + + #dataset-dir: D:/kamco-nfs/model_output/ #변경 model_output + dataset-dir: /kamco-nfs/model_output/export/ # 마운트경로 AI 추론결과 + dataset-tmp-dir: ${file.dataset-dir}tmp/ + + #model-dir: D:/kamco-nfs/ckpt/model/ + model-dir: /kamco-nfs/ckpt/model/ # 학습서버에서 트레이닝한 모델업로드경로 + model-tmp-dir: ${file.model-dir}tmp/ + model-file-extention: pth,json,py + + pt-path: /kamco-nfs/ckpt/model/v6-cls-checkpoints/ + pt-FileName: yolov8_6th-6m.pt + +inference: + url: http://127.0.0.1:8000/jobs + batch-url: http://127.0.0.1:8000/batches + geojson-dir: /kamco-nfs/requests/ # 학습서버에서 트레이닝한 모델업로드경로 + jar-path: /kamco-nfs/repo/jar/shp-exporter.jar # 추론실행을 위한 파일생성경로 + inference-server-name: server1,server2,server3,server4 + +gukyuin: + url: http://127.0.0.1:5301 + cdi: ${gukyuin.url}/api/kcd/cdi + +training-data: + geojson-dir: /kamco-nfs/dataset/request/ + +layer: + geoserver-url: https://kamco.geo-dev.gs.dabeeo.com + wms-path: geoserver/cd + wmts-path: geoserver/cd/gwc/service + workspace: cd