env 환경 설정 — env.sh / PPLANG / CERTPASS / -Dpe.conf.dir
이 문서에 나오는 비밀번호(CERT_PASS 등)는 사내 dev 박스의 기본값이며 비밀이 아니다.
고객사/양산 배포에서는 그대로 쓰지 않는다:
install.sh는CERT_PASS미지정 시 14자 랜덤을 생성한다(bin/install.sh:298). 생성된 값은/etc/kopens/credentials.txt(0600, root) 와 factory 라벨에 기록된다.- 박스 OS 접속 비밀번호도 설치 시 변경한다.
- 따라서 문서의 기본값이 유효한 범위는 사내 dev 박스 한 대뿐이다.
PlantPulse Edge 의 설정은 두 레이어로 나뉩니다.
| 레이어 | 무엇 | 어디 |
|---|---|---|
| 환경 변수 (env) ← 이 페이지 | 언어/시간대, JDK 경로, TLS 비번, 데이터 경로, 설치 시 사이트 값 | env.sh / /etc/kopens/*.env / systemd / docker -e |
| 애플리케이션 설정 (properties) | edge.id / cassandra.* / mqtt.* / OPC-UA 등 런타임 키 | app.properties → app.properties 가이드 |
env 레이어가 언어 · 시간대 · JVM 옵션 · 비밀번호 · 설정 디렉터리 위치를 결정하면, 그 위에서
app.properties 가 동작합니다. 박스 단위로 한 번 정하면 거의 바뀌지 않는 값들입니다.
1. 핵심 env 변수 한눈에
| 변수 | 의미 | 기본값 |
|---|---|---|
PP_LANG | UI/OS/JVM 언어 (BCP 47) — 박스 단위 단일 언어 | en |
PP_TZ | 시간대 (java.util.TimeZone ID) | Asia/Seoul |
JAVA_HOME | JDK 경로 (class file 65 → JDK 21) | /usr/lib/jvm/java-21-openjdk |
PE_HOME | 게이트웨이 루트 | /opt/kopens/plantpulse-edge |
PE_DATA_DIR | 데이터 디렉터리 (Cassandra/Redis/HiveMQ/Node-RED) | /data1 |
CERT_PASS | TLS keystore 비번 (Tomcat/HiveMQ/OPC-UA 공통) | kopens123! (legacy) / 설치 시 random |
CLEAN_ON_STARTUP | 부팅 시 work/temp 정리 여부 | false |
JAVA_TOOL_OPTIONS | 모든 JVM 공통 옵션 (entrypoint/setenv.sh 가 언어/시간대 주입) | (자동 구성) |
CERT_PASS / SERVER_API_KEY / 각종 password 는 shell history, ps argv, 로그에 노출되면 안 됩니다.
*_FILE 주입(예: EDGE_ADMIN_PASSWORD_HASH_FILE, CASSANDRA_PASSWORD_FILE)이나 root 0600 파일을
source 한 뒤 설치를 실행하세요. install.sh 가 생성하는 random 자격증명은 /etc/kopens/credentials.txt
(chmod 0600 root) 에 1회 저장됩니다.
2. 언어 / 시간대 — PP_LANG / PP_TZ
PlantPulse 는 박스 단위 단일 언어/시간대를 강제합니다. 사용자별 cookie / Accept-Language 는
무시되고, webapp + 호스트 OS + 컨테이너 OS + JVM 이 모두 같은 값을 씁니다.
PP_LANG=en PP_TZ=Asia/Seoul # 글로벌 default (영문 UI + 한국 시간)
PP_LANG=ko PP_TZ=Asia/Seoul # 완전 한국 박스
PP_LANG=en PP_TZ=UTC # 완전 영문 박스
2.1 전파 chain (4 layer)
env.sh / i18n.env ─→ install.sh ─→ systemd EnvironmentFile + docker -e ─→ container-entrypoint.sh ─→ webapp PpFixedLocaleResolver
(값 정의) (host locale) (PP_LANG / PP_TZ 주입) (OS LANG/TZ + JAVA_TOOL_OPTIONS) (UI 언어 결정)
2.2 컨테이너에서 entrypoint 가 하는 일
container-entrypoint.sh 가 PP_LANG 을 POSIX locale 로 매핑하고 JVM 옵션을 구성합니다:
PP_LANG="${PP_LANG:-en}"; PP_TZ="${PP_TZ:-Asia/Seoul}"
case "$PP_LANG" in
ko|ko_*|ko-*) LANG=ko_KR.UTF-8 ; lang=ko country=KR ;;
en|en_*|en-*) LANG=en_US.UTF-8 ; lang=en country=US ;;
esac
export LANG TZ="$PP_TZ"
ln -sf "/usr/share/zoneinfo/$PP_TZ" /etc/localtime
# 모든 JVM 프로세스 통일
export JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -Duser.language=$lang -Duser.country=$country -Duser.timezone=$PP_TZ"
/etc/locale.conf, /etc/environment, /etc/timezone 에도 기록되어 재로그인/도구 호출에도 유지됩니다.
언어는 부팅 시 한 번 결정되며 cookie / Accept-Language 로 못 바꿉니다.
ko↔en 토글은 PP_LANG 변경 + 컨테이너/Tomcat 재시작이 필요합니다.
2.3 native 모드의 LOCALE (setenv.sh)
native 에선 server/bin/setenv.sh 의 LOCALE 이 동적이어야 합니다 — 옛 hardcode
-Duser.language=ko -Duser.country=KR 가 JAVA_TOOL_OPTIONS 보다 우선되어 ko 가 이기던 사례가 있었습니다.
# server/bin/setenv.sh
LOCALE="-Duser.language=${PP_LANG:-en} -Duser.country=${PP_COUNTRY:-US} -Duser.timezone=${PP_TZ:-Asia/Seoul}"
그리고 conf/env.sh 에 export PP_LANG / export PP_TZ / export JAVA_HOME=/usr/lib/jvm/java-21-openjdk.
3. native conf/env.sh
native 박스의 환경 파일입니다. bin/start.sh 가 기동 전에 source 합니다.
# $PE_HOME/conf/env.sh
export PE_HOME=/opt/kopens/plantpulse-edge
export PE_DATA_DIR=/data1
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk # JDK 21 — class file 65 호환 (필수)
export PP_LANG="${PP_LANG:-en}"
export PP_TZ="${PP_TZ:-Asia/Seoul}"
export CLEAN_ON_STARTUP=false
| 키 | 의미 |
|---|---|
PE_HOME | 게이트웨이 루트 (스크립트 기준 경로) |
PE_DATA_DIR | 데이터 분리 디렉터리 (보통 별도 파티션 /data1) |
JAVA_HOME | JDK 21 미지정 시 UnsupportedClassVersionError |
PP_LANG / PP_TZ | 언어 / 시간대 (위 2장) |
CLEAN_ON_STARTUP | 부팅 시 work/temp 정리 |
native 설치 구조 전체는 네이티브 설치를 봅니다.
4. 컨테이너 /etc/kopens/*.env (systemd EnvironmentFile)
컨테이너 박스에선 systemd unit 이 아래 파일들을 EnvironmentFile 로 읽어 docker -e 로 주입합니다.
파일이 있으면 unit 내장 기본값을 override 합니다.
| 파일 | 키 | 생성자 | 용도 |
|---|---|---|---|
/etc/kopens/version.env | PE_VERSION=<tag> | OTA upgrade.sh | 이미지 tag 고정 — OTA/rollback 이 이 한 줄만 변경 |
/etc/kopens/i18n.env | PP_LANG / PP_TZ | install.sh | 언어 / 시간대 |
/etc/kopens/cert.env | CERT_PASS | TLS 발급 스크립트 | keystore 비번 |
# plantpulse-edge.service (발췌)
EnvironmentFile=-/etc/kopens/version.env
EnvironmentFile=-/etc/kopens/i18n.env
EnvironmentFile=-/etc/kopens/cert.env
Environment=PE_VERSION=latest
Environment=KOPENS_IMAGE=docker.kopens.io/pe/plantpulse-edge
Environment=PP_LANG=en
Environment=PP_TZ=Asia/Seoul
Environment=CERT_PASS=kopens123!
언어를 바꾸려면:
sudo tee /etc/kopens/i18n.env <<'EOF'
PP_LANG=ko
PP_TZ=Asia/Seoul
EOF
sudo systemctl restart plantpulse-edge.service
systemd unit 전체 해부는 도커 설치 §4.
5. 설정 디렉터리 위치 — -Dpe.conf.dir
app.properties 와 log4j2.xml 을 어디서 읽을지를 결정하는 핵심 env/시스템 프로퍼티입니다.
WAR 모드(2026-06-13~)에서 설정은 호스트 /etc/kopens 에서 직접 읽혀 — 이미지/배치 재빌드가 필요 없습니다.
| 모드 | -Dpe.conf.dir | canonical 파일 |
|---|---|---|
| 컨테이너 | /opt/kopens/plantpulse-edge/conf (= host /etc/kopens/conf bind-mount) | /etc/kopens/app.properties |
| native | $PE_HOME/conf | $PE_HOME/conf/app.properties |
- 컨테이너: 호스트
/etc/kopens/conf/app.properties가 실파일이자 source-of-truth./etc/kopens/app.properties는 그것을 가리키는 legacy 호환 심링크다 (ln -sfn /etc/kopens/conf/app.properties /etc/kopens/app.properties). log4j2.xml은 코드 산출물 — entrypoint 가 매 부팅 webapp default 에서 복사(로그레벨만 바꾸고 restart 하면 반영, 이미지 재빌드 불필요).
설정 키 자체(무엇을 적는가)는 app.properties 가이드와 환경 설정 화면을 봅니다. 이 페이지는 그 파일을 어디서/어떻게 읽는가를 다룹니다.
6. install.sh 설치 시 env override
설치 시점에 박스 사이트 값/네트워크/자격증명을 env 로 주입합니다 (install.sh 가 app.properties 에 반영).
sudo PROFILE=production \
EDGE_ID=EDGE_00303 \
SITE_ID=SITE_00001 \
SERVER_HOST=192.168.0.41 \
SERVER_API_KEY='<platform-api-key>' \
PP_LANG=en PP_TZ=Asia/Seoul \
CERT_PASS='<keystore-pass>' \
bash install.sh
| 변수 | 의미 | 기본값 |
|---|---|---|
PROFILE | production / staging / standalone / airgap preset | — |
EDGE_ID | 박스 고유 ID (^EDGE_[A-Z0-9_]{1,60}$) | MAC 기반 자동 생성 |
SITE_ID | 사이트 ID (플랫폼 등록 필수) | SITE_00001 |
DEV_MODE | EDGE (플랫폼 연결) / STANDALONE (미연결) | EDGE |
SERVER_HOST / SERVER_API_KEY | 플랫폼 API 연동 (EDGE 모드 필수) | — |
PP_LANG / PP_TZ | 언어 / 시간대 | en / Asia/Seoul |
ADMIN_PASS / API_KEY / MQTT_PASS / OPCUA_PASS | 초기 자격증명 override | 박스별 random |
CERT_PASS | TLS keystore 비번 | kopens123!(legacy) / random |
CERT_DOMAIN / CERT_SAN_DNS / CERT_SAN_IP | 인증서 CN / SAN | plantpulse.io / 자동 |
NET1_IFACE / NET2_IFACE …, NET2_IP / NET2_GATEWAY / NET2_DNS | NIC 매핑 / static IP | 자동 감지 / DHCP |
IMAGE_TAG | docker 이미지 tag 고정 | latest |
SKIP_PULL=1 | docker pull 생략 (airgap/재실행) | 0 |
SKIP_COSIGN_VERIFY=1 | 이미지 서명 검증 생략 | 0 (staging/standalone 1) |
dev.mode는EDGE와STANDALONE둘 다 지원하고PLATFORM만 reject 됩니다.STANDALONE시SERVER_HOST/SERVER_API_KEY프롬프트는 생략됩니다 (server.hostblank →DiagnosticSenderinit skip).
7. JVM heap env (컨테이너)
| env | 컴포넌트 | 기본 | override 예 |
|---|---|---|---|
HIVEMQ_HEAP | HiveMQ | -Xms2g -Xmx2g | 1g |
CASSANDRA_HEAP | Cassandra | host /proc/meminfo 기반 auto (~1/4) | 1g |
TOMCAT_HEAP | Tomcat | -Xms2g -Xmx2g | 1g |
8GB 박스 drop-in override(override.conf)는 컨테이너 모드 §자원 한도에 있습니다.
8. 변경 후 반영
| 바꾼 것 | 반영 방법 |
|---|---|
PP_LANG / PP_TZ (i18n.env / env.sh) | 컨테이너/Tomcat 재시작 (locale 은 부팅 1회) |
CERT_PASS (cert.env) | 컨테이너 재시작 (entrypoint 가 keystore 비번 재패치) |
PE_VERSION (version.env) | systemctl restart plantpulse-edge.service |
app.properties (컨테이너) | config.sh --set … && config.sh --restart |
app.properties (native) | vi conf/app.properties → bin/restart.sh (~6초) |
PP_LANG 을 app.properties 에 적는다고 적용되지 않습니다 — 언어는 env 레이어(env.sh / i18n.env)가
결정합니다. 반대로 cassandra.host 같은 런타임 키는 env 가 아니라 app.properties 에 적습니다.
9. 자주 빠지는 함정
| 증상 | 원인 / 해결 |
|---|---|
| UI 언어가 안 바뀜 | app.properties 에 적었거나 재시작 안 함. i18n.env(컨테이너)/env.sh(native) 수정 후 재시작 |
| native 에서 ko 가 계속 이김 | setenv.sh LOCALE 이 hardcode. ${PP_LANG} 동적화 (위 2.3) |
UnsupportedClassVersionError | JAVA_HOME 가 JDK 21 아님 |
| OPC-UA keystore password 오류 | cert.env 의 CERT_PASS 와 opc.ua.server.keystore.password=${ENV:CERT_PASS:} mirror 불일치 |
비밀번호가 ps/로그에 노출 | argv 대신 *_FILE 또는 root 0600 env 파일 source |
| 설정 변경이 반영 안 됨 | -Dpe.conf.dir 가 가리키는 canonical 파일을 안 고침 (컨테이너=/etc/kopens, native=$PE_HOME/conf) |
10. 다음 문서
- app.properties 가이드 — 런타임 설정 키 전체
- 환경 설정 화면 (
/ui/system/config) — 웹에서 app.properties 편집 - 네이티브 설치 / 도커(컨테이너) 설치 상세
- 빠른 설치 (
install.sh) — 설치 시 env 주입 절차 - 컨테이너 모드 운영 가이드 — config.sh / 자원 한도 / OTA