4c1dc4082e
Build and Push Images / build-and-push (push) Has been cancelled
이전 세션들에서 작업된 아래 범위를 모두 포함: Fleet 서브시스템 (src/fleet/) - fleetDeviceService / fleetCommandService / fleetDeploymentService / fleetReleaseService - fleetMetricsService, fleetScriptService, fleetEdgeConfigService - Edge 디바이스 관리, 커맨드 발행, 배포/릴리스, 스크립트 동기화 Collector 확장 - centralMqttForwarder / centralForwarderConfigService - equipmentStateService, pythonHookRunner, scriptCache - Modbus/OPC-UA/S7/XGT 프로토콜 클라이언트 - targetDbIntrospection (저장 DB 조회) Routes / API - automationDashboardRoutes, centralForwarderRoutes, equipmentStateRoutes DB - importEdgeConfig (Python cached config → Pipeline DB) - seedDataSources (external_db_connections 초기 시드) 엣지 배포 리소스 - docker/edge/Dockerfile.backend.prod, Dockerfile.frontend.prod - docker/edge/docker-compose.edge.yml 프론트엔드 - admin/automaticMng (centralForwarder, dashboard, equipmentState) - admin/fleet (commands, devices, deployments, releases, scripts, alerts) - admin/pipeline-device 개선 (저장 DB 드롭다운, 태그 매핑 등) - ExternalDbConnectionModal, ScriptsManagerDialog 등 신규 컴포넌트 - lib/api: automationDashboard, centralForwarder, equipmentState, fleet docs/ - EDGE_SERVER_STRUCTURE, FLEET_COMPLETE, FLEET_EDGE_INTEGRATION, FLEET_HOOK_INTEGRATION Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.1 KiB
6.1 KiB
Pipeline Edge Deployment
스피폭스 등 고객사 엣지 서버에 Pipeline을 올려 기존 Python data-collector + Kafka + forwarder를 완전 대체합니다.
기존 vs 신규 구조
[기존]
PLC → Python data-collector → 로컬 Kafka → kafka-to-central-mqtt → IDC EMQX → TimescaleDB
[신규 — Pipeline 단일 서비스]
PLC → Pipeline (XGT/Modbus/OPC UA/S7 직접 수집 + Python 훅 실행) → IDC EMQX → TimescaleDB
Pipeline이 다음 역할을 모두 수행:
- 장비 폴링 (XGT/Modbus/OPC UA/S7)
- Python 훅 실행 (transform/filter/derived_tags,
python3서브프로세스) - 로컬 현재값 스냅샷 (
equipment_current_state) - IDC MQTT 포워딩 (
dt/v1/data/{company_id}/{edge_id}) - 재시도 큐 (
central_mqtt_forwarder_retry_queue) - 모든 것을 UI에서 관리
1. 이미지 빌드 & 푸시 (최초 1회, 로컬에서)
cd /Users/chpark/workspace/vexplor_Pipeline
# 백엔드 프로덕션 이미지
docker build \
-f docker/edge/Dockerfile.backend.prod \
-t harbor.wace.me/vexplor_fleet/pipeline-backend:latest \
./backend-node
docker push harbor.wace.me/vexplor_fleet/pipeline-backend:latest
# (선택) 프론트엔드 이미지 — 엣지에서 UI 직접 띄우려면
docker build \
-f docker/dev/frontend.Dockerfile \
-t harbor.wace.me/vexplor_fleet/pipeline-front:latest \
./frontend
docker push harbor.wace.me/vexplor_fleet/pipeline-front:latest
2. 엣지 서버 준비 (스피폭스 112.168.212.142)
⚠️ 병행 운영 모드 기존 Python data-collector / fleet-agent / kafka-to-central-mqtt는 절대 중지하지 않고 그대로 둡니다. Pipeline은 옆에서 별도로 기동해 "연결/수집/포워딩이 잘 되는지"만 검증합니다. 안정성 확인 후 사용자가 판단해서 기존 컨테이너 중지 여부 결정.
ssh wace@112.168.212.142
# Harbor 로그인
docker login harbor.wace.me
# Pipeline 전용 디렉토리 (기존 data-collector와 분리)
mkdir -p /home/wace/pipeline-edge
cd /home/wace/pipeline-edge
포트 충돌 확인 (기존 컨테이너와 겹치지 않는지)
# 기존 스피폭스 엣지의 포트 사용 현황 확인
docker ps --format 'table {{.Names}}\t{{.Ports}}' | grep -E '8080|1883|8083|9771'
만약 겹치면 Pipeline 쪽 포트를 바꿔 기동 (compose에서 ports: 좌측 값만 수정).
3. compose + env 배치
docker-compose.edge.yml와 .env.example를 엣지에 업로드 후 .env.example를 .env로 복사하고 값 설정:
# 로컬 → 엣지로 scp
scp docker/edge/docker-compose.edge.yml wace@112.168.212.142:/home/wace/pipeline-edge/
scp docker/edge/.env.example wace@112.168.212.142:/home/wace/pipeline-edge/.env
# 엣지에서 .env 편집
ssh wace@112.168.212.142
cd /home/wace/pipeline-edge
vi .env # DATABASE_URL, JWT_SECRET, PASSWORD_ENCRYPTION_KEY, EDGE_ID 등 입력
4. 기동
docker compose -f docker-compose.edge.yml up -d
# 프론트 UI도 같이 띄우려면:
docker compose -f docker-compose.edge.yml --profile with-ui up -d
# Watchtower 자동 업데이트까지:
docker compose -f docker-compose.edge.yml --profile watchtower up -d
5. 검증
# 헬스체크
curl http://localhost:8080/health
# 부팅 로그 확인
docker logs pipeline-backend --tail 100 | grep -iE 'collector|forwarder|script'
# 기대 출력:
# ✅ 중앙 MQTT 포워더 + 장비 현재값 테이블 생성 완료
# ✅ 프로토콜 CHECK 제약 확장 완료
# 🔌 장비 수집기 자동 시작: N개 연결
# [CentralForwarder] 연결됨: mqtt://211.115.91.170:31883
- 이후 웹에서
http://<엣지IP>:9771로 UI 접근 (또는 중앙 Pipeline UI에서 같은 DB 공유 시 공통 사용). - 장비 통신 페이지에서 PLC 연결 활성화 / 비활성화 가능
- Python 훅
/admin/fleet/scripts에서 편집 → 연결에 체크박스로 붙임 → 다음 폴링부터 자동 반영
6. 롤백 / 정리
기존 Python data-collector는 그대로 돌고 있으므로 Pipeline만 내리면 원상 복구됩니다.
# Pipeline만 중지 (기존 data-collector는 영향 없음)
cd /home/wace/pipeline-edge
docker compose -f docker-compose.edge.yml down
병행 운영 중 주의사항 — 중복 IDC 전송 방지
기존 kafka-to-central-mqtt forwarder가 돌고 있는 상태에서 Pipeline 포워더까지 켜면 같은 데이터가 IDC에 두 번 들어갑니다 (동일 edge_id/company_id + 동일 토픽).
해결책 (택 1)
A. Pipeline 포워더는 켜지 말기 (추천 — 연결 검증만 먼저)
/admin/automaticMng/centralForwarder에서 포워더 설정 비활성(is_enabled='N') 유지- Pipeline은 수집/UI 테스트만, IDC 전송은 기존 forwarder가 계속 담당
B. 테스트용 edge_id 사용
.env에EDGE_ID=spifox-pipeline-test같은 식별자- IDC TimescaleDB에서 이 edge_id만 별도로 보면서 수집값 검증
- 검증 끝나면 실 edge_id로 변경 + 기존 forwarder 중지
C. 기존 포워더 중지 (완전 대체 시점)
docker stop kafka-to-central-mqtt
# 이제 Pipeline 포워더 활성화
주요 환경변수
| 변수 | 설명 | 필수 |
|---|---|---|
DATABASE_URL |
PostgreSQL 접속 URL | ✅ |
JWT_SECRET |
JWT 서명 키 (32+ 글자) | ✅ |
PASSWORD_ENCRYPTION_KEY |
AES-256 키 (32바이트 hex) | ✅ |
ENABLE_AUTO_COLLECTOR |
부팅 시 모든 활성 연결 자동 폴링 (엣지=true) | 엣지용 |
COMPANY_CODE |
고객사 식별 (예: spifox) | ✅ |
EDGE_ID |
엣지 UUID | ✅ |
트러블슈팅
Python 훅 실행 에러
docker exec pipeline-backend python3 --version # 3.11+이어야 함
IDC MQTT 미연결
docker exec pipeline-backend node -e '
const mqtt=require("mqtt");
const c=mqtt.connect("mqtt://211.115.91.170:31883",{username:"ingestion",password:"ingestion_secret_prod"});
c.on("connect",()=>{console.log("OK"); c.end();});
c.on("error",e=>console.log("ERR",e.message));
'
PLC 미연결
docker exec pipeline-backend sh -c 'timeout 3 bash -c "cat < /dev/tcp/192.168.101.50/2004" && echo OK || echo FAIL'