프로퍼티 레퍼런스
이 문서는 배포되는 실물 설정 템플릿(
*.properties)에서 재생성됩니다. 템플릿의 정본은plantpulse-datalake-cli/config/templates이고, 호스트의/etc/kopens/conf가 그 자리로 바인드 마운트됩니다. 어느 템플릿이 어디로 렌더되는지는config/render.map한 장이 정합니다. 로딩 우선순위의 정본은plantpulse-core/src/plantpulse/core/engine/utils/PropertiesUtils.java입니다.키를 추가·삭제·개명했다면 이 문서가 아니라 템플릿이 정본입니다. 문서를 손으로 채우지 말고 템플릿에서 다시 뽑으세요. 각 표의 「기본값」은 템플릿에 적힌 그대로이며,
${PP_XXX}는 렌더할 때 환경변수 값으로 치환되는 자리입니다.
값이 어디서 와서 어디로 가나
| 무엇 | 어디 | 권한 | 바꾸는 법 |
|---|---|---|---|
| 비밀 — DB 비밀번호 · API 키 | /etc/kopens/plantpulse-platform.env | 0600 | bin/passwd.sh (서버 계정 변경 → 사이드카 갱신 → 재렌더 → 재시작을 한 명령으로) |
이 박스 고유 값 — PP_MASTER_IP · Kafka 광고 주소 · 이미지 태그 핀 | /etc/kopens/platform.node.env | 0600 | 직접 편집 후 bin/restart-datalake.sh |
| 설정 — 포트 · 이미지 태그 · 로케일 · 데이터 경로 | repo 의 .env (.env.example 만 커밋) | — | 직접 편집 후 재시작 |
엔진 설정의 «줄» — postgresql.conf 파라미터, Kafka 보존, Aster TSDB 힙 | /etc/kopens/conf/<파일>.template | — | 템플릿 편집 → pd config render → pd restart <서비스> |
pd start 는 매번 템플릿을 렌더해 각 컴포넌트의 설정 자리로 덮어씁니다. cassandra.yaml
· postgresql.conf · kafka.properties 를 열어 고쳐도 다음 기동에 원래대로 돌아갑니다.
고칠 곳은 템플릿입니다 → 설정 바꾸는 법
비밀 파일은 split install 때 앱 노드로 복사되고, 노드 파일은 복사되면 안 됩니다.
합치면 한 박스의 PP_MASTER_IP 와 이미지 태그 핀이 다른 박스로 샙니다.
형식은 VAR=값 한 가지입니다 — export 를 붙이면 env_file: 이 파싱하지 못합니다.
템플릿 변경 표준 절차
호스트에서 값을 고치고, 컨테이너 안의 pd 로 반영합니다.
vi /etc/kopens/conf/<템플릿> # 1. 호스트의 템플릿을 고칩니다
docker exec plantpulse-datalake pd doctor # 2. 검사 (선택)
docker exec plantpulse-datalake pd config diff # 3. 무엇이 달라지는지 봅니다
docker exec plantpulse-datalake pd config render # 4. 실제로 씁니다
docker exec plantpulse-datalake pd restart <서비스> # 5. 재시작
docker exec plantpulse-datalake pd status # 6. 확인
pd config render는 설정 파일을 다시 쓸 뿐 서비스를 재시작하지 않습니다. 재시작 전까지는 새 설정이 디스크에만 있고 옛 프로세스가 살아 있습니다. 그래서 4번과 5번이 한 세트입니다.
설정 파일 로딩 우선순위
웹 애플리케이션(server / batch / cep / sql / data-gateway)은 다음 순서로 설정 파일을 찾는다. 구현은 PropertiesUtils.readExternalFirst() 다.
-Dpp.conf.dir시스템 프로퍼티로 지정한 디렉토리 (상수PropertiesUtils.CONF_DIR_SYSTEM_PROPERTY = "pp.conf.dir")${catalina.base}/../config— 모듈의config/디렉토리- 웹앱 클래스패스 (WAR 에 포함된 기본값) — fallback
외부 파일은 UTF-8 로 읽는다. 외부 설정이 정상 로드되면 기동 로그에 다음이 출력된다.
Properties loaded from external conf: <절대경로>
외부 파일 읽기에 실패하면 error 로그를 남기고 클래스패스로 fallback 한다.
로깅 설정(log4j2.xml)도 같은 체인으로 외부화되어 있다(자가 시딩 — 외부 파일이 없으면 WAR 기본값을 모듈 config/log4j2.xml 로 1회 복사 후 사용). 적용 시 기동 로그에 Logging reconfigured from external conf: <절대경로> 가 출력된다. 로그 레벨 변경은 모듈 config/log4j2.xml 수정 후 재시작으로 적용하며 WAR 재배포에도 보존된다. 상세는 설정 및 배포 가이드 참고.
주의: 웹앱 내부 파일(
server/webapps/ROOT/WEB-INF/classes/등)은 직접 수정하지 마라 — WAR 재배포 시 사라진다.
${ENV:기본값} 치환은 두 번 일어난다
템플릿의 ${PP_XXX} / ${PP_XXX:기본값} 표기는 두 시점에서 해석된다.
| 시점 | 주체 | 동작 |
|---|---|---|
| 기동 시 | pd config render | 사이드카(plantpulse-platform.env · platform.node.env)와 컨테이너 환경으로 치환. 순서는 환경변수 → :기본값 → 원본 유지. 중첩 placeholder 미지원 |
| 런타임 | PropertiesUtils.resolveEnvPlaceholders | 로드한 Properties 의 모든 값에 대해 ${ENV_VAR[:default]} 를 다시 해석 |
즉 배포 후 남아 있는 ${...} 도 프로세스의 환경변수로 채워질 수 있다. Docker -e VAR=... 주입이 템플릿 기본값보다 우선하는 이유다.
사이드카에 없는 PP_* 변수 (템플릿 기본값이 그대로 적용됨)
아래 변수들은 템플릿이 ${PP_XXX:기본값} 으로 참조하지만 사이드카 파일이 정의하지 않는다. 따라서 별도 주입이 없으면 항상 템플릿 기본값이 쓰인다.
PP_EXTERNAL_DB_PASSWORD · PP_MAIL_SMTP_HOST · PP_MAIL_SMTP_PORT · PP_MAIL_SMTP_AUTH · PP_MAIL_SMTP_USER · PP_MAIL_SMTP_PASSWORD · PP_MAIL_SMTP_STARTTLS · PP_DIAGNOSTIC_EMAIL
PP_AI_* 는 이 목록에 있었지만 이제 아무 일도 하지 않습니다PP_AI_OPENAI_* · PP_AI_MCP_* · PP_AI_CHAT_ENABLED 를 주면 조용히 무시됩니다. 그 값들을
읽던 층이 2026-09-18 에 없어졌습니다 — AI 설정을 보십시오.
PP_STORAGE_PASSWORD · PP_METASTORE_PASSWORD 는 이 목록에 있었지만 «없는 변수» 입니다템플릿도 사이드카도 그 이름을 참조하지 않습니다. 실제 이름은 이렇습니다 —
| 무엇 | 실제 변수 |
|---|---|
| 시계열 저장소(Aster TSDB) 접속 | PP_CASSANDRA_HOST · PP_CASSANDRA_PORT · PP_CASSANDRA_USER · 🔑 PP_CASSANDRA_PASSWORD |
| 메타스토어(PostgreSQL) 접속 | PP_POSTGRES_HOST · PP_POSTGRES_PORT · PP_PG_USER · 🔑 PP_PG_PASSWORD |
🔴 PP_MAIL_SMTP_* 도 이제 아무 일도 하지 않는다. 메일 설정의 정본은 pp.mm_config 이고, 값은 콘솔(/config/index)이나 그 표에서 바꾼다 — 메일 설정. 한 벌로 맞아야 하는 값(호스트 · 포트 · 인증 여부 · 계정)을 한 곳에서만 고치게 한 것이 이 이관의 이유이기도 하다.
서버 관리 설정 5종
ConfigTemplates.SERVER_CONFIGS 배열이 정의하는, plantpulse-server/config/ 로 배포되는 설정 파일은 5개다.
| # | 템플릿 | 배포 경로 |
|---|---|---|
| 1 | plantpulse-engine.properties | /plantpulse-server/config/plantpulse-engine.properties |
| 2 | plantpulse-storage.properties | /plantpulse-server/config/plantpulse-storage.properties |
| 3 | plantpulse-mq.properties | /plantpulse-server/config/plantpulse-mq.properties |
세 파일은 PropertiesLoader.load() 가 한꺼번에 읽고(engine/mq/storage), 타입드 설정 빈 EngineConfig · StorageConfig · MqConfig 를 재구성한다.
pp.mm_config 가 정본이다plantpulse-mail.properties 와 plantpulse-ai.properties 는 2026-09-17 에 삭제됐고, 외부 설정 디렉터리에 남아 있을 수 있는 옛 사본을 읽어 표로 옮기던 경로도 2026-09-18 에 통째로 없어졌다. 즉 그 파일을 만들어 두어도 아무것도 읽지 않는다.
값이 들어가는 길은 콘솔과 PostgreSQL pp.mm_config 둘뿐이다. 키 이름과 기본값의 정본은 코드의 MailConfigKeys · AiConfigKeys 이고, 표에 행이 없는 키는 그 기본값으로 읽힌다 — 아래 두 절의 키 표는 그대로 유효하다.
application.properties (제거됨)
application.properties 는 2026.06 에 제거됐다. 이 파일을 읽는 코드가 없으며(전 리포 사용처 0건), 기존 항목은 다음으로 이관됐다.
- 테마 / 홈페이지 등 콘솔 동작 설정 → 콘솔 시스템 > 설정 관리 (PostgreSQL
mm_config테이블) alarm.duplicate.check.minutes→plantpulse-engine.properties계열 (EngineConfig가 읽는다)
plantpulse-engine.properties
경로: plantpulse-server/config/plantpulse-engine.properties · 템플릿: template/plantpulse-engine.properties
데이터 처리 엔진의 핵심 동작을 제어한다.
비동기 / 파이프라인
| 프로퍼티 | 기본값 | 치환 | 설명 (템플릿 주석) |
|---|---|---|---|
engine.async.parallelism | 256 | — | Async worker pool parallelism (total cores ~= 256) |
engine.pipeline.threads | 36 | — | 파이프라인 스레드 수 |
engine.pipeline.ratelimit | 40000 | — | 파이프라인 초당 처리 상한 (rate limit) |
engine.pipeline.queue.size | 1200000 | — | 파이프라인 큐 크기 (백프레셔 한계) |
engine.pipeline.queue.o3.delay | 50 | — | 순서 어긋난(out-of-order) 데이터 허용 지연 (ms) |
engine.pipeline.task.mode | SINGLE | — | 태스크 실행 모드 (SINGLE / PARALLEL) |
NTP
| 프로퍼티 | 기본값 | 치환 | 설명 |
|---|---|---|---|
engine.ntpdate.server.ip | 127.0.0.1 | — | NTP 서버 IP |
engine.ntpdate.sync | false | — | 부팅 시 NTP 동기화 수행 여부 |
스트림 / CEP
| 프로퍼티 | 기본값 | 치환 | 설명 |
|---|---|---|---|
engine.stream.processor | DIRECT | — | 스트림 처리 모드 (DIRECT/BUFFERED) |
engine.cep.server.ip | 127.0.0.1 | ${PP_CEP_HOST:127.0.0.1} | CEP 서버 IP |
engine.cep.server.port | 7400 | ${PP_CEP_CONNECT_PORT:7400} | CEP 서버 포트 (protocol 에 자동 정렬: http→7400, https→7401) |
engine.cep.server.protocol | http | ${PP_CEP_PROTOCOL:http} | CEP 프로토콜. 내부 통신 기본 http, 분산/컨테이너는 https |
engine.cep.server.api.key | (없음) | ${PP_CEP_API_KEY} | CEPClient X-API-Key 헤더용. CEP 서버 cep.api.key 와 일치해야 함 |
스트리밍 메시지 전달
| 프로퍼티 | 기본값 | 치환 | 설명 |
|---|---|---|---|
engine.streaming.messaging.warning.ms | 5000 | — | 메시지 전달 지연 경고 (ms) |
engine.streaming.messaging.timeout.ms | 10000 | — | 메시지 전달 타임아웃 (ms) |
engine.streaming.messaging.timeout.store.type | FILE_QUEUE | — | 타임아웃 메시지 저장 방식 (FILE_QUEUE/MEMORY) |
engine.streaming.messaging.timeout.recovery.type | DB | — | 타임아웃 메시지 복구 소스 (DB/FILE) |
잡 워커 스레드
| 프로퍼티 | 기본값 | 치환 | 설명 |
|---|---|---|---|
engine.job.thread.asset | 8 | — | 에셋 잡 스레드 수 |
engine.job.thread.point | 8 | — | 포인트 잡 스레드 수 |
DDS
| 프로퍼티 | 기본값 | 치환 | 설명 |
|---|---|---|---|
engine.dds.enabled | true | — | DDS 전역 활성화 |
engine.dds.data.tag.enabled | true | — | 태그 데이터 DDS 발행 |
engine.dds.data.asset.enabled | true | — | 에셋 데이터 DDS 발행 |
이상 탐지 / 데이터플로우
| 프로퍼티 | 기본값 | 치환 | 설명 |
|---|---|---|---|
engine.data.anomaly.enabled | false | — | 이상 탐지 활성화 (외부 서비스 연동) |
engine.data.anomaly.url | https://127.0.0.1:8970 | — | 이상 탐지 서비스 URL |
engine.dataflow.class | plantpulse.core.engine.pipeline.dataflow.BaseDataFlow | — | 데이터플로우 구현 클래스 |
engine.dataflow.server-timestamp.override | false | — | 서버 타임스탬프 강제 여부 (true: 수집 시각, false: 원본) |
engine.dataflow.negative-timestamp.override | true | — | 음수 타임스탬프 보정 여부 |
engine.factory.model.updater.class | plantpulse.core.engine.model.impl.DefaultFactoryMetaModelUpdater | — | 팩토리 메타모델 업데이터 |
engine.event.handler.class | plantpulse.core.engine.event.DefaultEventHanlder | — | 이벤트 핸들러 구현 (클래스명 오타 Hanlder 는 실제 클래스명 그대로) |
engine.javagc.enabled | false | — | 명시적 System.gc() 호출 허용 여부 |
Flow 엔진
| 프로퍼티 | 기본값 | 치환 | 설명 |
|---|---|---|---|
flow.debug.execution.log | false | — | 노드 실행 INFO 로그. 디버깅 세션에만 true |
flow.stats.prune.interval.ms | 86400000 | — | 카운터 정리 실행 주기 (ms, 24시간). Aster TSDB 카운터 테이블은 default_time_to_live 를 못 쓰므로 애플리케이션 레벨로 정리 |
flow.stats.prune.hourly.days | 30 | — | tm_flow_stats_hourly 의 hour_bucket 보관 일수 |
flow.stats.prune.daily.days | 90 | — | tm_flow_stats_daily 의 day_bucket 보관 일수 |
flow.health.check.interval.ms | 600000 | — | Flow 헬스체크 주기 (ms, 10분). 현재 시각 버킷 errors > 0 이면 ERROR, 아니면 NORMAL (KST 기준) |
flow.webhook.api.key | dev-webhook-19ba7a54-1132-49f2-967e-3c6f5cd989a0 | ${PP_FLOW_WEBHOOK_API_KEY:...} | Flow 엔진 외부 웹훅 인증 |
Flow 헬스체크가 쓰는 Aster TSDB 테이블: tm_flow_health_status(flow_id, hour_bucket — 현재 시각 누적기), tm_flow_health_status_10m(flow_id, min10_bucket — 10분 단위 시계열).
엣지 헬스체크
| 프로퍼티 | 기본값 | 치환 | 설명 |
|---|---|---|---|
edge.health.check.interval.ms | 600000 | — | 엣지 헬스체크 주기 (ms, 10분) |
판정 소스는 Aster TSDB tm_edge_status payload 의 _ON / _NORMAL 플래그다. RT REST 호출이 없어 부하가 0이고 1초 안에 끝난다. 테이블은 tm_edge_health_status(edge_id, hour_bucket), tm_edge_health_status_10m(edge_id, min10_bucket).
인증 / 보안
| 프로퍼티 | 기본값 | 치환 | 설명 |
|---|---|---|---|
api.key | (없음) | ${PP_API_KEY} | 플랫폼 내부 API 키 (서버 ↔ 엣지 에이전트 인증) |
engine.api.v5.auth.bruteforce.enabled | true | — | V5 API 인증 브루트포스 방어 |
engine.api.v5.auth.bruteforce.ip_limit | 30 | — | IP 당 시도 한도 |
engine.api.v5.auth.bruteforce.user_limit | 10 | — | 사용자 당 시도 한도 |
engine.api.v5.auth.bruteforce.window.seconds | 60 | — | 카운팅 윈도우 (초) |
engine.api.v5.trusted_proxies | (빈 값) | — | 신뢰 프록시 IP 화이트리스트. 설정 시에만 remoteAddr 이 목록에 있을 때 X-Forwarded-For 첫 IP 를 client IP 로 사용. 비어 있으면 getRemoteAddr() 만 사용(fail-safe) |
engine.session.bruteforce.enabled | true | — | /login/login 브라우저 세션 브루트포스 방어 |
engine.session.bruteforce.ip_limit | 30 | — | IP 당 시도 한도 |
engine.session.bruteforce.user_limit | 10 | — | 사용자 당 시도 한도 |
engine.session.bruteforce.window.seconds | 300 | — | 카운팅 윈도우 (초) |
세션 브루트포스 카운터는 Caffeine 인메모리다 — 다중 노드 공유(Redis)는 미구현.
API 토큰
| 프로퍼티 | 기본값 | 치환 | 설명 |
|---|---|---|---|
engine.api.token.cleanup.enabled | true | — | 만료(expires_at < now)/회수(revoked_at IS NOT NULL) 토큰 정리 |
engine.api.token.cleanup.retention_days | 30 | — | 이 기간 경과 후 mm_token 에서 hard delete. 매 24시간 1회(부팅 60초 후 첫 실행) |
engine.api.token.default_ttl_days | 90 | — | 신규 토큰 발급 시 기본 만료(일). 0 = 영구 토큰. 발급 요청이 ttl_days 를 주면 그 값이 우선한다 → API 토큰 발급 |
기존 expires_at 이 NULL 인 토큰은 영구 활성으로 유지된다(하위 호환).
plantpulse-storage.properties
경로: plantpulse-server/config/plantpulse-storage.properties · 템플릿: template/plantpulse-storage.properties
메타스토어(PostgreSQL) · 캐시(Valkey) · 시계열(Aster TSDB) · TSE · Data Gateway 접속과 스토리지 정책을 관리한다.
⚠️ 이 파일에는 오타 키가 실재한다. 3개 키가 코드가 읽는 철자와 다르다 — 오타 키 경고 절을 반드시 읽어라.
PostgreSQL 메타스토어
| 프로퍼티 | 기본값 | 치환 | 설명 |
|---|---|---|---|
metastore.driver | org.postgresql.Driver | — | JDBC 드라이버 클래스 |
metastore.url | jdbc:postgresql://... | ${PP_POSTGRES_HOST} · ${PP_POSTGRES_PORT} · ${PP_DB_NAME} | 메타스토어 JDBC URL. 쿼리스트링 ?characterEncoding=UTF-8&reWriteBatchedInserts=true 포함 |
metastore.user | — | ${PP_PG_USER} | 메타스토어 계정 |
metastore.password | — | ${PP_PG_PASSWORD} | 메타스토어 비밀번호 |
캐시 (Valkey / Redis 호환)
| 프로퍼티 | 기본값 | 치환 | 설명 |
|---|---|---|---|
cache.host | — | ${PP_REDIS_HOST} | 캐시 호스트 |
cache.port | — | ${PP_REDIS_PORT} | 캐시 포트 (내부 plaintext Valkey backend) |
cache.password | — | ${PP_REDIS_PASSWORD} | 캐시 비밀번호 |
cache.ssl.enabled | false | — | 캐시 TLS. 내부 클라이언트는 redis:// 기본 |
cache.ssl.truststore.location | /var/security/plantpulse/master/master.truststore.p12 | — | 트러스트스토어 경로 |
cache.ssl.truststore.password | kopens123! | ${PP_TLS_TRUSTSTORE_PASSWORD:kopens123!} | 트러스트스토어 비밀번호 |
cache.ssl.truststore.type | PKCS12 | — | 트러스트스토어 타입 |
cache.ssl.endpoint.identification.enabled | false | — | 엔드포인트 식별 검증 |
키 상수 정본은 plantpulse-inmemory 의 InMemoryConfigKeys 다.
TSE (TimeSeries Engine)
| 프로퍼티 | 기본값 | 치환 | 설명 |
|---|---|---|---|
tse.protocol | http | ${PP_TSE_PROTOCOL:http} | TSE 프로토콜. 내부 통신이라 평문 http 기본 (2026-08) |
tse.host | — | ${PP_TSE_HOST} | TSE 호스트 |
tse.port | 7800 | ${PP_TSE_CONNECT_PORT:7800} | TSE 포트. 평문 리스너 7800 기본 |
tse.user | tse | ${PP_TSE_USER:tse} | TSE 계정 |
tse.password | tse123! | ${PP_TSE_PASSWORD:tse123!} | TSE 비밀번호 |
Aster TSDB 시계열 저장소
| 프로퍼티 | 기본값 | 치환 | 설명 |
|---|---|---|---|
storage.db_type | CASSANDRA | — | DB 종류. 템플릿 주석에 CASSANDRA/DSE/SCYLLADB 가 남아 있으나 지금 지원되는 값은 CASSANDRA 뿐입니다 |
storage.db_version | 5.0 | — | 서버 버전이 아니라 «기능 호환 수준» 입니다 — 아래 주를 보십시오 |
storage.host | — | ${PP_CASSANDRA_HOST} | contact point 호스트 |
storage.db_version 이 5.0 인데 nodetool version 은 6.0.0 이라고 나옵니다둘 다 맞습니다. 같은 것을 가리키는 값이 아닙니다.
| 값 | 무엇 | |
|---|---|---|
storage.db_version | 5.0 | 드라이버가 어느 기능 집합으로 말할지를 정하는 호환 수준 |
| 실제 번들 서버 | 6.0.0 | apache-cassandra-timeseries-6.0.0.jar — cassandra-6.0 의 사내 포크 |
5.0 을 보고 「서버가 5.0 이구나」라고 읽지 마십시오. 서버 쪽 이야기는
시계열 데이터베이스에 있습니다.
이 값을 임의로 6.0 으로 올리지 마십시오 — 드라이버 동작이 바뀝니다.
| storage.port | 9042 | ${PP_STORAGE_PORT:9042} | native 프로토콜 포트 |
| storage.keyspace | — | ${PP_KEYSPACE} | 사용 keyspace |
| storage.user | — | ${PP_CASSANDRA_USER} | 접속 계정 |
| storage.password | cassandra | ${PP_STORAGE_PASSWORD:cassandra} | 비밀번호. PP_STORAGE_PASSWORD 는 env.sh 미export → 기본값 적용 |
| storage.durable_writes | true | — | commit log 사용 여부 (⚠️ 읽는 코드 없음 — 아래 참고) |
| storage.append_columns | [] | — | 사용자 정의 컬럼 자동 추가 |
| storage.replication | { 'class' : 'NetworkTopologyStrategy', 'datacenter1' : 1 } | — | 복제 전략 (단일 노드 기본) |
| storage.data.disk.name | — | ${PP_DATA_DISK_NAME} | 데이터 디스크 이름 |
TTL (단위: 일)
| 프로퍼티 | 기본값 | 설명 |
|---|---|---|
storage.tag.point.ttl | 62 | 태그 시계열 원본 |
storage.tag.point.map.ttl | 1 | 태그 포인트 맵 |
storage.tag.point.sampling.ttl | 93 | 태그 샘플링 |
storage.tag.point.snapshot.ttl | 93 | 태그 스냅샷 |
storage.tag.point.aggregation.ttl | 93 | 태그 집계 |
storage.tag.point.archive.ttl | 365 | 태그 아카이브 (장기 보존) |
storage.tag.blob.ttl | 93 | 태그 BLOB |
storage.asset.data.ttl | 10 | 에셋 데이터 |
storage.asset.data.sampling.ttl | 31 | 에셋 샘플링 |
에셋 스냅샷 주기
| 프로퍼티 | 기본값 | 설명 |
|---|---|---|
storage.asset.data.snapshot.interval | 10 SECONDS | 매 사이클 전 자산의 태그맵(data_map)을 asset_data 계열(data/second/timestamp + 분/시/일 경계)에 기록 |
템플릿 주석이 근거를 밝히고 있다: 1 SECONDS 는 자산 121 기준 분당 약 22K 쓰기(Aster TSDB 전체의 약 4%)로 과밀했다. 태그 원본(초 단위)은 tm_tag_point/TSE 에 완전 보존되므로 자산 뷰 스냅샷은 10s(코드 기본값과 일치)로 낮췄다 — 쓰기 −90%, 기록 완전성 유지.
이 값은 스케줄러의
ASSET_DATA_JOB주기가 된다."<수> <단위>"2토큰 형식이어야 하며 규칙은 스케줄러 아키텍처 참고.
내부 메타스토어 동기화 (실험적)
| 프로퍼티 | 기본값 | 설명 |
|---|---|---|
storage.internal.metastore.enabled | false | 내부 메타스토어 동기화 활성화 |
storage.internal.metastore.thread.count | 4 | 동기화 워커 스레드 수 |
storage.internal.metastore.queue.size | 12000000 | 동기화 큐 크기 |
storage.internal.metastore.point.retation.days | 10 | 포인트 보관 일수 (⚠️ 오타 키 — 아래 참고) |
행 캐시
| 프로퍼티 | 기본값 | 설명 |
|---|---|---|
storage.asset.data.row.cache.size | NONE | 에셋 데이터 행 캐시 (NONE/ROWS_ONLY/ALL) — ⚠️ 읽는 코드 없음 |
storage.tag.point.row.cache.size | NONE | 태그 포인트 행 캐시 — ⚠️ 읽는 코드 없음 |
Compaction
| 프로퍼티 | 기본값 | 설명 |
|---|---|---|
storage.table.compaction.strategy | UCS | 기본 전략 (TWCS: TimeWindow, UCS: Unified). CassandraCreateDAO 가 읽는다(코드 fallback 은 TWCS) |
storage.table.compaction.strategy.twcs.window_size | 1 | TWCS 윈도우 크기 — ⚠️ 읽는 코드 없음 |
storage.table.compaction.strategy.twcs.window_unit | DAYS | TWCS 윈도우 단위 — ⚠️ 읽는 코드 없음 |
storage.table.compaction.strategy.ucs.scailing_parameter | T8 | UCS 스케일링 파라미터 (T8 = tiered 8 levels). 키 철자 scailing 은 코드와 일치 |
storage.table.compaction.strategy.ucs.min_sstable_size | 128MiB | UCS 최소 sstable 크기 (코드 fallback 100MiB) |
storage.table.compaction.strategy.ucs.target_sstable_size | 512MiB | UCS 목표 sstable 크기 |
storage.table.compaction.strategy.ucs.base_shard_count | 8 | UCS base shard 수 |
storage.table.compaction.strategy.ucs.max_sstables_to_compact | 6 | 한 번에 compaction 할 최대 sstable 수 |
storage.table.compaction.strategy.ucs.sstable_growth | 0.7 | UCS sstable 증가 비율 |
압축 / 쿼리 한도 / 백업 / Data Gateway
| 프로퍼티 | 기본값 | 치환 | 설명 |
|---|---|---|---|
storage.compresion.zstd.level | 3 | — | zstd 압축 레벨 (1~22) — ⚠️ 오타 키, 아래 참고 |
storage.tag.point.select.limit.size | 1000000 | — | 단일 태그 포인트 select 최대 행 수 |
storage.doamin.model.changed.to.metastore.backup | true | — | 도메인 모델 변경 시 메타스토어 백업 — ⚠️ 오타 키 + 읽는 코드 없음 |
data.gateway.protocol | http | ${PP_DATA_GATEWAY_PROTOCOL:http} | Data Gateway 프로토콜 |
data.gateway.host | 127.0.0.1 | ${PP_DATA_GATEWAY_HOST:127.0.0.1} | Data Gateway 호스트 (로컬 동거 전제) |
data.gateway.port | 5500 | ${PP_DATA_GATEWAY_CONNECT_PORT:5500} | Data Gateway 포트 (코드 fallback 5501) |
data.gateway.api.key | — | ${PP_DATA_GATEWAY_API_KEY} | Data Gateway API 키 |
⚠️ 오타 키 — 편집해도 무시된다
템플릿에 실제로 존재하는 아래 3개 키는 코드가 읽는 철자와 다르다. 관리자가 이 줄의 값을 바꿔도 조용히 무시되고 코드 기본값이 적용된다.
| 템플릿의 키 (오타) | 코드가 실제로 읽는 키 | 코드 기본값 | 읽는 위치 |
|---|---|---|---|
storage.compresion.zstd.level | storage.compression.zstd.level | 3 | StorageConfig → CassandraCreateDAO |
storage.internal.metastore.point.retation.days | storage.internal.metastore.point.retention.days | 10 | StorageConfig → PointDAO |
storage.doamin.model.changed.to.metastore.backup | 없음 (올바른 철자로도 읽는 코드가 없다) | — | — |
값을 실제로 바꾸려면 코드 철자의 키를 같은 파일에 추가하라. 예를 들어 zstd 레벨을 6으로 올리려면
storage.compression.zstd.level=6을 넣어야 한다(오타 키를 고쳐 쓰는 것이 아니라 올바른 철자 줄을 추가). 오타 줄은 남겨 두어도 무해하지만, 템플릿 자체를 고치는 편이 근본 해법이다.
storage.doamin.model.changed.to.metastore.backup은 어느 철자로도 읽는 코드가 없다. 도메인 모델 변경 시 백업은 이 키가 아니라MetastoreBackupDeployer(cron0 0 12 1 1/1 ? *, 매월 1일 12:00)가 담당한다 — 스케줄러 아키텍처 참고.
템플릿에는 없지만 코드가 읽는 storage 키
| 프로퍼티 | 코드 기본값 | 설명 |
|---|---|---|
storage.compression.zstd.type | ZstdCompressor | 압축기 클래스명 |
읽는 코드가 없는 storage 템플릿 키 (편집해도 무효)
storage.durable_writes · storage.asset.data.row.cache.size · storage.tag.point.row.cache.size · storage.table.compaction.strategy.twcs.window_size · storage.table.compaction.strategy.twcs.window_unit (+ 위 오타 키 3개)
TWCS 관련 두 키는 storage.table.compaction.strategy=TWCS 로 바꾸더라도 윈도우 크기/단위를 제어하지 못한다.
plantpulse-mq.properties
경로: plantpulse-server/config/plantpulse-mq.properties · 템플릿: template/plantpulse-mq.properties
Kafka / MQTT 브로커 접속과 DDS 발행 토픽을 관리한다. 코드 측 SSOT 는 MqConfig(접속) 와 UNSTopicDefaults(토픽)다.
브로커 접속
| 프로퍼티 | 기본값 | 치환 | 설명 |
|---|---|---|---|
mq.host | — | ${PP_KAFKA_HOST} | 브로커 호스트 (Kafka/MQTT 공용) |
mq.user | — | ${PP_MQ_USER} | 브로커 관리 계정 |
mq.password | — | ${PP_MQ_PASSWORD} | 브로커 비밀번호 |
mq.kafka.port | 9092 | ${PP_KAFKA_PORT:9092} | Kafka 포트 |
mq.kafka.security.protocol | SASL_PLAINTEXT | — | Kafka 보안 프로토콜 |
mq.ssl.truststore.location | /var/security/plantpulse/master/master.truststore.p12 | — | 메시징 TLS 트러스트스토어 (MQTT + 선택적 Kafka TLS) |
mq.ssl.truststore.password | kopens123! | ${PP_TLS_TRUSTSTORE_PASSWORD:kopens123!} | 트러스트스토어 비밀번호 |
mq.ssl.truststore.type | PKCS12 | — | 트러스트스토어 타입 |
mq.ssl.endpoint.identification.algorithm | (빈 값) | — | 호스트명 검증 알고리즘 (빈 값 = 검증 안 함) |
mq.mqtt.port | — | ${PP_MQTT_TLS_PORT} | MQTT 접속 포트 |
mq.mqtt.ssl.enabled | true | — | MQTT TLS 사용 |
MqConfig 는 위 키 외에 Kafka 전용 트러스트스토어 오버라이드 mq.kafka.ssl.truststore.location / .password / .type 과 mq.kafka.ssl.endpoint.identification.algorithm 도 읽는다(템플릿에는 없고, 없으면 mq.ssl.* 를 쓴다).
DDS 토픽
Kafka 14종(mq.dds.kafka.topic.*) + MQTT UNS 14종(mq.dds.mqtt.topic.*) + SparkplugB 2종(mq.dds.mqtt.sparkplugb.*).
키·기본값 전량은 메시징 아키텍처 → DDS 발행 토픽 에 정리돼 있다. 토픽 값은 Kafka/MQTT 와이어 계약이고 UNSTopicDefaultsContractTest 가 리터럴을 동결하므로 임의 변경 금지.
${PP_TOPIC_PREFIX} 가 Kafka 토픽의 접두(pp-)와 MQTT UNS 경로의 루트(pp/), SparkplugB 그룹 ID 를 동시에 결정한다.
메일 설정 (pp.mm_config)
정본: PostgreSQL pp.mm_config · 키 정본: plantpulse.core.config.MailConfigKeys.
읽는 쪽은 SMTPMailSender.loadMailConfig() 다.
PP_MAIL_* 환경변수도 아무 일도 하지 않습니다AI 와 같습니다 — plantpulse-mail.properties 와 ${PP_MAIL_*} 치환 층이 2026-09-17~18 에
없어졌습니다. 사이드카나 docker run -e 로 주어도 조용히 무시됩니다. 값은 콘솔의
설정 화면(/config/index) 또는 pp.mm_config 표에 넣습니다.
| 설정 키 | 기본값 | 설명 |
|---|---|---|
MAIL_SEND_ENABLED | false | 마스터 발송 게이트. 꺼져 있으면 SMTP 접속 없이 건너뛰고 WARN 만 남깁니다 |
MAIL_SMTP_HOST | smtp-relay.brevo.com | SMTP 릴레이 주소 |
MAIL_SMTP_PORT | 587 | 587 = STARTTLS, 465 = 암시적 TLS(MAIL_SMTP_SSL_ENABLE 과 함께) |
MAIL_SMTP_AUTH | true | SMTP 로그인 여부. 켜 있어도 MAIL_SMTP_USER 가 비어 있으면 로그인하지 않습니다 |
MAIL_SMTP_USER | (빈 값) | SMTP 계정. 릴레이가 발급한 이름이라 발신 주소와 다를 수 있습니다. 비워서 저장할 수 있습니다 |
🔑 MAIL_SMTP_PASSWORD | (빈 값) | SMTP 비밀번호 또는 API 키. 로그인하는 릴레이에서 비어 있으면 인증이 거부됩니다 |
MAIL_SMTP_STARTTLS_ENABLE | true | 587 에서 STARTTLS 로 승격할지 |
MAIL_SMTP_SSL_ENABLE | false | 465 처럼 처음부터 TLS 로 붙을지. 이 경우 starttls 는 끕니다 |
MAIL_SMTP_CONNECTIONTIMEOUT | 10000 | 접속 타임아웃(ms). 없으면 JavaMail 기본값은 「무한 대기」입니다 |
MAIL_SMTP_TIMEOUT | 10000 | 읽기 타임아웃(ms). 〃 |
MAIL_SMTP_WRITETIMEOUT | 10000 | 쓰기 타임아웃(ms). 〃 |
MAIL_FROM | (빈 값) | 발신 주소. 비우면 MAIL_SMTP_USER 를 쓰는데, 릴레이 계정명은 대개 유효한 주소가 아니라 수신 측이 거부할 수 있습니다 — 실제 주소를 적으십시오 |
sms.sender.class | plantpulse.core.service.support.alarm.sms.DefaultSMSSender | SMS 발송기 구현 FQN. 없는 클래스를 적으면 기본 구현으로 되돌아갑니다 |
TLS 는 1.3 · 1.2 만 쓰고 서버 인증서의 이름을 검사합니다.
MAIL_SMTP_USER · MAIL_SMTP_PASSWORD 의 기본값은 빈 값입니다. MAIL_SEND_ENABLED 가 기본 false
이므로 운영자가 켜기 전까지는 발송을 시도하지 않습니다.
Gmail SMTP 릴레이로 보내기
Google Workspace 의 SMTP 릴레이(smtp-relay.gmail.com)는 보내는 서버의 IP 주소로 허가할 수 있습니다. 이때는 계정이 없으므로 로그인하지 않게 둡니다. 먼저 Google 관리 콘솔의 SMTP 릴레이 설정에 이 서버가 밖으로 나가는 IP 를 등록합니다.
| 설정 키 | 값 |
|---|---|
MAIL_SEND_ENABLED | true |
MAIL_SMTP_HOST | smtp-relay.gmail.com |
MAIL_SMTP_PORT | 587 |
MAIL_SMTP_AUTH | false |
MAIL_SMTP_USER | (비움) |
MAIL_SMTP_STARTTLS_ENABLE | true |
MAIL_SMTP_SSL_ENABLE | false |
MAIL_FROM | Workspace 도메인의 실제 주소 |
저장한 뒤 설정 화면의 재적용 을 누릅니다.
알람 메일
- 머리에는 제품 로고가 메일 안에 실려 갑니다(CID 인라인 이미지). 콘솔 주소가 없어도 보이고, 밖에서 받아 오는 것이 없습니다.
- 메일의 위치 줄은 사이트부터 적힙니다(사이트 › 구역 › 라인 › 설비, 기업은 넣지 않습니다).
- «알람 확인하러 가기» 링크는
PP_UI_CONSOLE_URL(<콘솔 주소>/alarm/view/<알람 번호>)입니다. 비어 있으면 메일은 그대로 나가고 링크만 빠집니다 — 주소 설정.
diagnostic.log.email 은 없어졌습니다읽는 코드가 하나도 없어 표에서 제거됐습니다(제품 테스트가 그 키가 다시 들어오는 것을 막고 있습니다). 어딘가에 남아 있어도 아무 일도 하지 않습니다.
AI 설정 (pp.mm_config)
정본: PostgreSQL pp.mm_config · 키 정본: plantpulse.core.config.AiConfigKeys.
읽는 쪽은 AiConfig(+ AiConfig.mcpSettings()) 다.
PP_AI_* 환경변수는 아무 일도 하지 않습니다옛 plantpulse-ai.properties 는 2026-09-17 에 삭제됐고, 그 파일을 읽던 경로와 ${PP_AI_*}
치환 층까지 2026-09-18 에 함께 없어졌습니다. 지금 PP_AI_OPENAI_ENABLED 같은 이름을 사이드카나
docker run -e 로 주면 조용히 무시됩니다 — 오류도 경고도 없습니다.
제품이 그 이름들을 「혹시 모르니」 남겨 두지 않고 지운 이유가 그것입니다. 있으면서 무시되는 이름은 없는 이름보다 나쁩니다. 서버가 설정된 것처럼 보이기 때문입니다.
값을 넣는 길은 둘뿐입니다 — 콘솔의 설정 화면(/env), 또는 pp.mm_config 표를 직접 고치는 것.
행이 없는 키는 아래 표의 기본값으로 읽히고, 값을 넣으면 그때 행이 생깁니다.
LLM 게이트웨이
| 프로퍼티 | 기본값 | 설명 |
|---|---|---|
ai.llm.enabled | false | AI 전체 스위치. 꺼져 있으면 AI 화면과 엔드포인트가 모두 닫힙니다 |
ai.llm.base.url | https://api.openai.com | OpenAI 호환 게이트웨이(LiteLLM/vLLM). 끝에 / 를 붙이지 않습니다 |
ai.llm.chat.path | /v1/chat/completions | 게이트웨이가 다른 경로를 쓸 때만 바꿉니다 |
ai.llm.responses.path | /v1/responses | 〃 |
🔑 ai.llm.api.key | (빈 값) | 게이트웨이 키. 비어 있으면 호출이 401 로 거부됩니다 |
ai.llm.model | gpt-5-mini | 게이트웨이가 노출하는 모델명. base.url 을 바꾸면 이것도 함께 바꿉니다 |
ai.llm.timeout.ms | 60000 | LLM 호출 타임아웃(ms) |
ai.llm.max.output.tokens | 4000 | 응답 최대 토큰 수 |
ai.llm.temperature | -1 | 음수면 요청에서 아예 생략해 모델 기본값을 씁니다 |
ai.openai.* 는 더 이상 읽히지 않습니다접두사가 ai.llm. 으로 바뀌었습니다. pp.mm_config 에 ai.openai.base.url 행이 남아 있어도
읽는 코드가 없어 기본값(https://api.openai.com)이 쓰입니다 — 게이트웨이를 설정해 두었는데
OpenAI 로 나가려다 실패하는 모양이 됩니다. 업그레이드한 설치는 이 행들을 확인하십시오.
ai.llm.temperature 는 왜 음수가 기본인가gpt-5 계열은 temperature 를 지원하지 않아 기본값 1 외의 값을 보내면 400 Unsupported value 가
납니다. 그래서 「보내지 않음」을 뜻하는 음수를 기본으로 둡니다. LiteLLM/vLLM 뒤의 다른 모델을
쓸 때만 0 이상으로 올리십시오.
기능 스위치
🔴 기본값이 2026-09-16 에 바뀌었습니다. 화면에 남은 AI 기능은 채팅 하나이고, 나머지는
제품이 내렸습니다. 값을 true 로 되돌리면 기능은 돌아오지만, 그 화면들은 그 판에서 검증된
상태가 아닙니다.
| 프로퍼티 | 기본값 | 설명 |
|---|---|---|
ai.chat.enabled | true | AI 채팅 콘솔 — 화면에 남은 AI 기능은 이것 하나입니다 |
ai.chat.history.ttl.days | 90 | 채팅 이력 보존(일). Cassandra TTL 로 적용되며 재기동 후 «신규» 메시지부터 반영됩니다 |
ai.alarm.rca.enabled | false | 알람 RCA — 켜면 알람 상세에 AI 원인분석이 붙습니다 |
ai.alarm.eql.enabled | false | 알람 EQL 어시스턴트 — 켜면 알람 설정 폼에 초안 버튼이 붙습니다 |
ai.uns.topic.enabled | false | UNS 토픽 설명 — 켜면 UNS 트리에 설명 패널이 붙습니다 |
ai.result.audit.enabled | false | AI 결과 감사 — 화면 없는 RCA 내부 부품. RCA 를 켤 때 함께 켭니다 |
ai.similar.incident.enabled | false | 유사 장애 증거 수집 — 〃 |
ai.similar.incident.max.items | 5 | 증거로 실을 유사 장애 최대 건수 |
ai.similar.incident.min.score | 40 | 유사 장애로 인정할 최소 점수 |
ai.diagnostic.summary.* 3개(진단 로그 AI 요약)와 ai.operations.report.* 3개(AI 운영
리포트)는 2026-08-25 제품에서 제거되었습니다. 화면·JS·컨트롤러까지 함께 걷어냈으므로
값을 되돌려도 기능이 살아나지 않습니다. 남아 있어도 해는 없습니다 — 읽는 코드가 없습니다.
MCP
🔴 MCP 는 ai.llm.enabled 와 «독립»입니다. 화면이 아니라 외부 클라이언트용이라,
게이트웨이가 꺼져 있어도 /api/v5/mcp 는 열려 있습니다. 자세한 것은 MCP 서버.
| 프로퍼티 | 기본값 | 설명 |
|---|---|---|
AI_MCP_ENABLED | true | false 면 /api/v5/mcp 가 404 를 냅니다 |
AI_MCP_ALLOWED_ORIGINS | (빈 값) | 브라우저 Origin 화이트리스트(쉼표 구분). 비어 있으면 브라우저 요청을 전부 거부하고 네이티브 클라이언트만 허용합니다 |
AI_MCP_TREE_MAX_NODES | 2000 | 트리 응답 노드 상한 — 모델 컨텍스트 창에 종속되는 값이라 모델이 커지면 올립니다 |
AI_MCP_TREE_DEFAULT_DEPTH | 2 | 트리 조회 기본 깊이 |
AI_MCP_TREE_MAX_NODE_TAGS | 100 | 노드 하나에 실을 태그 수 상한 |
AI_MCP_TREE_ONTOLOGY_MAX_CHARS | 200000 | 온톨로지 응답 문자 수 상한 |
AI_MCP_TREE_ONTOLOGY_DEFAULT_DEPTH | 3 | 트리 기본 깊이보다 한 단계 깊습니다 — 태그 수가 실리는 설비 노드까지 나와야 「이 설비 태그 몇 개」를 기본 응답으로 답할 수 있습니다 |
AI_MCP_TREE_ONTOLOGY_MAX_TAGS | 500 | 온톨로지 응답 전체의 태그 행 예산(노드별 상한과 별개). 슬림 태그 1건이 약 85B 라, 사이트 전체를 실으면 컨텍스트 창의 33~56% 를 먹습니다 |
그 외 템플릿
template/ 에는 위 5종 외에도 애플리케이션·인프라 설정 템플릿이 있다. 배포 경로 매핑 정본은 ConfigTemplates.java 다.
| 템플릿 | 배포 경로 | 용도 |
|---|---|---|
plantpulse-batch.properties | /plantpulse-batch/config/ | 배치(시계열 동기/집계) |
plantpulse-cep.properties | /plantpulse-cep/config/ | CEP 엔진 |
plantpulse-jdbc.properties | /plantpulse-data-gateway/config/ | JDBC 통합 설정 |
plantpulse-data-gateway.properties | /plantpulse-data-gateway/config/ | Data Gateway 동작 |
plantpulse-warehouse.properties | /plantpulse-warehouse/config/ | Aster TSDB → Iceberg(S3) 아카이브 |
plantpulse-datalake-admin-api.properties | /plantpulse-datalake-admin-api/config/ | 관리 콘솔 API · JMX 수집 |
plantpulse-plugin-opcua.properties | /plantpulse-plugin/opc-ua/config/ | OPC UA 서버 플러그인 |
plantpulse-plugin-aas.properties | /plantpulse-plugin/aasx-server/config/ | AAS V3 (aasx-server) 플러그인 |
kafka.properties | /plantpulse-messaging/kafka/config/kafka.properties | Kafka(KRaft) 브로커 |
kafka-jaas.conf | /plantpulse-messaging/kafka/config/jaas.conf | Kafka JAAS |
hivemq.xml | /plantpulse-messaging/mqtt/conf/config.xml | HiveMQ 브로커 |
plantpulse-mq-auth.properties | /plantpulse-messaging/mqtt/conf/auth.properties | HiveMQ 인증 소스 |
hive-auth.properties | /plantpulse-analytics/spark/conf/ | Hive/분석 계정 인증 소스 |
plantpulse-timeseries-engine.conf | /plantpulse-timeseries/engine/conf/ (2곳) | TSE |
valkey.conf · postgresql.conf · pg_hba.conf · cassandra.yaml · jvm-server.options | /plantpulse-storage/... | 스토리지 |
spark-env.sh · spark-defaults.conf · hive-site.xml · kyuubi-defaults.conf · gravitino-iceberg-rest-server.conf | /plantpulse-analytics/... | 분석 |
workflow.yaml · application.yaml | /plantpulse-workflow/... | Temporal / Kestra |
plantpulse-websocket.properties도 존재하지 않는다. WebSocket/STOMP 계열 설정 파일은 없다.template/cluster/는 워커 노드 전용 오버라이드다 — master 템플릿을 고치면 여기도 동기화해야 한다.
plantpulse-batch.properties
접속 블록(플랫폼/메타스토어/캐시/TSE/Kafka/Aster TSDB/Spark)과 배치 동작 설정으로 구성된다. 접속 키는 storage/jdbc 와 이름이 다르니 주의 — 예: Aster TSDB 는 storage.db.host / storage.db.port / storage.db.keyspace (server 는 storage.host / storage.port / storage.keyspace).
| 프로퍼티 | 기본값 | 설명 |
|---|---|---|
platform.host | ${PP_MASTER_IP} | 플랫폼(server-web) 호스트 |
mq.port | 9092 | Kafka 포트 (리터럴 — 치환 아님) |
kafka.topic | pp-batch | 배치 인입 토픽 |
kafka.group.id | PP-BATCH-GROUP | 배치 컨슈머 그룹 |
batch.timer_schedule_delay | 5000 | 배치 타이머 주기 (ms) |
batch.thread_pool_batch_thread_size | 4 | 배치 워커 스레드 수 |
batch.buffer_drain_limit_size | 10000 | 한 번에 비우는 최대 건수 |
batch.sync.inmemory.enabled | false | 인메모리 동기화 |
batch.sync.inmemory.ttl.minute | 10 | 인메모리 동기화 TTL (분) |
batch.sync.tse.enabled | true | TSE 로 분배 |
batch.sync.external.db.enabled | false | 외부 DB 동기화 |
external.db.name | TIMESCALEDB | 외부 DB 종류. INFLUXDB/QUESTDB 블록은 템플릿에 주석 상태로 있다 |
analytics.url | jdbc:spark://${PP_SPARK_HOST}:${PP_KYUUBI_PORT}/default | Spark Thrift JDBC |
plantpulse-cep.properties
| 프로퍼티 | 기본값 | 설명 |
|---|---|---|
cep.backend | aster | 부팅할 백엔드 (aster · flink). 그 밖의 값은 부팅 실패 — 백엔드 |
cep.aster.state.enabled | true | Aster CEP 룰 상태(창 · 집계 · 진행 중 패턴)를 cache.* Redis 에 보존. 키는 PP:CEP:ASTER-STATE:<문장> |
cep.aster.state.snapshot_interval_ms | 60000 | 스냅샷 주기 — 크래시 때 잃을 수 있는 최대 상태. 정상 정지는 마지막 스냅샷을 찍고 내려간다 |
cep.async.core_pool_size | 32 | 비동기 코어 풀 |
cep.async.max_pool_size | 256 | 비동기 최대 풀 |
cep.async.queue_capacity | 50000 | 비동기 큐 |
cep.async.keep_alive_seconds | 60 | 스레드 keep-alive |
cep.async.shutdown_timeout_seconds | 30 | graceful shutdown 대기 |
cep.consumer.thread_count | 16 | 컨슈머 스레드 |
cep.stream.shard_count | 16 | 스트림 샤드 수 |
cep.stream.drain_limit_size | 1000 | 드레인 한도 |
cep.stream.drain_warn_ms | 1000 | 드레인 경고 (ms) |
cep.monitor.initial_delay_seconds | 5 | 모니터 최초 지연 |
cep.monitor.interval_seconds | 1 | 모니터 주기 |
cep.monitor.store_interval_seconds | 60 | 지표 Aster TSDB 저장 주기 |
cep.api.key | ${PP_CEP_API_KEY} | EQL 관리 엔드포인트 인증 (X-API-Key) |
cep.api.max_eql_text_length | 100000 | EQL 텍스트 최대 길이 (DOS 방어) |
cep.storage.request_timeout_seconds | 10 | Aster TSDB 요청 타임아웃 |
cep.storage.connect_max_retries | 3 | 접속 재시도 |
cep.storage.ttl_seconds | 864000 | 메트릭 TTL (초, 10일) |
cep.stream.pending_idle_threshold_ms | 60000 | pending 유휴 임계 |
cep.stream.cleaner_initial_delay_ms | 60000 | 클리너 최초 지연 |
cep.stream.cleaner_interval_ms | 10000 | 클리너 주기 |
cep.stream.max_clean_duration_ms | 30000 | 클린 최대 소요 |
cep.stream.cleaner_max_claim_count | 5000 | 클레임 최대 건수 |
cep.stream.ack_chunk_size | 500 | ACK 청크 크기 |
cep.stream.max_deliveries | 3 | 이 횟수만큼 배달돼도 처리되지 못한 이벤트만 데드레터로 보낸다 |
cep.stream.dead_letter.retention_ms | 86400000 | 데드레터 보존 나이(24시간) |
cep.stream.dead_letter.max_bytes | 268435456 | 데드레터 바이트 예산(256 MiB, 샤드 전체 합계). 넘으면 샤드마다 오래된 것부터 자른다 |
plantpulse-jdbc.properties
외부 JDBC 클라이언트(SQL 모듈 · Data Gateway)의 통합 접속 설정이다. 프리픽스는 jdbc.<tech> (postgres/cassandra/spark/tse).
| 프로퍼티 | 값 | 설명 |
|---|---|---|
jdbc.postgres.driver | org.postgresql.Driver | META / PQL |
jdbc.postgres.url | jdbc:postgresql://${PP_POSTGRES_HOST}:${PP_POSTGRES_PORT}/${PP_DB_NAME}?characterEncoding=UTF-8 | |
jdbc.cassandra.driver | plantpulse.cassandra.jdbc.CassandraDriver | OLTP 시계열(CQL). 드라이버 값은 설정 일관성용(기능상 미사용) |
jdbc.cassandra.url | jdbc:cassandra://${PP_CASSANDRA_HOST}:${PP_CASSANDRA_PORT}/${PP_SCHEME} | |
jdbc.tse.driver | plantpulse.timeseries.tql.TQLDriver | OTAP / TQL |
jdbc.tse.url | jdbc:ts://${PP_TSE_HOST}:${PP_TSE_PORT}/${PP_SCHEME} | ⚠️ plain http(ts/7800) 고정 |
jdbc.spark.driver | plantpulse.spark.jdbc.SparkSQLDriver | OLAP 분석 |
jdbc.spark.url | jdbc:spark://${PP_SPARK_HOST}:${PP_KYUUBI_PORT}/default/${PP_SCHEME} | |
data.gateway.api.key | ${PP_DATA_GATEWAY_API_KEY} | JDBC 호출 인증용 |
⚠️
jdbc.tse.url을 https(tss/7801)로 바꾸지 마라. TQL JDBC 드라이버는 평문 TSE 리스너(7800)를 쓴다. TSE 클라이언트는 전역적으로 평문 http/7800 이 기본이다(2026-08, env.sh TSE 섹션). tss/7801 로 잡히면 JDBC 접속 실패 → data-gateway 부팅 실패 →/api/v1/*전부 404 → analytics 카탈로그 404 로 이어진다. 그래서ts/PP_TSE_PORT로 핀 고정돼 있다.
jdbc.spark.username은 분석 전용 계정${PP_ANALYTICS_USER}다. Kyuubi 내부 메타스토어 계정(PP_HIVE_*)과 분리돼 있다. 선택 키로jdbc.<tech>.pool.initial|min|max(postgres/spark/tse),jdbc.<tech>.query.timeout|fetch-size를 쓸 수 있다(전체 레퍼런스는plantpulse-jdbc/docs/configuration.md).jdbc.cassandra.local-datacenter는 템플릿에 주석 상태이며 미설정 시datacenter1이다.
plantpulse-data-gateway.properties
| 프로퍼티 | 기본값 | 설명 |
|---|---|---|
data.gateway.api.key | ${PP_DATA_GATEWAY_API_KEY:ADFA-URDV-QWED-1234} | API 인증 키 (필수). dev 기본값은 납품 시 교체 |
data.gateway.rate.limit | 1000 | 초당 최대 요청 수 (IP + API 키 기준) |
data.gateway.slow.query.ms | 10000 | 느린 조회 경고 임계 (ms) |
data.gateway.slow.update.ms | 2000 | 느린 갱신 경고 임계 (ms) |
data.gateway.async.timeout.ms | 60000 | 비동기 타임아웃 (ms) |
plantpulse-datalake-admin-api.properties
단일 노드(type=MASTER) 기준 각 서비스의 JMX/관리 엔드포인트 모음이다. 키에 점(.)이 아니라 언더스코어(_) 를 쓰는 유일한 파일이다.
| 프로퍼티 | 기본값 | 설명 |
|---|---|---|
type | MASTER | 단일 노드 또는 클러스터 마스터 |
db_type | CASSANDRA | 모니터링 대상 DB 종류 |
master / host | ${PP_MASTER_IP} / ${PP_HOST_IP} | 마스터 / 자기 호스트 |
db_host · db_port · db_keyspace · db_username · db_password · db_replication_factor | ${PP_CASSANDRA_*} · 9042 · ${PP_SCHEME} · 1 | Aster TSDB 접속 |
tse_host · tse_port · tse_protocol · tse_username · tse_password | ${PP_TSE_*} · 7801 · https · tse · tse123! | TSE 접속(메트릭 적재) |
kafka_jmx_uri | service:jmx:rmi:///jndi/rmi://${PP_KAFKA_HOST}:7299/jmxrmi | Kafka JMX |
mqtt_jmx_uri | ...://${PP_MQTT_HOST}:7279/jmxrmi | HiveMQ JMX |
cep_jmx_uri | ...://${PP_HOST_IP}:6499/jmxrmi | CEP JMX |
datagateway_jmx_uri | ...://${PP_HOST_IP}:7499/jmxrmi | Data Gateway JMX |
sql_jmx_uri | ...://${PP_HOST_IP}:7599/jmxrmi | SQL JMX |
tse_jmx_uri | ...://${PP_HOST_IP}:7899/jmxrmi | TSE JMX |
cassandra_jmx_uri | ...://${PP_CASSANDRA_HOST}:7199/jmxrmi | Aster TSDB JMX |
spark_jmx_uri | ...://${PP_SPARK_HOST}:10010/jmxrmi | Spark JMX |
redis_jmx_uri | redis://${PP_REDIS_HOST}:${PP_REDIS_PORT}?password=... | Valkey 접속 URI |
redis_ssl_truststore_location / _password / _type / redis_ssl_endpoint_identification_enabled | p12 · ${PP_TLS_TRUSTSTORE_PASSWORD:kopens123!} · PKCS12 · false | Valkey TLS |
postgres_jmx_uri | jdbc:postgresql://.../${PP_DB_NAME}?user=...&password=... | PostgreSQL 접속 URI |
JMX 포트 요약: HiveMQ 7279, Kafka 7299, CEP 6499, Data Gateway 7499, SQL 7599, TSE 7899, Aster TSDB 7199, Spark 10010.
plantpulse-warehouse.properties
Aster TSDB → Iceberg(S3) 아카이브 배치. 이 파일만 키가 대문자 스네이크(UPPER_SNAKE) 다.
| 그룹 | 주요 키 | 기본값 |
|---|---|---|
| Temporal | TEMPORAL_SERVER · TEMPORAL_TASK_QUEUE · TEMPORAL_WORKFLOW_ID · TEMPORAL_SCHEDULE_ID · OPTIMIZER_SCHEDULE_ID · OPTIMIZER_WORKFLOW_ID | ${PP_TEMPORAL_HOST}:${PP_TEMPORAL_PORT} · PP-S3-QUEUE · PP-S3-ARCHIVER-DAILY-WORKFLOW · PP-S3-ARCHIVER-DAILY · PP-S3-OPTIMIZER-WEEKLY · PP-S3-OPTIMIZER-WEEKLY-WORKFLOW |
| 스케줄 | DAILY_HOUR · DAILY_MINUTE · OPTIMIZER_DAY_OF_WEEK · OPTIMIZER_HOUR · OPTIMIZER_MINUTE · TIMEZONE | 2 · 20 · 0(일요일) · 3 · 0 · ${PP_TZ} |
| 실행 모드 | ARCHIVER_MODE | SHELL (또는 KESTRA) |
| Kestra | KESTRA_SERVER · KESTRA_NAMESPACE · KESTRA_TASK_ID · KESTRA_USER · KESTRA_PASS | ${PP_KESTRA_HOST}:${PP_KESTRA_PORT} · plantpulse · plantpulse-daily-s3-archiver · admin@plantpulse.io · (빈 값) |
| 스크립트 | S3_SCRIPT_DIR · S3_SCRIPT_NAME · S3_OPTIMIZER_SCRIPT_NAME | ${PP_HOME}/plantpulse-warehouse/s3 · archive.sh · optimize.sh |
| Spark | SPARK_APP_NAME · SPARK_MASTER · SPARK_JAR_PATH · SPARK_DRIVER_MEMORY · SPARK_EXECUTOR_MEMORY · SPARK_EXECUTOR_CORES · SPARK_NUM_EXECUTORS · ARCHIVER_PARALLELISM · SPARK_CHECKPOINT_DIR | PP-SPARK-S3-LAKEHOUSE · local[*] · .../plantpulse-warehouse-s3.jar · 2g · 4g · 4 · 3 · 4 · s3a://${PP_S3_BUCKET:-plantpulse}/spark-checkpoint/ |
| 소스/타깃 | CASSANDRA_CATALOG · CASSANDRA_DATABASE · S3_BUCKET · ICEBERG_CATALOG · ICEBERG_DATABASE | cassandra · ${PP_SCHEME:pp} · ${PP_S3_BUCKET:-plantpulse} · spark_catalog · ${PP_SCHEME:pp} |
| 최적화 | SNAPSHOT_RETENTION_DAYS · OPTIMIZER_MIN_INPUT_FILES · OPTIMIZER_TARGET_FILE_SIZE_BYTES | 3 · 10 · 134217728 (128MB) |
| 타임아웃 | ARCHIVER_WF_EXECUTION/RUN/TASK_TIMEOUT_HOURS · OPTIMIZER_WF_EXECUTION/RUN/TASK_TIMEOUT_HOURS · ACTIVITY_MAX_ATTEMPTS · ACTIVITY_TIMEOUT_HOURS · OPTIMIZER_ACTIVITY_TIMEOUT_HOURS · SCRIPT_TIMEOUT_SECONDS · OPTIMIZER_TIMEOUT_SECONDS · HEARTBEAT_INTERVAL_SECONDS | 12/12/12 · 8/7/12 · 3 · 12 · 8 · 21600(6h) · 25200(7h) · 60 |
| 웹 | WEB_SERVER_PORT | 9600 |
메시징 / 인증 소스 템플릿
plantpulse-mqtt.properties — HiveMQ 브로커 설정.
| 프로퍼티 | 기본값 |
|---|---|
mqtt.host · mqtt.user · mqtt.password | ${PP_MQTT_HOST} · ${PP_MQ_USER} · ${PP_MQ_PASSWORD} |
mqtt.port · mqtt.ssl.enabled | ${PP_MQTT_TLS_PORT} · true |
mqtt.websocket_port | 8888 |
mqtt.data_dir | /data1/pp-data/hivemq |
plantpulse-mq-auth.properties — HiveMQ security extension(FileAuthAuthenticator)이 HIVEMQ_AUTH_FILE 환경변수로 가리키는 인증 소스. 키는 mqtt.user / mqtt.password 둘뿐이다.
hive-auth.properties — plantpulse-hive-auth(PasswordAuthenticator)가 읽는다. HIVE_AUTH_FILE 환경변수 또는 $PP_HOME/plantpulse-analytics/spark/conf/hive-auth.properties. 키 이름 자체가 placeholder 라는 점이 특이하다.
${PP_HIVE_USER}=${PP_HIVE_PASSWORD}
${PP_ANALYTICS_USER}=${PP_ANALYTICS_PASSWORD}
kafka.properties — KRaft 모드 Kafka 브로커. 주요 값: process.roles=broker,controller, node.id=1, num.partitions=4, 리스너 3종(SASL_PLAINTEXT/CONTROLLER/SASL_SSL), sasl.enabled.mechanisms=PLAIN, super.users=User:admin, allow.everyone.if.no.acl.found=false, log.dirs=${PP_DATA_DIR}/kafka/kraft_combined_logs, log.retention.ms=3600000(1시간), message.max.bytes=157286400, default.replication.factor=1, auto.create.topics.enable=true.
⚠️
log.retention.ms=3600000= 1시간. Kafka 는 버퍼 역할이고 영속화는 Aster TSDB/TSE 가 맡는다는 전제다. 컨슈머가 1시간 이상 멈추면 데이터가 유실된다.
플러그인 템플릿
plantpulse-plugin-opcua.properties — PostgreSQL / Aster TSDB / Valkey / Kafka 접속 + OPC UA 서버 엔드포인트.
| 프로퍼티 | 기본값 | 설명 |
|---|---|---|
kafka.topic | pp-tag-point | ⚠️ 리터럴 — ${PP_TOPIC_PREFIX} 치환이 아니다 |
kafka.thread · kafka.group.id | 8 · opcua-plugin-group | |
opc.ua.server.domain · opc.ua.server.port | ${PP_HOST_IP} · 8007 | |
opc.ua.server.user · password · anonymous | opcua · 설치-시-변경 · false | |
opc.ua.server.tcp.port · tls.port | ${PP_OPCUA_TCP_PORT:11004} · ${PP_OPCUA_TLS_PORT:11005} | |
redis.thread · redis.ssl.enabled | 4 · false |
plantpulse-plugin-aas.properties — AAS V3 서버 + Kafka 소비 설정.
| 프로퍼티 | 기본값 | 설명 |
|---|---|---|
aas.v3.port | ${PP_AAS_V3_PORT:8090} | V3 HTTP 포트 |
kafka.topic | ${PP_TOPIC_PREFIX}-tag-point | 실시간 태그 포인트 수신 |
kafka.thread · kafka.poll.count | 8 · 1000 | |
group.id · auto.offset.reset · enable.auto.commit | pp-plugin-aas-server · earliest · false | |
session.timeout.ms · auto.commit.interval.ms | 30000 · 1000 | |
plugin.message.listener | plantpulse.plugin.opcua.messaging.KafkaPluginMessageListener |
BaSyx V2 의 registry/AAS 포트는 설정이 아니라 코드 하드코딩이다 —
AASServer.java의REGISTRY_PORT=4800,AAS_PORT=4801.
템플릿에 없지만 코드가 읽는 엔진 키
EngineConfig 는 아래 키들도 읽는다. 템플릿(plantpulse-engine.properties)에는 없으므로 평소에는 코드 기본값이 적용되며, 값을 바꾸려면 plantpulse-server/config/plantpulse-engine.properties 에 직접 줄을 추가해야 한다.
엣지 시계 / 상태 폴링
| 프로퍼티 | 코드 기본값 |
|---|---|
edge.clock.poll.term.sec | 60 |
edge.clock.skew.threshold.ms | 10000 |
edge.clock.rtt.max.ms | 2000 |
edge.clock.autosync.enabled | true |
edge.clock.autosync.cooldown.ms | 600000 |
edge.clock.warn.cooldown.ms | 600000 |
edge.clock.skip.warn.count | 5 |
edge.status.poll.seconds | 30 |
edge.status.poll.jitter.max.ms | 3000 |
edge.clock.poll.term.sec 와 edge.status.poll.seconds 는 스케줄러 잡 주기를 결정한다 — 값 제약은 스케줄러 아키텍처 의 Edge 절 참고.
DDS / 이벤트버스 / 푸시 / 버퍼
| 프로퍼티 | 코드 기본값 |
|---|---|
engine.dds.queue.size | 80000 |
engine.dds.worker.threads | 4 |
engine.dds.latency.warn.ms | 1000 |
engine.eventbus.queue.capacity | 65536 |
engine.push.threads | 4 |
engine.push.queue.size | 10000 |
engine.storage.buffer.type | KAFKA |
engine.streaming.timeout.backup.queue.capacity | 12000000 |
engine.dds.enabled·engine.dds.data.tag.enabled·engine.dds.data.asset.enabled의 코드 기본값은false다. 템플릿이true로 명시하고 있기 때문에 배포본에서만 켜져 있다 — 이 세 줄을 지우면 DDS 가 조용히 꺼진다.
잡 스레드 (템플릿 미기재분)
| 프로퍼티 | 코드 기본값 |
|---|---|
engine.job.thread.oee | 10 |
engine.job.thread.ram | 5 |
engine.job.thread.ems | 5 |
engine.job.thread.system | 4 |
engine.job.asset.slow.threshold.ms | 20000 |
⚠️
engine.job.thread.point의 코드 기본값은4인데 템플릿은8이다(engine.job.thread.asset은 양쪽8로 일치). 템플릿 줄을 지우면 값이 절반으로 떨어진다.
Flow 엔진 (템플릿 미기재분)
| 프로퍼티 | 코드 기본값 |
|---|---|
flow.engine.enabled | true |
flow.executor.parallelism | 64 |
flow.executor.queue.capacity | 10000 |
flow.executor.queue.size | 10000 |
flow.executor.poll.timeout.ms | 50 |
flow.scheduler.pool.size | 4 |
flow.timer.pool.size | 2 |
flow.jdbc.trigger.pool.size | 2 |
flow.shutdown.timeout.sec | 5 |
flow.enabled.cache.ttl.ms | 5000 |
flow.webhook.auth.enabled | true |
알람 / ISO 지표 / OEE
| 프로퍼티 | 코드 기본값 |
|---|---|
alarm.duplicate.check.minutes | 10 |
engine.oee.debounce.ms | 100 |
iso.oee.rolling.window.minutes | 10 |
iso.ems.rolling.window.minutes | 10 |
iso.ram.rolling.window.minutes | 1440 |
이상 탐지 상세 (에셋 포인트 / 시스템)
engine.data.anomaly.enabled=true 로 켰을 때만 의미가 있다.
| 프로퍼티 | 코드 기본값 |
|---|---|
engine.data.anomaly.asset.point.interval | MINUTE |
engine.data.anomaly.asset.point.lookback.minutes | 14400 |
engine.data.anomaly.asset.point.recent.seconds | 600 |
engine.data.anomaly.asset.point.limit | 2100 |
engine.data.anomaly.asset.point.context.length | 2048 |
engine.data.anomaly.asset.point.prediction.length | 96 |
engine.data.anomaly.asset.point.score.history | 60 |
engine.data.anomaly.asset.point.threshold.k | 3.5 |
engine.data.anomaly.asset.point.threshold.min | 0.80 |
engine.data.anomaly.asset.point.threshold.max | 0.98 |
engine.data.anomaly.asset.point.topk.request | 5 |
engine.data.anomaly.asset.point.topn.report | 5 |
engine.data.anomaly.system.lookback.minutes | 1440 |
engine.data.anomaly.system.recent.seconds | 60 |
engine.data.anomaly.system.limit | 2100 |
engine.data.anomaly.system.context.length | 2048 |
engine.data.anomaly.system.pred.length | 96 |
engine.data.anomaly.system.threshold.min | 0.80 |
engine.data.anomaly.system.topk | 2 |
존재하지 않는 설정
아래 이름들은 과거 문서·외부 자료에 등장하지만 템플릿에도 코드에도 없다. 이 이름으로 설정을 추가해도 아무 효과가 없다.
| 찾던 것 | 실제 위치 |
|---|---|
storage.postgresql.* | metastore.driver / metastore.url / metastore.user / metastore.password |
storage.redis.* | cache.host / cache.port / cache.password / cache.ssl.* |
storage.cassandra.* | storage.host / storage.port / storage.keyspace / storage.user / storage.password |
storage.tse.* | tse.protocol / tse.host / tse.port / tse.user / tse.password |
storage.ttl.realtime 등 | 테이블별 storage.tag.point.ttl / storage.asset.data.ttl 등 (TTL 절) |
storage.compression.enable / .algorithm | storage.compression.zstd.level / storage.compression.zstd.type (템플릿 줄은 오타 — 오타 키 경고) |
storage.compaction.enable / .schedule | storage.table.compaction.strategy 계열 (Compaction 절) |
storage.metastore.* / storage.cache.* | 없음 |
mq.type / mq.kafka.bootstrap.servers / mq.kafka.group.id | mq.host + mq.kafka.port. 컨슈머 그룹은 설정이 아니라 코드 상수(PP-KAFKA-POINT-GROUP 등, 메시징 아키텍처) |
mail.* 를 파일에서 | pp.mm_config 한 곳(2026-09-17 이관, 파일은 삭제) |
websocket.* / plantpulse-websocket.properties | 없음. STOMP/WebSocket 은 2026-07 퇴역, 브라우저 푸시는 SSE(/push/sse) — 메시징 아키텍처 |
scheduler.enabled / scheduler.thread.count / scheduler.misfire.* / scheduler.history.* | 없음. Quartz 설정은 plantpulse-server-web/src/quartz.properties(WAR 클래스패스) — 스케줄러 아키텍처 |
engine.ntp.enable / engine.ntp.server | engine.ntpdate.sync / engine.ntpdate.server.ip |
engine.cep.enable / engine.cep.host / engine.cep.port | engine.cep.server.ip / engine.cep.server.port / engine.cep.server.protocol |
engine.anomaly.* | engine.data.anomaly.* |
engine.dds.enable / engine.dds.topic.prefix | engine.dds.enabled, 토픽 접두는 PP_TOPIC_PREFIX(mq 템플릿) |
engine.async.queue.size / engine.async.timeout / engine.pipeline.batch.size / engine.timeout.* / engine.dataflow.threads / engine.dataflow.buffer.size | 없음 |
PP_STOMP_* / PP_WEBSOCKET_* env 변수 | env.sh 에 없다 |
비밀번호가 들어 있는 프로퍼티
납품 전 반드시 교체해야 하는 값들이다. dev 평문 기본값은 env.sh(또는 템플릿)의 placeholder 이며, 운영/고객 납품 시 고객 전용 값으로 바꾸거나 Docker -e VAR=... / export 로 덮어쓴다.
| 파일 | 키 |
|---|---|
plantpulse-storage.properties | metastore.password · cache.password · cache.ssl.truststore.password · storage.password · tse.password · data.gateway.api.key |
plantpulse-engine.properties | api.key · flow.webhook.api.key · engine.cep.server.api.key |
plantpulse-mq.properties | mq.password · mq.ssl.truststore.password |
pp.mm_config (메일) | mail.smtp.password |
pp.mm_config (AI) | ai.llm.api.key — 옛 이름 ai.openai.* 의 폴백은 두지 않습니다 |
plantpulse-cep.properties | cache.password · storage.password · cep.api.key |
plantpulse-batch.properties | metastore.password · cache.password · tse.password · mq.password · storage.db.password · analytics.password · external.db.password |
plantpulse-jdbc.properties | cache.password · jdbc.postgres.password · jdbc.cassandra.password · jdbc.tse.password · jdbc.spark.password · data.gateway.api.key |
plantpulse-data-gateway.properties | data.gateway.api.key |
plantpulse-datalake-admin-api.properties | db_password · tse_password · redis_jmx_uri(URL 내 password) · redis_ssl_truststore_password · postgres_jmx_uri(URL 내 password) |
plantpulse-mqtt.properties · plantpulse-mq-auth.properties | mqtt.password |
plantpulse-plugin-opcua.properties | postgres.password · cassandra.password · redis.password · kafka.password · opc.ua.server.password |
plantpulse-plugin-aas.properties | aas.db.password · cassandra.password · kafka.password |
kafka.properties | ssl.keystore.password · ssl.key.password · ssl.truststore.password |
hive-auth.properties | 값 전체가 비밀번호 |
API 키 정책:
PP_API_KEY·PP_DATA_GATEWAY_API_KEY·PP_FLOW_WEBHOOK_API_KEY·PP_CEP_API_KEY는 dev 평문 기본값 폴백(${VAR:-<dev기본값>})으로 둔다 — dev/테스트가 추가 시크릿 주입 없이 부팅·배포되게 하기 위함이다. 하드페일(:?)로 바꾸지 마라 —restart-server.sh가env.sh를 source 하다 즉사해 배포가 실패한다.
권장 조치
비밀은 설정 파일에 적지 않습니다. 사이드카 파일 하나에 모으고 0600 으로 둡니다.
ls -l /etc/kopens/plantpulse-platform.env # 비밀 — 0600, repo 밖
ls -l /etc/kopens/platform.node.env # 이 박스 고유 값 — 0600
# 값을 바꿀 때는 파일을 열지 말고 도구를 씁니다
cd /opt/kopens/plantpulse-platform-docker
bin/passwd.sh --list # 바꿀 수 있는 키
bin/passwd.sh PP_PG_PASSWORD # 서버 계정 변경 → 사이드카 → 재렌더 → 재시작
렌더된 설정 파일에는 치환이 끝난 값이 들어가므로, 그 파일을 저장소에 커밋하지 않습니다.