본문으로 건너뛰기

도커(컨테이너) 설치 상세 — plantpulse-edge.service

2026.05 부터 PlantPulse Edge 의 양산/현장 표준 배포는 단일 Docker 컨테이너 이미지입니다. 7개 컴포넌트(Tomcat / Cassandra / Redis / HiveMQ / TSE / Dashboard / Node-RED)가 하나의 이미지 안에 들어있고, install.sh 가 OS 의존성부터 systemd 등록까지 처리한 뒤 plantpulse-edge.service 가 컨테이너를 관리합니다.

빠른 설치 vs 이 페이지

현장에서 1대를 빠르게 올리는 절차 요약빠른 설치 (install.sh)에 있습니다. 이 페이지는 그 설치가 내부에서 무엇을 하는지 — 이미지 좌표, docker run 플래그, bind mount, EnvironmentFile, OTA — 를 깊게 파고드는 레퍼런스입니다. 일상 운영은 컨테이너 모드 운영 가이드를 봅니다.

native 와 동시 사용 금지

컨테이너는 plantpulse-edge.service, native 는 plantpulse.service. systemd unit 에 Conflicts=plantpulse.service 가 걸려 있지만, 두 서비스를 강제로 같이 띄우면 포트/데이터가 충돌합니다.


1. 이미지 좌표

항목
Registrydocker.kopens.io/pe (anonymous pull)
이미지명plantpulse-edge
전체 좌표docker.kopens.io/pe/plantpulse-edge:<tag>
Tag 형식<VERSION>-<BUILD_DATE> 예: 2026-20260524 (또는 latest)
다운로드 서버https://product.kopens.io/plantpulse-edge/ (LAN alias)

이미지 안 고정 경로: KOPENS_HOME=/opt/kopens, PE_HOME=/opt/kopens/plantpulse-edge, PE_DATA_DIR=/data1, JAVA_HOME=/usr/lib/jvm/java-21-openjdk.


2. 설치 흐름 — bootstrap.shinstall.sh

2.1 원라이너

curl -fsSL https://product.kopens.io/plantpulse-edge/install.sh | sudo bash

install.shbootstrap.sh 와 동일합니다. 이 스크립트가:

  1. repo tarball(plantpulse-edge-docker.tar.gz)을 /opt/kopens/plantpulse-edge-docker/ 로 펼침 (실패 시 git clone fallback)
  2. PROFILE preset 적용(있으면, 아래 3장)
  3. 대화형 prompt — Edge ID (MAC 기반 자동 제시) / Site ID (기본 SITE_00001) / Mode (1=EDGE 기본 / 2=STANDALONE) / EDGE 모드면 플랫폼 서버 + API key
  4. install.sh 본체 9단계 실행

2.2 install.sh 9단계

#단계
1OS 감지 (Rocky/Alma/RHEL/Ubuntu/Debian)
2Docker 설치 (dnf 또는 apt)
3/data1, /etc/kopens, /var/log/kopens 디렉터리 생성
4sysctl + firewalld 포트 + chrony + hostname + nmcli static IP
5/etc/kopens/app.properties 생성 (EDGE_ID / SITE_ID / 박스별 random 자격증명)
6systemd unit 설치 — plantpulse-edge.service + OTA kopens-upgrade.path/.service
7docker pull (cosign 서명 검증 — 기본 soft-fail)
8systemctl enable --now plantpulse-edge.service
9cron weekly cleanup 등록

첫 설치 시 admin / MQTT / OPC-UA / API key / keystore 비번이 박스별 random 으로 생성되어 /etc/kopens/credentials.txt (chmod 0600 root) 에 1회 저장됩니다.


3. PROFILE preset

PROFILE env 로 사이트 유형별 기본값을 한 번에 적용합니다.

PROFILE적용 기본값
productionDEV_MODE=EDGE (플랫폼 SERVER_HOST/SERVER_API_KEY 명시 필요)
stagingDEV_MODE=EDGE, EDGE_ID=EDGE_00303, SITE_ID=SITE_00001, SERVER_HOST=192.168.0.235, SKIP_COSIGN_VERIFY=1
standaloneDEV_MODE=STANDALONE, SKIP_COSIGN_VERIFY=1 (플랫폼 미연결)
airgapIMAGE_URL=tarball, SKIP_PULL=1, DEV_MODE=STANDALONE (오프라인 설치)
# 양산 (플랫폼 연결)
curl -fsSL https://product.kopens.io/plantpulse-edge/install.sh \
| sudo PROFILE=production EDGE_ID=EDGE_00303 \
SERVER_HOST=10.0.0.5 SERVER_API_KEY=<uuid> bash

# 단독 운영 (플랫폼 없이)
curl -fsSL https://product.kopens.io/plantpulse-edge/install.sh \
| sudo PROFILE=standalone EDGE_ID=EDGE_LOCAL_01 bash
staging = dev 클론

staging 박스는 dev 와 같은 EDGE_00303 / SITE_00001 클론입니다. 달라야 하는 건 플랫폼 연결정보(SERVER_HOST=192.168.0.235 / API key) 뿐. 플랫폼에 미등록된 site 를 쓰면 엣지 자기-진단 OPC 가 FK 위반으로 실패하므로 등록된 EDGE/site 를 그대로 씁니다. dev 와 동시에 플랫폼에 연결하면 같은 edge 로 인식되니 검증은 겹치지 않게 운영합니다.

설치 시 자주 쓰는 env 전체 목록은 env 환경 설정 §6을 봅니다.


4. systemd unit 해부 — plantpulse-edge.service

install.sh/etc/systemd/system/plantpulse-edge.service 로 배치하는 실제 컨테이너 기동 정의입니다.

4.1 docker run (ExecStart)

/usr/bin/docker run --rm --name plantpulse-edge \
--network=host \
--init \
--stop-timeout=120 \
-v /data1:/data1:z \
-v /etc/kopens:/etc/kopens:z \
-v /etc/kopens/conf:/opt/kopens/plantpulse-edge/conf:z \
-v /var/security:/var/security:rw,z \
-v /etc/localtime:/etc/localtime:ro \
-v /var/run/docker.sock:/var/run/docker.sock \
-e PP_LANG=${PP_LANG} \
-e PP_TZ=${PP_TZ} \
-e CERT_PASS=${CERT_PASS} \
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
--cap-add=NET_RAW \
--cap-add=DAC_OVERRIDE \
--cap-add=CHOWN \
--cap-add=FOWNER \
--log-driver=journald \
--log-opt tag="plantpulse-edge" \
${KOPENS_IMAGE}:${PE_VERSION}
플래그의미
--network=host9개 포트 자동 노출 + multicast / OPC-UA discovery 자연스러움
--inittini 가 PID 1 (zombie reap + signal forward)
--stop-timeout=120Cassandra graceful drain 시간 확보
--cap-drop=ALL + 개별 --cap-add최소 권한. NET_RAW 는 PLC ping, NET_BIND_SERVICE 는 80/443 바인드

4.2 bind mount

Host 경로컨테이너 경로모드용도
/data1/data1rw,z데이터 (Cassandra/Redis/HiveMQ/Node-RED) — 컨테이너 교체에도 보존
/etc/kopens/etc/kopensrw,z설정 + 시그널 파일
/etc/kopens/conf/opt/kopens/plantpulse-edge/confrw,zapp.properties / log4j2.xml
/var/security/var/securityrw,zTLS keystore
/etc/localtime/etc/localtimero호스트 시간대
/var/run/docker.sock/var/run/docker.sockrw/ui/apps 도커 앱 관리

4.3 EnvironmentFile + 기본값

unit 내장 기본값(파일 없을 때):

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!

EnvironmentFile (있으면 override — 최신 값 우선):

파일생성자
/etc/kopens/version.envPE_VERSION=<tag>OTA upgrade.sh
/etc/kopens/i18n.envPP_LANG / PP_TZinstall.sh
/etc/kopens/cert.envCERT_PASSTLS 발급 스크립트

4.4 자원 한도 / 재시작 정책

MemoryMax=12G # 16GB 박스 기준 — 호스트 OOM 방지
MemoryHigh=11G
CPUQuota=600% # 6 cores
TasksMax=8192

Restart=on-failure
RestartSec=30s
TimeoutStartSec=300
TimeoutStopSec=180

8GB 박스용 heap 축소 override(drop-in)는 컨테이너 모드 §자원 한도를 봅니다.


5. 컨테이너 런타임 설정 읽기 경로

WAR 모드(2026-06-13~)에서 설정은 호스트의 /etc/kopens 에서 직접 읽습니다 — 이미지 재빌드 불필요.

/etc/kopens/app.properties ← 운영자가 편집하는 canonical
│ (entrypoint 가 symlink 생성)

/etc/kopens/conf/app.properties ──bind──▶ /opt/kopens/plantpulse-edge/conf/app.properties

Tomcat setenv.sh: -Dpe.conf.dir=/opt/kopens/plantpulse-edge/conf
  • app.properties: 호스트 /etc/kopens/app.properties 가 source-of-truth. 없으면 entrypoint 가 image default 로 seed. 운영자 편집 → config.sh --restart 로 반영.
  • log4j2.xml: entrypoint 가 매 부팅 webapp default 에서 conf/log4j2.xml 로 복사(코드 산출물 — 이미지 재빌드 없이 로그레벨 변경 후 restart).
  • HiveMQ auth.properties: entrypoint 가 매 부팅 app.propertiesmqtt.server.* 와 자동 sync — app.properties 만 고치면 됩니다.
  • TLS 비번: entrypoint 가 CERT_PASScert.env 에서 해석해 Tomcat server.xml / HiveMQ config / OPC-UA keystore 비번을 일괄 패치.

자세한 env→설정 미러링은 env 환경 설정, 키별 의미는 app.properties 가이드.


6. OTA 업그레이드 / 롤백

버전은 /etc/kopens/version.envPE_VERSION 한 줄로 고정됩니다 — OTA 가 이 파일만 바꾸고 restart.

# 최신으로 업그레이드 (pre-snapshot → pull → restart → 90초 health probe → 실패 시 auto-rollback)
sudo bash /opt/kopens/install/upgrade.sh

# 특정 tag 로
sudo bash /opt/kopens/install/upgrade.sh --to 2026-20260601

# 직전 tag 로 rollback
sudo bash /opt/kopens/install/upgrade.sh --rollback

# 새 빌드 존재만 확인
sudo bash /opt/kopens/install/upgrade.sh --check

수동 롤백:

echo 'PE_VERSION=2026-20260524' > /etc/kopens/version.env
sudo systemctl restart plantpulse-edge.service

상태: cat /etc/kopens/upgrade.statusidle | running | success | rolling-back | rolled-back | error. 흐름 상세는 컨테이너 모드 §OTA.


7. 디버그용 수동 docker run

운영은 반드시 systemd / install.sh 경유지만, 격리 디버그 시 수동 기동:

sudo docker run --rm --name pe-debug \
--network=host --init \
-v /data1:/data1:z \
-v /etc/kopens:/etc/kopens:z \
-v /etc/kopens/conf:/opt/kopens/plantpulse-edge/conf:z \
-v /var/security:/var/security:rw,z \
-e PP_LANG=en -e PP_TZ=Asia/Seoul -e CERT_PASS="$(. /etc/kopens/cert.env; echo $CERT_PASS)" \
docker.kopens.io/pe/plantpulse-edge:<tag>

배포는 파이프라인 경유만 — 이미지 (re)build / push / staging 재배포는 로컬에서 하지 말고 plantpulse-edge-docker 의 릴리즈 체인(edge:libsedge:deploy-devedge:imageedge:stagingedge:version, 파이프라인 변수 RELEASE=1 로 트리거)으로 합니다. 위 명령은 격리 디버그 한정.


8. 설치 후 검증

systemctl is-active plantpulse-edge.service
sudo bash /opt/kopens/install/bin/status.sh

# version: container_mode=true 여야 함
curl -ks https://127.0.0.1/api/v1/system/version | python3 -m json.tool
# health: HTTP 200 + components UP
curl -ks https://127.0.0.1/api/v1/system/health | python3 -m json.tool
화면URL
웹 UIhttps://<게이트웨이-IP>/ui/main
Node-REDhttps://<게이트웨이-IP>/ui/flow/
Swagger UIhttps://<게이트웨이-IP>/public/swagger-ui/index.html

증상별 조치는 설치 트러블슈팅, 일상 운영/장애는 컨테이너 모드 운영 가이드.


9. 다음 문서