본문으로 건너뛰기

문제 해결

이 문서는 원라인 / Docker 설치로 운영되는 PlantPulse 플랫폼에서 자주 발생하는 문제와 해결 방법을 안내합니다. 대부분의 문제는 아래 절차를 순서대로 따라가면 해결할 수 있습니다.

컨테이너는 아홉 개입니다

플랫폼은 Docker Compose 스택으로 동작합니다 — 인증서 원샷 하나(plantpulse-certs, Exited (0) 이 정상), 데이터레이크 하나, 앱 여섯, 프록시 하나. plantpulse-platform 이라는 이름의 컨테이너는 없습니다.

「무엇이 고장났나」를 먼저 좁히세요. ./status.sh 가 서비스별로 답합니다 → 설치되는 모양

첫 단계: 어떤 문제든 우선 아래 3가지를 먼저 확인해 주세요.

cd /opt/kopens/plantpulse-platform-docker/bin
./status.sh # 컨테이너 / health / 볼륨 요약
./ops-check.sh # 운영 health + critical log
./logs.sh -n 200 # 최근 컨테이너 로그 (전체)

그래도 해결되지 않으면 ./doctor.sh 로 진단 tarball 을 생성하여 기술 지원팀에 전달해 주세요.

컨테이너 기동 문제

증상: 컨테이너가 unhealthy 상태에서 회복되지 않음

원인해결
Cassandra 스키마 마이그레이션 실패./logs.sh cassandra -n 300 으로 에러 확인 후 ./restart.sh 시도. 반복 실패 시 ./doctor.sh
데이터 디렉토리 권한 문제호스트의 /data1/pp-data 권한 확인. sudo chown -R root:root /data1/pp-data && sudo chmod -R 755 /data1/pp-data
메모리 부족 (OOMKilled)docker inspect <컨테이너> --format '{{.State.OOMKilled}}' 로 확인. 컨테이너마다 한계값이 다릅니다 — 데이터레이크는 DOCKER_DATALAKE_MEMORY, 앱은 DOCKER_SERVER_MEMORY 등 (환경 변수)
JVM warm-up 미완료부팅에는 3~5분 소요됨. 5분 이상 unhealthy 가 지속되면 다음 단계 진단
# 어떤 서비스가 비정상인가 (0 = 정상 / 2 = 비정상)
./status.sh

# 스택 전체 준비 판정
./stack-verify-boot.sh

# 컨테이너별 메모리 / CPU
docker stats --no-stream

# 헬스체크 엔드포인트 응답 확인
curl -kfsS https://<서버IP>:4950/api/health | jq
원샷은 「죽은 컨테이너」가 아닙니다

plantpulse-certs 는 인증서를 굽고 스스로 끝나므로 Exited (0) 이 성공 상태입니다. compose 가 이 컨테이너의 헬스체크를 명시적으로 꺼 두었기 때문에(healthcheck: disable) health 칸은 비어 있고, 정상 동작하는 컨테이너가 unhealthy 로 보이는 일도 없습니다. status.shops-check.sh 는 이 컨테이너만 종료 코드로 판정하니, 손으로 볼 때도 그렇게 봐 주세요.

증상: no such service · 컨테이너가 없다고 나옴

최초 설치가 완료되지 않았거나 ./remove.sh 로 컨테이너가 제거된 상태입니다.

옛 런북을 따라 plantpulse-platform 을 찾고 있었다면 그 이름의 컨테이너는 없습니다 — 이름은 ./status.sh 또는 ./logs.sh --list 로 확인하세요.

cd /opt/kopens/plantpulse-platform-docker/bin
./install.sh # 최초 설치
# 또는 OS 설정이 이미 끝났다면
./up.sh # 컨테이너 생성 + 기동

증상: address already in use (포트 충돌)

호스트에 이전 버전의 plantpulse 가 native 로 실행 중이거나 다른 서비스가 포트를 점유하고 있는 경우입니다.

# 호스트 native plantpulse 정지
pkill -ef plantpulse

# 특정 포트 점유 프로세스 확인 (예: 7500)
ss -tlnp | grep :7500

# 충돌 프로세스를 종료한 후 재시도
./restart.sh

상세 포트 목록은 포트 및 서비스 관리 페이지를 참고해 주세요.

이미지 / 레지스트리 문제

증상: docker pullunauthorized: authentication required

레지스트리 인증이 만료되었거나 자격증명이 없는 상태입니다.

docker login docker.kopens.io
# Username/Password 입력 후
./update.sh

증상: 이미지 다운로드 실패 (네트워크)

# 1. 레지스트리 접근 가능 여부 확인
curl -fsSL https://docker.kopens.io/v2/

# 2. DNS 확인
nslookup docker.kopens.io

# 3. 회사 방화벽 / 프록시 차단 가능성 — 네트워크 관리자에게 다음 도메인 허용 요청
# docker.kopens.io, download.kopens.io

폐쇄망 환경이라면 Docker 설치 페이지의 폐쇄망(Airgap) 설치 절차를 따라주세요.

데이터베이스 문제

데이터베이스 컴포넌트는 컨테이너 내부에서 동작합니다. 점검은 ./shell.sh 로 컨테이너에 진입한 뒤 수행합니다.

PostgreSQL (메타 DB)

역할: 사용자 정보, 사이트 설정, 자산 설정 등 플랫폼의 메타데이터를 저장합니다.

./shell.sh # 컨테이너 진입

# 컨테이너 내부에서
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node psql # PostgreSQL 셸 접속
psql=# SELECT 1;
psql=# SHOW max_connections;
psql=# SELECT count(*) FROM pg_stat_activity;
증상원인해결
Connection refusedPostgreSQL 컴포넌트 다운컨테이너 내부에서 pd restart storage 실행. 호스트에서는 ./restart.sh
Too many connections연결 풀 초과properties 의 connection pool 설정 검토. 일시적이면 storage 재시작
Authentication failed비밀번호 불일치/etc/kopens/plantpulse-platform.envPP_PG_PASSWORD 와 애플리케이션 properties 일치 여부 확인

경로 확인 — 시크릿 사이드카의 정본은 /etc/kopens/plantpulse-platform.env 하나입니다(권한 0600). 옛 설치에서 /opt/kopens/ 밑에 같은 이름이 남아 있을 수 있지만 읽지 않으며, 설치 스크립트가 정본으로 되돌립니다 → 환경 변수 레퍼런스

Cassandra (시계열 DB)

역할: 센서 시계열 데이터, 알람 이력 등 대량 데이터를 저장합니다.

./shell.sh

# 컨테이너 내부에서
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node status # 클러스터 상태
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node compactionstats # 컴팩션 진행 상태
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node cql # CQL 셸 접속
증상원인해결
Connection timeout노드 다운pd node status 로 노드 상태 확인 후 pd restart storage
WriteTimeout쓰기 지연 (디스크 I/O 포화)pd node compactionstats 확인, pd node compact 로 수동 컴팩션
ReadTimeout읽기 지연 (큰 파티션)pd node table-histograms 로 파티션 크기 확인
디스크 공간 부족SSTable 누적pd node cleanup 실행 후 df -h /data1 으로 확인

Valkey (Redis 캐시)

./shell.sh

# 컨테이너 내부에서
redis-cli -a "$PP_REDIS_PASSWORD" ping
redis-cli -a "$PP_REDIS_PASSWORD" INFO memory

로그인 / 콘솔 접속 문제

증상: 브라우저에서 콘솔에 접속이 안 됨

# 1. 컨테이너 health 확인
./status.sh

# 2. 외부 노출 IP 설정 확인
grep DOCKER_PP_EXTERNAL_IP env.sh

# 3. 호스트 방화벽 확인
sudo firewall-cmd --list-ports # RHEL/Rocky/Oracle
sudo ufw status # Ubuntu

# 4. 포트 점유 확인 — 프록시가 80/443 을, 데이터레이크가 7443 을 엽니다
ss -tlnp | grep -E ':(80|443|7443)\s'
증상원인해결
페이지가 열리지 않음plantpulse-proxy 가 비정상./status.sh 로 프록시 상태 확인. 프록시가 80/443 을 받는 유일한 입구입니다
페이지가 열리지 않음방화벽 차단회사/클라우드 방화벽에서 80, 443, 7443, 4950 허용 요청
로그인 실패비밀번호 불일치기본 admin / admin123! 확인. 변경했다면 관리자에게 초기화 요청
403 Forbidden사용자 권한 부족관리자에게 역할(role) 확인 요청
세션 만료30분 무활동 시 자동 로그아웃다시 로그인

데이터 수집 문제

데이터 수집 경로: OPC 서버 → 메시지 브로커(Kafka/MQTT) → 엔진 파이프라인 → Cassandra. 이 경로 중 한 곳이라도 막히면 데이터가 들어오지 않습니다.

증상: 데이터가 수집되지 않음

점검 항목확인 방법
OPC 연결 상태웹 콘솔 > 연결 관리 > 상태에서 CONNECTED 확인
엔진 상태콘솔 > 모니터링 > 시스템 상태에서 RUNNING 확인
파이프라인MPS(초당 메시지 수) 가 0 이면 수신 중단
메시지 브로커./shell.sh 진입 후 /opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node topic 로 Kafka 토픽 확인
네트워크OPC 서버 → 플랫폼 호스트 IP 핑 / telnet

증상: 데이터 지연

원인해결
파이프라인 큐 적체properties 의 engine.pipeline.threads 상향
Cassandra 쓰기 지연pd node compactionstats 확인, 디스크 I/O 모니터링
Kafka lagpd node topic 로 consumer lag 확인
네트워크 지연OPC 서버 ↔ 플랫폼 호스트 RTT 측정

성능 문제

증상: 콘솔 / API 응답이 느림

# 호스트에서 컨테이너 자원 사용량
docker stats --no-stream

# 앱 컨테이너의 JVM 메모리 (그 앱이 도는 컨테이너 안에서)
./shell.sh plantpulse-server-web
jmap -heap $(pgrep -f plantpulse-server)
어느 컨테이너인지 먼저 정하세요

앱 여섯은 각자 컨테이너에서 돌기 때문에, 데이터레이크 안에서 앱 프로세스를 찾으면 나오지 않습니다. ./status.sh 로 대상 컨테이너를 확인한 뒤 ./shell.sh <컨테이너> 로 들어가세요.

원인해결
컨테이너 메모리 부족해당 컨테이너의 한계값 상향 후 ./restart.sh — 데이터레이크는 DOCKER_DATALAKE_MEMORY, 앱은 DOCKER_SERVER_MEMORY 등 (환경 변수)
JVM 메모리 부족컨테이너 내부 setenv 의 힙 크기 조정 (자세한 내용은 성능 튜닝)
GC 빈번GC 로그 분석, G1GC 옵션 튜닝
DB 슬로우 쿼리PostgreSQL slow query 로그 확인
호스트 CPU 포화top / htop 확인 후 DOCKER_PP_CPUS 상향 검토

증상: OutOfMemoryError

# 컨테이너 내부에서 heap dump 활성화
./shell.sh
# setenv 또는 JAVA_TOOL_OPTIONS 에 -XX:+HeapDumpOnOutOfMemoryError 추가

# 생성된 hprof 를 호스트로 복사
docker cp plantpulse-datalake:/path/to/heap.hprof /tmp/

Eclipse MAT / VisualVM 으로 분석합니다.

알람 문제

증상원인해결
알람이 발생하지 않음알람 설정 미배포알람 설정 화면에서 "배포" 클릭
알람 중복 발생중복 체크 비활성화알람 설정에서 중복 체크 활성화
이메일 알림 미발송SMTP 설정 오류mail.properties 확인 (컨테이너 내부 /opt/kopens/plantpulse-platform/plantpulse-server/config/)
알림 소리 안남브라우저 자동재생 정책브라우저 설정에서 사이트 자동재생 허용

UI 문제

증상해결
화면이 깨짐브라우저 캐시 삭제 (Ctrl+Shift+Delete)
차트 미표시브라우저 개발자 도구(F12) > Console 에서 JS 에러 확인
실시간 갱신 끊김프록시/방화벽의 SSE(HTTP 스트리밍) 버퍼링·타임아웃 설정 확인
대시보드 로드 실패연결된 태그 / 데이터 소스 존재 여부 확인
한글 깨짐env.shPP_LANG=ko, PP_TZ=Asia/Seoul 확인 후 ./restart.sh

디스크 / 볼륨 문제

증상: 디스크 공간 부족

# 호스트 디스크 사용량
df -h
df -h /data1 # 데이터 디스크

# Docker 사용량 (이미지 / 볼륨 / 빌드 캐시)
docker system df

# 컨테이너 내부 사용량
./shell.sh
df -h
du -sh /opt/kopens/plantpulse-platform/plantpulse-storage/db/cassandra/data
원인해결
오래된 백업 누적/data1/pp-backup/docker-volume 의 오래된 tar.gz 정리
Docker 미사용 이미지docker system prune 으로 정리 (이미지/네트워크/캐시)
Cassandra SSTable 누적컨테이너 내부에서 pd node cleanup, pd node compact
로그 디렉토리 비대/opt/kopens/plantpulse-platform-docker/logs 정리

주의: docker volume prune 은 사용 중이 아닌 볼륨을 모두 삭제합니다. pp-* 볼륨이 실수로 지워지지 않도록 컨테이너를 정지 상태로 두지 마세요.

증상: 볼륨 데이터 복구가 필요

운영 관리 - 백업과 복구 페이지의 복구 절차를 참고해 주세요.

업데이트 / 롤백 문제

증상: 업데이트 후 컨테이너가 정상 동작하지 않음

./update.sh 는 health 검증에 실패하면 자동으로 이전 이미지로 rollback 합니다. 수동 rollback 이 필요한 경우:

# 1. 이전 버전 태그를 env.sh 에 지정
vi env.sh
# PP_IMAGE_TAG="2026.04" ← 이전 안정 버전

# 2. 업데이트 재실행
./update.sh

증상: 업데이트 중 NOT FOUND CONTAINER

최초 설치(./install.sh)가 안 된 상태입니다. 먼저 설치를 수행해 주세요.

네트워크 / 클러스터 문제

증상: 워커가 마스터에 join 되지 않음

# 1. 워커 컨테이너 진입 (워커는 기본 스택의 서비스가 아니라 shell.sh 로는 잡히지 않습니다)
docker exec -ti plantpulse-worker-1 /bin/bash
# 워커 내부에서 마스터 IP 로 연결 테스트
ping ${PP_MASTER_IP}

# 2. 마스터에서 링 확인 — 이것이 조인의 «유일한» 증거입니다
cd /opt/kopens/plantpulse-platform-docker/bin
./shell.sh
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node status

# 3. JGroups / Cassandra 포트 (7000, 7001, 7800, 7801, 9042) 방화벽 허용 확인
컨테이너가 떠 있다는 것은 조인의 증거가 아닙니다

조인에 실패한 워커도 성공한 워커와 똑같이 정상으로 보고합니다 — 컨테이너의 자체 검사는 «마스터에 닿는가»만 보기 때문입니다. 2026-08-31 실측으로 Cassandra 가 OOMKilled 된 워커가 링은 1노드인 채로 health: starting 을 유지했습니다.

반드시 pd node status 의 링 목록으로 판정하세요. 워커 추가는 bin/worker-add.sh 가 이 확인을 대신 해 줍니다 → 클러스터 설치

증상: MQTT / Kafka 외부 클라이언트 연결 실패

호스트 방화벽과 회사/클라우드 방화벽에서 1883/1884 (MQTT), 9092/9093/9094 (Kafka) 가 허용되었는지 확인해 주세요. 자세한 포트 목록은 포트 구성 정보 를 참고해 주세요.

  • MQTT 는 plantpulse-proxy 가 받습니다. 설비는 이 호스트만 알면 되고, 브로커가 옮겨가거나 이름이 바뀌어도 설비 설정을 건드릴 필요가 없습니다. 1884 는 TLS passthrough 라 브로커가 TLS 를 종단합니다.
  • Kafka 는 프록시를 거치지 않습니다. 클라이언트가 부트스트랩 후 advertised.listeners 주소로 다시 접속하기 때문입니다 — 부트스트랩만 성공하고 그 뒤가 조용히 실패한다면 이 주소를 먼저 의심하세요.

긴급 대응

컨테이너가 응답하지 않을 때

cd /opt/kopens/plantpulse-platform-docker/bin

# 1. 상태 확인
docker ps -a
./status.sh

# 2. 로그에서 마지막 에러 확인
./logs.sh -n 200

# 3. 안전 재시작
./restart.sh

# 4. 위 단계로 회복 안 될 경우 진단 tarball 생성
./doctor.sh
# 생성된 tarball 을 webmaster@kopens.com 으로 전달

데이터 손상 의심 시

# 1. 즉시 정지 (추가 손상 방지)
./down.sh

# 2. 최신 백업 확인
ls -lh /data1/pp-backup/docker-volume/

# 3. 진단 tarball 생성 (절대 데이터를 임의로 수정하지 마세요)
./doctor.sh

# 4. 기술 지원팀 연락

데이터 손상 시 금지 사항: 직접 pd node repair, pd node cleanup, SSTable 삭제 등을 수행하지 마세요. 잘못된 복구 작업은 손상을 확대시킬 수 있습니다. 반드시 기술 지원팀과 협의 후 진행해 주세요.

지원 요청 시 필요한 정보

위 방법으로 해결되지 않으면 아래 정보를 함께 보내주시면 빠른 분석이 가능합니다.

항목수집 방법
진단 tarball./doctor.sh 실행 후 생성된 파일
컨테이너 로그./logs.sh -n 500 > /tmp/container.log 2>&1 (여덟 컨테이너 전부)
모듈별 로그./tools/copy-log-to-local.sh 결과 (/tmp/plantpulse-log/)
이미지 버전./stack-version.sh 출력
환경 변수env.sh (비밀번호는 마스킹)
시스템 정보OS, CPU, 메모리, 디스크 (uname -a, free -h, df -h)
에러 메시지정확한 에러 메시지 / 브라우저 콘솔(F12) 캡처
재현 절차문제 발생 직전에 수행한 작업 순서

기술 지원: webmaster@kopens.com

관련 문서