Files
factoryOps-v2/start-dev.sh
Johngreen 278cd9d551
All checks were successful
Deploy to Production / deploy (push) Successful in 1m37s
feat: bidirectional equipment sync with digital-twin
Add import, sync, and push capabilities between factoryOps and the
digital-twin (BaSyx AAS) backend. Includes:

- Equipment sync service with field mapping and LWW conflict resolution
- Import preview modal with already-imported detection
- Bidirectional sync (pull updates + push local changes)
- Sync history tracking via equipment_sync_history table
- Machine detail page shows sync status and change history
- Docker networking for container-to-container communication
- UI fixes: responsive layout (375px), touch targets, section spacing
- 30 test cases for sync service
2026-02-12 12:27:21 +09:00

335 lines
10 KiB
Bash
Executable File

#!/bin/bash
# FactoryOps v2 개발 환경 시작 스크립트 (Podman)
# 색상 정의
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'
# 스크립트 위치 기준으로 프로젝트 루트 이동
cd "$(dirname "$0")" || exit 1
COMPOSE_FILE="docker-compose.dev.yml"
PROJECT_NAME="factoryops-dev"
# 도움말
show_help() {
echo "사용법: $0 [OPTIONS]"
echo ""
echo "옵션:"
echo " -l, --logs 로그 표시 모드 (기본: 백그라운드)"
echo " -c, --clean 완전 초기화 (볼륨 포함 모든 리소스 삭제)"
echo " -r, --rebuild 이미지 강제 재빌드"
echo " -h, --help 도움말 표시"
echo ""
echo "실행 예시:"
echo " $0 # 빠른 시작 (기존 이미지 재사용)"
echo " $0 -l # 로그 표시 모드"
echo " $0 -r # 이미지 재빌드"
echo " $0 -c # 완전 초기화 후 시작"
echo " $0 -c -r # 완전 초기화 + 이미지 재빌드"
echo ""
echo "서비스:"
echo " PostgreSQL → localhost:5432"
echo " FastAPI → localhost:8000 (uvicorn --reload)"
echo " Next.js → localhost:3100 (npm run dev)"
}
# Podman 설치 확인
check_podman() {
if ! command -v podman &> /dev/null; then
echo -e "${RED}Podman이 설치되어 있지 않습니다.${NC}"
echo "설치: brew install podman"
exit 1
fi
}
# Podman Machine 상태 확인 및 복구 (macOS)
check_and_fix_podman() {
echo -e "${BLUE}Podman 상태 확인 중...${NC}"
# Linux에서는 Podman Machine 불필요
if [[ "$(uname -s)" != "Darwin" ]]; then
if podman ps >/dev/null 2>&1; then
echo -e "${GREEN} Podman 정상 작동${NC}"
return 0
else
echo -e "${RED} Podman 연결 실패${NC}"
exit 1
fi
fi
# macOS: Podman Machine 확인
if ! podman machine list 2>/dev/null | grep -q "Running"; then
echo -e "${YELLOW} Podman Machine이 실행되지 않았습니다. 시작 중...${NC}"
podman machine start 2>/dev/null || {
echo -e "${YELLOW} Podman Machine 초기화 중...${NC}"
podman machine init --cpus 4 --memory 8192
podman machine start
}
sleep 3
fi
# 연결 테스트 (최대 3회)
local max_attempts=3
local attempt=1
while [ $attempt -le $max_attempts ]; do
if podman ps >/dev/null 2>&1; then
echo -e "${GREEN} Podman 정상 작동${NC}"
return 0
fi
echo -e "${YELLOW} 연결 실패. 복구 시도 ($attempt/$max_attempts)...${NC}"
pkill -9 -f "gvproxy" 2>/dev/null || true
sleep 2
podman machine stop 2>/dev/null || true
sleep 2
podman machine start 2>/dev/null || {
echo -e "${RED} Podman Machine 재시작 실패${NC}"
podman machine rm -f podman-machine-default 2>/dev/null || true
podman machine init --cpus 4 --memory 8192
podman machine start
}
sleep 3
attempt=$((attempt + 1))
done
echo -e "${RED}Podman 복구 실패. 수동으로 확인해주세요:${NC}"
echo " podman machine stop && podman machine start"
exit 1
}
# factoryops-dev 관련 리소스만 정리 (다른 프로젝트 보존)
cleanup_project_resources() {
echo -e "${BLUE}FactoryOps 개발 리소스 정리 중...${NC}"
echo ""
# 1. 실행 중인 컨테이너 중지
echo -e "${BLUE} [1/5] 컨테이너 중지 및 제거...${NC}"
local containers=$(podman ps -aq --filter "name=factoryops-dev" 2>/dev/null || true)
if [ -n "$containers" ]; then
echo "$containers" | xargs -r podman stop -t 5 2>/dev/null || true
echo "$containers" | xargs -r podman rm -f 2>/dev/null || true
echo -e "${GREEN} 컨테이너 제거 완료${NC}"
else
echo -e "${GREEN} 제거할 컨테이너 없음${NC}"
fi
# 2. Pod 정리
echo -e "${BLUE} [2/5] Pod 정리...${NC}"
local pods=$(podman pod ls --filter "name=factoryops" --format "{{.ID}}" 2>/dev/null || true)
if [ -n "$pods" ]; then
echo "$pods" | xargs -r podman pod rm -f 2>/dev/null || true
echo -e "${GREEN} Pod 제거 완료${NC}"
else
echo -e "${GREEN} 제거할 Pod 없음${NC}"
fi
# 3. 네트워크 정리
echo -e "${BLUE} [3/5] 네트워크 정리...${NC}"
local networks=$(podman network ls --format "{{.Name}}" 2>/dev/null | grep "factoryops-dev" || true)
if [ -n "$networks" ]; then
echo "$networks" | xargs -r podman network rm -f 2>/dev/null || true
echo -e "${GREEN} 네트워크 제거 완료${NC}"
else
echo -e "${GREEN} 제거할 네트워크 없음${NC}"
fi
# 4. 볼륨 정리
echo -e "${BLUE} [4/5] 볼륨 정리...${NC}"
local volumes=$(podman volume ls --format "{{.Name}}" 2>/dev/null | grep "factoryops" || true)
if [ -n "$volumes" ]; then
echo "$volumes" | xargs -r podman volume rm -f 2>/dev/null || true
echo -e "${GREEN} 볼륨 제거 완료 (DB 데이터 포함)${NC}"
else
echo -e "${GREEN} 제거할 볼륨 없음${NC}"
fi
# 5. 이미지 정리
echo -e "${BLUE} [5/5] 이미지 정리...${NC}"
local images=$(podman images --format "{{.ID}} {{.Repository}}" 2>/dev/null | grep "factoryops" | awk '{print $1}' || true)
if [ -n "$images" ]; then
echo "$images" | xargs -r podman rmi -f 2>/dev/null || true
echo -e "${GREEN} 이미지 제거 완료${NC}"
else
echo -e "${GREEN} 제거할 이미지 없음${NC}"
fi
echo ""
echo -e "${GREEN} 초기화 완료 (다른 프로젝트 리소스 보존됨)${NC}"
echo ""
}
# 포트 충돌 확인 및 해결
check_and_free_ports() {
echo -e "${BLUE}포트 사용 확인 중...${NC}"
local ports=(8000 3100)
local port_names=("FastAPI" "Next.js")
local ports_freed=false
for i in "${!ports[@]}"; do
local port=${ports[$i]}
local name=${port_names[$i]}
if lsof -ti:$port >/dev/null 2>&1; then
echo -e "${YELLOW} 포트 $port ($name) 사용 중 → 프로세스 종료${NC}"
lsof -ti:$port | xargs kill -9 2>/dev/null || true
ports_freed=true
sleep 1
fi
done
if [ "$ports_freed" = true ]; then
echo -e "${GREEN} 포트 정리 완료${NC}"
sleep 2
else
echo -e "${GREEN} 모든 포트 사용 가능${NC}"
fi
}
# 서비스 헬스체크 대기
wait_for_services() {
echo ""
echo -e "${BLUE}서비스 준비 대기 중...${NC}"
# API 대기
waited=0
echo -ne "${BLUE} FastAPI "
while [ $waited -lt $max_wait ]; do
if curl -sf http://localhost:8000/api/health >/dev/null 2>&1; then
echo -e " ${GREEN}ready${NC}"
break
fi
echo -n "."
sleep 2
waited=$((waited + 2))
done
if [ $waited -ge $max_wait ]; then
echo -e " ${YELLOW}timeout (로그를 확인하세요)${NC}"
fi
# Dashboard 대기 (npm install이 오래 걸릴 수 있음)
waited=0
max_wait=120
echo -ne "${BLUE} Next.js "
while [ $waited -lt $max_wait ]; do
if curl -sf http://localhost:3100 >/dev/null 2>&1; then
echo -e " ${GREEN}ready${NC}"
break
fi
echo -n "."
sleep 3
waited=$((waited + 3))
done
if [ $waited -ge $max_wait ]; then
echo -e " ${YELLOW}아직 준비 중 (npm install 진행 중일 수 있음)${NC}"
fi
}
# ─── 인자 파싱 ───
SHOW_LOGS=false
FULL_CLEAN=false
FORCE_REBUILD=false
while [[ $# -gt 0 ]]; do
case $1 in
-l|--logs) SHOW_LOGS=true; shift ;;
-c|--clean) FULL_CLEAN=true; shift ;;
-r|--rebuild) FORCE_REBUILD=true; shift ;;
-h|--help) show_help; exit 0 ;;
*) echo "알 수 없는 옵션: $1"; show_help; exit 1 ;;
esac
done
# ─── 실행 시작 ───
echo -e "${CYAN}"
echo "================================================="
echo " FactoryOps v2 개발 환경 시작"
echo "================================================="
echo -e "${NC}"
check_podman
check_and_fix_podman
# 완전 초기화 또는 빠른 시작
if [ "$FULL_CLEAN" = true ]; then
echo -e "${YELLOW}완전 초기화 모드 (-c)${NC}"
echo -e "${YELLOW} factoryops 관련 리소스만 삭제됩니다 (볼륨/DB 포함)${NC}"
echo ""
cleanup_project_resources
else
echo -e "${GREEN}빠른 시작 모드 (기존 리소스 재사용)${NC}"
echo -e "${BLUE} 완전 초기화가 필요하면: $0 -c${NC}"
echo ""
# 실행 중인 컨테이너만 중지
running=$(podman ps -q --filter "name=factoryops-dev" 2>/dev/null || true)
if [ -n "$running" ]; then
echo -e "${YELLOW} 기존 컨테이너 중지 중...${NC}"
echo "$running" | xargs -r podman stop -t 5 2>/dev/null || true
echo -e "${GREEN} 기존 컨테이너 중지 완료${NC}"
fi
echo ""
fi
check_and_free_ports
# 빌드 & 실행 옵션
BUILD_OPTIONS=""
RUN_OPTIONS=""
if [ "$FORCE_REBUILD" = true ]; then
BUILD_OPTIONS="--build --no-cache"
echo -e "${BLUE}이미지 재빌드 모드 활성화 (-r)${NC}"
else
echo -e "${GREEN}기존 이미지 재사용 (재빌드: $0 -r)${NC}"
fi
if [ "$SHOW_LOGS" = false ]; then
RUN_OPTIONS="-d"
fi
echo ""
echo -e "${BLUE}서비스 시작 중...${NC}"
# compose 실행
podman compose -f "$COMPOSE_FILE" up $RUN_OPTIONS $BUILD_OPTIONS 2>&1 | \
grep -v "WARNING" || true
if [ "$SHOW_LOGS" = false ]; then
wait_for_services
fi
echo ""
echo -e "${CYAN}"
echo "================================================="
echo " FactoryOps v2 개발 환경 시작 완료"
echo "================================================="
echo -e "${NC}"
echo " 서비스 접속:"
echo " Frontend http://localhost:3100"
echo " Backend http://localhost:8000"
echo " API Docs http://localhost:8000/docs"
echo " Database 211.115.91.141:8200 (원격 DB)"
echo ""
if [ "$SHOW_LOGS" = false ]; then
echo " 로그 확인:"
echo " podman compose -f $COMPOSE_FILE logs -f"
echo " podman compose -f $COMPOSE_FILE logs -f api"
echo " podman compose -f $COMPOSE_FILE logs -f dashboard"
echo ""
fi
echo " 중지:"
echo " ./stop-dev.sh"
echo ""