From 2fb0637ad1bb1277e3156c97d2bd5aae989efd51 Mon Sep 17 00:00:00 2001 From: hyungi Date: Sun, 14 Sep 2025 12:23:35 +0900 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9A=20Add=20comprehensive=20setup=20do?= =?UTF-8?q?cumentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TECH_STACK.md: Complete technology stack overview - HOMEBREW_SETUP.md: macOS development environment setup guide - SYNOLOGY_SETUP.md: General Synology NAS installation guide - DS1525_OPTIMIZED_SETUP.md: DS1525+ 32GB RAM optimized configuration Features: ✅ Multi-platform deployment options (Mac/NAS) ✅ Performance optimization for different hardware specs ✅ Docker-based containerization ✅ Monitoring and logging setup ✅ Automated backup and maintenance scripts ✅ SSD optimization for longevity --- DS1525_OPTIMIZED_SETUP.md | 607 ++++++++++++++++++++++++++++++++ HOMEBREW_SETUP.md | 592 +++++++++++++++++++++++++++++++ SYNOLOGY_SETUP.md | 721 ++++++++++++++++++++++++++++++++++++++ TECH_STACK.md | 285 +++++++++++++++ 4 files changed, 2205 insertions(+) create mode 100644 DS1525_OPTIMIZED_SETUP.md create mode 100644 HOMEBREW_SETUP.md create mode 100644 SYNOLOGY_SETUP.md create mode 100644 TECH_STACK.md diff --git a/DS1525_OPTIMIZED_SETUP.md b/DS1525_OPTIMIZED_SETUP.md new file mode 100644 index 0000000..7a8e50c --- /dev/null +++ b/DS1525_OPTIMIZED_SETUP.md @@ -0,0 +1,607 @@ +# 🏠 DS1525+ 최적화 설치 가이드 + +## 📋 하드웨어 사양 + +### 대상 기기: Synology DS1525+ +- **CPU**: AMD Ryzen R1600 (4코어 2.6GHz) +- **메모리**: 32GB RAM (대폭 업그레이드됨!) +- **저장장치**: 시놀로지 정품 2.5" SSD 480GB +- **네트워크**: 기가비트 이더넷 x4 +- **DSM**: 7.0 이상 + +### 성능 특징 +- **고성능 CPU**: AMD Ryzen으로 NLP 처리 우수 +- **대용량 메모리**: 32GB로 모든 서비스 여유롭게 운영 +- **SSD 스토리지**: 빠른 I/O, 낮은 지연시간 +- **멀티 기가비트**: 네트워크 병목 없음 + +--- + +## 🚀 DS1525+ 32GB 최적화 구성 + +### 메모리 할당 계획 (32GB 활용) +``` +총 메모리: 32GB +├── DSM 시스템: 2GB +├── PostgreSQL: 4GB (대폭 증량) +├── Elasticsearch: 8GB (고성능 검색) +├── Redis: 2GB (대용량 캐시) +├── 애플리케이션: 4GB (멀티 워커) +├── NLP 처리: 4GB (동시 처리) +├── 시스템 캐시: 6GB (파일 시스템 캐시) +└── 여유 공간: 2GB +``` + +### Docker Compose 최적화 (DS1525+ 전용) +```yaml +# /volume1/docker/industrial-info/docker-compose.yml +version: '3.8' + +networks: + industrial-net: + driver: bridge + ipam: + config: + - subnet: 172.20.0.0/16 + +services: + postgres: + image: postgres:15-alpine + container_name: industrial-postgres + environment: + POSTGRES_DB: industrial_info + POSTGRES_USER: industrial_user + POSTGRES_PASSWORD: secure_password_here + POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=C" + volumes: + - /volume1/docker/industrial-info/data/postgres:/var/lib/postgresql/data + - /volume1/docker/industrial-info/config/postgresql.conf:/etc/postgresql/postgresql.conf + ports: + - "5432:5432" + networks: + - industrial-net + restart: unless-stopped + deploy: + resources: + limits: + memory: 4G # 32GB 활용 + cpus: '2.0' # Ryzen 4코어 활용 + reservations: + memory: 2G + cpus: '1.0' + command: postgres -c config_file=/etc/postgresql/postgresql.conf + + elasticsearch: + image: elasticsearch:8.11.0 + container_name: industrial-elasticsearch + environment: + - discovery.type=single-node + - "ES_JAVA_OPTS=-Xms4g -Xmx8g" # 대폭 증량! + - xpack.security.enabled=false + - xpack.security.enrollment.enabled=false + - bootstrap.memory_lock=true + volumes: + - /volume1/docker/industrial-info/data/elasticsearch:/usr/share/elasticsearch/data + - /volume1/docker/industrial-info/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml + ports: + - "9200:9200" + - "9300:9300" + networks: + - industrial-net + restart: unless-stopped + deploy: + resources: + limits: + memory: 10G # 8GB JVM + 2GB 시스템 + cpus: '2.0' + reservations: + memory: 6G + cpus: '1.0' + ulimits: + memlock: + soft: -1 + hard: -1 + nofile: + soft: 65536 + hard: 65536 + + redis: + image: redis:7-alpine + container_name: industrial-redis + command: redis-server /etc/redis/redis.conf + volumes: + - /volume1/docker/industrial-info/data/redis:/data + - /volume1/docker/industrial-info/config/redis.conf:/etc/redis/redis.conf + ports: + - "6379:6379" + networks: + - industrial-net + restart: unless-stopped + deploy: + resources: + limits: + memory: 2G # 대용량 캐시 + cpus: '1.0' + reservations: + memory: 1G + cpus: '0.5' + + app: + build: ./app + container_name: industrial-app + environment: + - DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info + - REDIS_URL=redis://redis:6379/0 + - ELASTICSEARCH_URL=http://elasticsearch:9200 + - PYTHONPATH=/app + - WORKERS=4 # 멀티 워커 + volumes: + - /volume1/docker/industrial-info/app:/app + - /volume1/docker/industrial-info/data/logs:/app/logs + ports: + - "8000:8000" + networks: + - industrial-net + depends_on: + - postgres + - redis + - elasticsearch + restart: unless-stopped + deploy: + resources: + limits: + memory: 4G # 멀티 워커 지원 + cpus: '2.0' + reservations: + memory: 2G + cpus: '1.0' + + # NLP 전용 워커 (고성능) + nlp-worker: + build: ./app + container_name: industrial-nlp-worker + command: celery -A main.celery worker --loglevel=info --concurrency=4 -Q nlp + environment: + - DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info + - REDIS_URL=redis://redis:6379/0 + - ELASTICSEARCH_URL=http://elasticsearch:9200 + - SPACY_MODEL_PATH=/app/models + volumes: + - /volume1/docker/industrial-info/app:/app + - /volume1/docker/industrial-info/data/logs:/app/logs + - /volume1/docker/industrial-info/data/models:/app/models + networks: + - industrial-net + depends_on: + - postgres + - redis + - elasticsearch + restart: unless-stopped + deploy: + resources: + limits: + memory: 4G # NLP 모델 로딩용 + cpus: '2.0' + reservations: + memory: 2G + cpus: '1.0' + + # 데이터 수집 워커 + collector-worker: + build: ./app + container_name: industrial-collector + command: celery -A main.celery worker --loglevel=info --concurrency=2 -Q collector + environment: + - DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info + - REDIS_URL=redis://redis:6379/0 + - ELASTICSEARCH_URL=http://elasticsearch:9200 + volumes: + - /volume1/docker/industrial-info/app:/app + - /volume1/docker/industrial-info/data/logs:/app/logs + networks: + - industrial-net + depends_on: + - postgres + - redis + - elasticsearch + restart: unless-stopped + deploy: + resources: + limits: + memory: 2G + cpus: '1.0' + reservations: + memory: 1G + cpus: '0.5' + + # 스케줄러 + scheduler: + build: ./app + container_name: industrial-scheduler + command: celery -A main.celery beat --loglevel=info + environment: + - DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info + - REDIS_URL=redis://redis:6379/0 + - ELASTICSEARCH_URL=http://elasticsearch:9200 + volumes: + - /volume1/docker/industrial-info/app:/app + - /volume1/docker/industrial-info/data/logs:/app/logs + networks: + - industrial-net + depends_on: + - postgres + - redis + - elasticsearch + restart: unless-stopped + deploy: + resources: + limits: + memory: 512M + cpus: '0.5' + + # 모니터링 (Prometheus) + prometheus: + image: prom/prometheus:latest + container_name: industrial-prometheus + volumes: + - /volume1/docker/industrial-info/config/prometheus.yml:/etc/prometheus/prometheus.yml + - /volume1/docker/industrial-info/data/prometheus:/prometheus + ports: + - "9090:9090" + networks: + - industrial-net + restart: unless-stopped + deploy: + resources: + limits: + memory: 1G + cpus: '0.5' + + # 모니터링 대시보드 (Grafana) + grafana: + image: grafana/grafana:latest + container_name: industrial-grafana + environment: + - GF_SECURITY_ADMIN_PASSWORD=admin123 + volumes: + - /volume1/docker/industrial-info/data/grafana:/var/lib/grafana + ports: + - "3000:3000" + networks: + - industrial-net + restart: unless-stopped + deploy: + resources: + limits: + memory: 1G + cpus: '0.5' + + nginx: + image: nginx:alpine + container_name: industrial-nginx + volumes: + - /volume1/docker/industrial-info/config/nginx.conf:/etc/nginx/nginx.conf + - /volume1/docker/industrial-info/data/logs:/var/log/nginx + ports: + - "80:80" + - "443:443" + networks: + - industrial-net + depends_on: + - app + restart: unless-stopped + deploy: + resources: + limits: + memory: 512M + cpus: '0.5' +``` + +--- + +## ⚙️ 고성능 설정 파일들 + +### PostgreSQL 최적화 (32GB 활용) +```ini +# /volume1/docker/industrial-info/config/postgresql.conf +# DS1525+ 32GB RAM 최적화 설정 + +# 메모리 설정 +shared_buffers = 2GB # 32GB의 6.25% +effective_cache_size = 16GB # 32GB의 50% +maintenance_work_mem = 512MB # 대용량 인덱스 작업 +work_mem = 64MB # 정렬/해시 작업용 + +# 체크포인트 설정 +checkpoint_completion_target = 0.9 +checkpoint_timeout = 15min +max_wal_size = 4GB +min_wal_size = 1GB + +# 연결 설정 +max_connections = 200 +shared_preload_libraries = 'pg_stat_statements' + +# 로그 설정 +log_destination = 'stderr' +logging_collector = on +log_directory = '/var/lib/postgresql/data/log' +log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' +log_rotation_age = 1d +log_rotation_size = 100MB +log_min_duration_statement = 1000 # 1초 이상 쿼리 로깅 + +# 성능 최적화 +random_page_cost = 1.1 # SSD 최적화 +effective_io_concurrency = 200 # SSD 동시 I/O +max_worker_processes = 4 # Ryzen 4코어 활용 +max_parallel_workers = 4 +max_parallel_workers_per_gather = 2 + +# 자동 VACUUM 최적화 +autovacuum = on +autovacuum_max_workers = 2 +autovacuum_naptime = 30s +``` + +### Elasticsearch 최적화 (8GB JVM) +```yaml +# /volume1/docker/industrial-info/config/elasticsearch.yml +cluster.name: "industrial-cluster" +node.name: "industrial-node-1" +path.data: /usr/share/elasticsearch/data +path.logs: /usr/share/elasticsearch/logs + +# 네트워크 설정 +network.host: 0.0.0.0 +http.port: 9200 +transport.port: 9300 + +# 메모리 설정 (32GB 환경) +bootstrap.memory_lock: true +indices.memory.index_buffer_size: 2GB +indices.fielddata.cache.size: 2GB + +# 성능 최적화 +thread_pool.write.queue_size: 1000 +thread_pool.search.queue_size: 1000 +indices.queries.cache.size: 1GB + +# SSD 최적화 +index.store.type: niofs +index.merge.scheduler.max_thread_count: 2 + +# 한국어 분석 설정 +index.analysis.analyzer.nori.type: custom +index.analysis.analyzer.nori.tokenizer: nori_tokenizer +index.analysis.analyzer.nori.filter: [nori_part_of_speech, lowercase] +``` + +### Redis 최적화 (2GB) +```ini +# /volume1/docker/industrial-info/config/redis.conf +# DS1525+ 32GB RAM 최적화 + +# 메모리 설정 +maxmemory 2gb +maxmemory-policy allkeys-lru + +# 영속성 설정 (SSD 최적화) +save 900 1 +save 300 10 +save 60 10000 + +# AOF 설정 +appendonly yes +appendfsync everysec +auto-aof-rewrite-percentage 100 +auto-aof-rewrite-min-size 64mb + +# 네트워크 최적화 +tcp-keepalive 300 +timeout 0 + +# 성능 최적화 +hash-max-ziplist-entries 512 +hash-max-ziplist-value 64 +list-max-ziplist-size -2 +set-max-intset-entries 512 +zset-max-ziplist-entries 128 +zset-max-ziplist-value 64 + +# 로그 설정 +loglevel notice +logfile "" +``` + +--- + +## 📊 성능 벤치마크 (DS1525+ 32GB) + +### 예상 성능 지표 +``` +동시 사용자: 100명 (여유롭게) +검색 응답시간: 50-100ms (매우 빠름) +RSS 수집: 500개 피드/분 (대용량 처리) +NLP 처리: 10,000건/시간 (고속 처리) +데이터베이스: 1,000 TPS (높은 처리량) +``` + +### 리소스 사용률 목표 +``` +CPU 사용률: 평균 30-40% (여유) +메모리 사용률: 평균 70-80% (효율적) +디스크 I/O: SSD 성능 최대 활용 +네트워크: 기가비트 대역폭 활용 +``` + +--- + +## 💾 SSD 480GB 최적화 + +### 디스크 공간 할당 +``` +총 용량: 480GB +├── DSM 시스템: 50GB +├── Docker 이미지: 20GB +├── PostgreSQL 데이터: 100GB +├── Elasticsearch 인덱스: 150GB +├── 애플리케이션 로그: 30GB +├── 백업 공간: 80GB +└── 여유 공간: 50GB (10% 여유) +``` + +### SSD 수명 연장 설정 +```bash +# SSD 최적화 스크립트 +#!/bin/bash + +# TRIM 활성화 +echo 'deadline' > /sys/block/sda/queue/scheduler + +# 로그 로테이션 최적화 +cat > /etc/logrotate.d/docker << EOF +/volume1/docker/industrial-info/data/logs/*.log { + daily + rotate 7 + compress + delaycompress + missingok + notifempty + create 644 root root +} +EOF + +# 스왑 사용 최소화 +echo 'vm.swappiness=1' >> /etc/sysctl.conf +echo 'vm.vfs_cache_pressure=50' >> /etc/sysctl.conf +``` + +### 자동 정리 스크립트 +```bash +# /volume1/docker/industrial-info/scripts/cleanup.sh +#!/bin/bash + +# Docker 이미지 정리 (주간) +docker system prune -f + +# 로그 파일 압축 (일일) +find /volume1/docker/industrial-info/data/logs -name "*.log" -mtime +1 -exec gzip {} \; + +# 오래된 백업 삭제 (월간) +find /volume1/docker/industrial-info/backup -name "*.gz" -mtime +30 -delete + +# Elasticsearch 인덱스 최적화 (주간) +curl -X POST "localhost:9200/_forcemerge?max_num_segments=1" + +echo "Cleanup completed: $(date)" +``` + +--- + +## 🔧 모니터링 및 알림 + +### Prometheus 설정 +```yaml +# /volume1/docker/industrial-info/config/prometheus.yml +global: + scrape_interval: 15s + +scrape_configs: + - job_name: 'industrial-app' + static_configs: + - targets: ['app:8000'] + + - job_name: 'postgres' + static_configs: + - targets: ['postgres:5432'] + + - job_name: 'elasticsearch' + static_configs: + - targets: ['elasticsearch:9200'] + + - job_name: 'redis' + static_configs: + - targets: ['redis:6379'] + + - job_name: 'node-exporter' + static_configs: + - targets: ['localhost:9100'] +``` + +### 알림 규칙 +```yaml +# 메모리 사용률 80% 초과 시 알림 +- alert: HighMemoryUsage + expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 80 + for: 5m + labels: + severity: warning + annotations: + summary: "High memory usage detected" + +# 디스크 사용률 85% 초과 시 알림 +- alert: HighDiskUsage + expr: (1 - (node_filesystem_avail_bytes / node_filesystem_size_bytes)) * 100 > 85 + for: 5m + labels: + severity: critical + annotations: + summary: "High disk usage detected" +``` + +--- + +## 🚀 배포 및 실행 + +### 원클릭 설치 스크립트 +```bash +#!/bin/bash +# /volume1/docker/industrial-info/install.sh + +echo "🚀 DS1525+ 산업정보시스템 설치 시작..." + +# 디렉토리 생성 +mkdir -p /volume1/docker/industrial-info/{app,data/{postgres,elasticsearch,redis,logs,grafana,prometheus},config,backup,scripts} + +# 권한 설정 +chown -R 1000:1000 /volume1/docker/industrial-info + +# Docker 네트워크 생성 +docker network create industrial-net 2>/dev/null || true + +# 환경 변수 파일 생성 +cat > /volume1/docker/industrial-info/.env << EOF +POSTGRES_PASSWORD=$(openssl rand -base64 32) +SECRET_KEY=$(openssl rand -base64 64) +ELASTICSEARCH_PASSWORD=$(openssl rand -base64 32) +EOF + +# 컨테이너 시작 +cd /volume1/docker/industrial-info +docker-compose up --build -d + +echo "✅ 설치 완료! 접속 URL:" +echo " 애플리케이션: http://$(hostname -I | awk '{print $1}'):80" +echo " 모니터링: http://$(hostname -I | awk '{print $1}'):3000" +echo " Elasticsearch: http://$(hostname -I | awk '{print $1}'):9200" +``` + +--- + +## 📈 성능 비교 요약 + +### DS1525+ vs 일반 NAS vs Mac +| 항목 | DS1525+ 32GB | 일반 NAS 8GB | Mac Mini M2 | +|------|--------------|--------------|-------------| +| 동시 사용자 | 100명 | 20명 | 50명 | +| 검색 속도 | 50ms | 200ms | 30ms | +| NLP 처리 | 10K건/시간 | 1K건/시간 | 15K건/시간 | +| 전력 소모 | 60W | 40W | 150W | +| 24시간 운영 | ✅ 최적 | ✅ 가능 | ❌ 비효율 | +| 확장성 | ✅ 우수 | ⚠️ 제한적 | ❌ 제한적 | +| 비용 효율 | ✅ 최고 | ✅ 좋음 | ❌ 높음 | + +**결론**: DS1525+ 32GB는 이 프로젝트에 **과분할 정도로 좋은 성능**을 제공합니다! 🚀 + +480GB SSD도 충분하고, 32GB RAM으로 모든 서비스를 여유롭게 돌릴 수 있어요. 완벽한 선택입니다! 👍 diff --git a/HOMEBREW_SETUP.md b/HOMEBREW_SETUP.md new file mode 100644 index 0000000..0b105ab --- /dev/null +++ b/HOMEBREW_SETUP.md @@ -0,0 +1,592 @@ +# 🍺 Homebrew 기반 개발환경 설정 가이드 + +## 📋 개요 + +macOS에서 Homebrew를 사용하여 산업 전문 정보 수집 시스템의 개발환경을 설정하는 단계별 가이드입니다. + +--- + +## 🔧 사전 요구사항 + +### 시스템 요구사항 +- **macOS**: 12.0+ (Monterey 이상 권장) +- **메모리**: 8GB 이상 (16GB 권장) +- **저장공간**: 20GB 이상 여유 공간 +- **네트워크**: 인터넷 연결 (패키지 다운로드용) + +### 개발자 도구 +```bash +# Xcode Command Line Tools 설치 (Homebrew 설치 전 필수) +xcode-select --install +``` + +--- + +## 🍺 1단계: Homebrew 설치 + +### Homebrew 설치 +```bash +# Homebrew 설치 스크립트 실행 +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + +# 설치 확인 +brew --version + +# PATH 설정 (M1/M2 Mac의 경우) +echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zshrc +source ~/.zshrc +``` + +### Homebrew 업데이트 +```bash +# Homebrew 자체 업데이트 +brew update + +# 설치된 패키지 업그레이드 +brew upgrade +``` + +--- + +## 🐍 2단계: Python 환경 설정 + +### Python 설치 +```bash +# Python 3.11 설치 (최신 안정 버전) +brew install python@3.11 + +# 설치 확인 +python3 --version +pip3 --version + +# 심볼릭 링크 설정 (선택사항) +brew link python@3.11 +``` + +### 가상환경 도구 설치 +```bash +# virtualenv 설치 +pip3 install virtualenv + +# 또는 pyenv 사용 (Python 버전 관리) +brew install pyenv +echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc +echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc +echo 'eval "$(pyenv init -)"' >> ~/.zshrc +source ~/.zshrc +``` + +### 프로젝트 가상환경 생성 +```bash +# 프로젝트 디렉토리로 이동 +cd /Users/hyungi/news-project + +# 가상환경 생성 +python3 -m venv venv + +# 가상환경 활성화 +source venv/bin/activate + +# 가상환경 활성화 확인 (프롬프트에 (venv) 표시됨) +which python +``` + +--- + +## 🟢 3단계: Node.js 환경 설정 + +### Node.js 설치 +```bash +# Node.js 18 LTS 설치 +brew install node@18 + +# 설치 확인 +node --version +npm --version + +# 글로벌 패키지 업데이트 +npm install -g npm@latest +``` + +### 선택적: Node 버전 관리자 설치 +```bash +# nvm 설치 (Node Version Manager) +brew install nvm + +# nvm 설정 +mkdir ~/.nvm +echo 'export NVM_DIR="$HOME/.nvm"' >> ~/.zshrc +echo '[ -s "/opt/homebrew/share/nvm/nvm.sh" ] && \. "/opt/homebrew/share/nvm/nvm.sh"' >> ~/.zshrc +echo '[ -s "/opt/homebrew/share/nvm/bash_completion" ] && \. "/opt/homebrew/share/nvm/bash_completion"' >> ~/.zshrc +source ~/.zshrc + +# Node.js 18 설치 및 사용 +nvm install 18 +nvm use 18 +nvm alias default 18 +``` + +--- + +## 🗄️ 4단계: 데이터베이스 설치 + +### PostgreSQL 설치 +```bash +# PostgreSQL 설치 +brew install postgresql@15 + +# 서비스 시작 +brew services start postgresql@15 + +# 데이터베이스 생성 +createdb industrial_info + +# 연결 테스트 +psql industrial_info +# \q 로 종료 +``` + +### PostgreSQL 설정 +```bash +# 사용자 생성 (선택사항) +createuser --interactive --pwprompt industrial_user + +# 데이터베이스 권한 부여 +psql -c "GRANT ALL PRIVILEGES ON DATABASE industrial_info TO industrial_user;" +``` + +### Redis 설치 +```bash +# Redis 설치 +brew install redis + +# 서비스 시작 +brew services start redis + +# 연결 테스트 +redis-cli ping +# PONG 응답 확인 +``` + +--- + +## 🔍 5단계: Elasticsearch 설치 + +### Elasticsearch 설치 +```bash +# Elasticsearch 설치 +brew install elasticsearch + +# 설정 파일 위치 확인 +brew --prefix elasticsearch + +# JVM 메모리 설정 (8GB Mac 기준) +echo 'export ELASTICSEARCH_JAVA_OPTS="-Xms512m -Xmx1g"' >> ~/.zshrc +source ~/.zshrc + +# 서비스 시작 +brew services start elasticsearch + +# 연결 테스트 (약 30초 후) +curl http://localhost:9200 +``` + +### Elasticsearch 한국어 분석기 설치 +```bash +# nori 분석기 설치 +/opt/homebrew/bin/elasticsearch-plugin install analysis-nori + +# 서비스 재시작 +brew services restart elasticsearch +``` + +--- + +## 🐳 6단계: Docker 설치 + +### Docker Desktop 설치 +```bash +# Docker Desktop 설치 +brew install --cask docker + +# Docker 실행 확인 (GUI에서 Docker Desktop 실행 필요) +docker --version +docker-compose --version +``` + +### Docker 설정 최적화 +```bash +# Docker Desktop 설정 권장사항: +# - Memory: 4GB (8GB Mac 기준) +# - Swap: 1GB +# - Disk image size: 64GB +``` + +--- + +## 🛠️ 7단계: 개발 도구 설치 + +### 필수 개발 도구 +```bash +# Git (이미 설치되어 있을 수 있음) +brew install git + +# 시스템 모니터링 도구 +brew install htop + +# 텍스트 처리 도구 +brew install jq # JSON 처리 +brew install ripgrep # 빠른 텍스트 검색 + +# 네트워크 도구 +brew install curl +brew install wget +``` + +### IDE 및 에디터 +```bash +# Visual Studio Code +brew install --cask visual-studio-code + +# 또는 다른 에디터들 +brew install --cask sublime-text +brew install --cask atom +brew install vim # 터미널 에디터 +``` + +### 선택적 도구 +```bash +# 데이터베이스 GUI 도구 +brew install --cask dbeaver-community # 다중 DB 클라이언트 +brew install --cask tableplus # macOS 네이티브 DB 클라이언트 + +# API 테스트 도구 +brew install --cask postman +brew install --cask insomnia + +# 터미널 개선 +brew install zsh-autosuggestions +brew install zsh-syntax-highlighting +``` + +--- + +## 🚀 8단계: 프로젝트 설정 + +### 프로젝트 클론 및 설정 +```bash +# 프로젝트 디렉토리로 이동 +cd /Users/hyungi/news-project + +# 가상환경 활성화 +source venv/bin/activate + +# 환경 변수 파일 생성 +cp .env.example .env +``` + +### 환경 변수 설정 (.env 파일) +```bash +# .env 파일 편집 +cat > .env << EOF +# 데이터베이스 설정 +DATABASE_URL=postgresql://industrial_user:password@localhost:5432/industrial_info +REDIS_URL=redis://localhost:6379/0 +ELASTICSEARCH_URL=http://localhost:9200 + +# 개발 환경 설정 +DEBUG=True +SECRET_KEY=your-secret-key-here + +# API 키 (필요시) +PUBMED_API_KEY=your-pubmed-api-key +IEEE_API_KEY=your-ieee-api-key +EOF +``` + +### Python 의존성 설치 +```bash +# requirements.txt가 있는 경우 +pip install -r requirements.txt + +# 또는 기본 패키지 설치 +pip install fastapi uvicorn sqlalchemy psycopg2-binary redis elasticsearch celery spacy beautifulsoup4 requests pandas numpy +``` + +### Node.js 의존성 설치 (프론트엔드가 있는 경우) +```bash +# frontend 디렉토리가 있는 경우 +cd frontend +npm install +cd .. +``` + +--- + +## 🔧 9단계: 서비스 관리 + +### 서비스 시작/중지 명령어 +```bash +# 모든 서비스 시작 +brew services start postgresql@15 +brew services start redis +brew services start elasticsearch + +# 서비스 상태 확인 +brew services list + +# 특정 서비스 중지 +brew services stop postgresql@15 +brew services stop redis +brew services stop elasticsearch + +# 서비스 재시작 +brew services restart postgresql@15 +``` + +### 자동 시작 설정 +```bash +# 시스템 부팅 시 자동 시작 (이미 설정됨) +# brew services start 명령어로 설치한 서비스들은 자동으로 부팅 시 시작됨 + +# 수동으로 자동 시작 해제하려면 +brew services stop postgresql@15 +# 그리고 수동으로 시작하려면 +pg_ctl -D /opt/homebrew/var/postgresql@15 start +``` + +--- + +## 📊 10단계: 성능 최적화 + +### 메모리 사용량 최적화 (8GB Mac 기준) +```bash +# ~/.zshrc에 추가 +cat >> ~/.zshrc << EOF + +# 개발환경 메모리 최적화 +export ELASTICSEARCH_JAVA_OPTS="-Xms512m -Xmx1g" +export REDIS_MAXMEMORY="256mb" +export PYTHONOPTIMIZE=1 + +# PostgreSQL 설정 최적화 +export PGDATA="/opt/homebrew/var/postgresql@15" +EOF + +source ~/.zshrc +``` + +### PostgreSQL 설정 최적화 +```bash +# postgresql.conf 편집 +vim /opt/homebrew/var/postgresql@15/postgresql.conf + +# 다음 설정 추가/수정: +# shared_buffers = 256MB +# effective_cache_size = 1GB +# maintenance_work_mem = 64MB +# checkpoint_completion_target = 0.9 +# wal_buffers = 16MB +# default_statistics_target = 100 + +# 설정 적용을 위해 재시작 +brew services restart postgresql@15 +``` + +--- + +## 🔍 11단계: 개발환경 테스트 + +### 연결 테스트 스크립트 +```bash +# test_connections.py 생성 +cat > test_connections.py << EOF +#!/usr/bin/env python3 +import psycopg2 +import redis +import requests + +def test_postgresql(): + try: + conn = psycopg2.connect( + host="localhost", + database="industrial_info", + user="industrial_user", + password="password" + ) + print("✅ PostgreSQL 연결 성공") + conn.close() + except Exception as e: + print(f"❌ PostgreSQL 연결 실패: {e}") + +def test_redis(): + try: + r = redis.Redis(host='localhost', port=6379, db=0) + r.ping() + print("✅ Redis 연결 성공") + except Exception as e: + print(f"❌ Redis 연결 실패: {e}") + +def test_elasticsearch(): + try: + response = requests.get('http://localhost:9200') + if response.status_code == 200: + print("✅ Elasticsearch 연결 성공") + else: + print(f"❌ Elasticsearch 연결 실패: {response.status_code}") + except Exception as e: + print(f"❌ Elasticsearch 연결 실패: {e}") + +if __name__ == "__main__": + print("🔍 개발환경 연결 테스트") + test_postgresql() + test_redis() + test_elasticsearch() +EOF + +# 테스트 실행 +python test_connections.py +``` + +### 시스템 리소스 모니터링 +```bash +# 시스템 리소스 확인 +htop + +# Docker 컨테이너 리소스 확인 (Docker 사용 시) +docker stats + +# 디스크 사용량 확인 +df -h + +# 메모리 사용량 확인 +vm_stat +``` + +--- + +## 🚨 문제 해결 + +### 일반적인 문제들 + +#### 1. Homebrew 설치 실패 +```bash +# 권한 문제 해결 +sudo chown -R $(whoami) /opt/homebrew + +# 또는 Rosetta 2 설치 (M1/M2 Mac) +softwareupdate --install-rosetta +``` + +#### 2. PostgreSQL 연결 실패 +```bash +# 서비스 상태 확인 +brew services list | grep postgresql + +# 로그 확인 +tail -f /opt/homebrew/var/log/postgresql@15.log + +# 포트 충돌 확인 +lsof -i :5432 +``` + +#### 3. Elasticsearch 시작 실패 +```bash +# Java 설치 확인 +java --version + +# 메모리 부족 시 설정 조정 +export ELASTICSEARCH_JAVA_OPTS="-Xms256m -Xmx512m" + +# 로그 확인 +tail -f /opt/homebrew/var/log/elasticsearch.log +``` + +#### 4. Redis 연결 문제 +```bash +# Redis 서비스 확인 +brew services list | grep redis + +# 설정 파일 확인 +cat /opt/homebrew/etc/redis.conf + +# 포트 확인 +lsof -i :6379 +``` + +### 성능 문제 해결 + +#### 메모리 부족 시 +```bash +# 불필요한 서비스 중지 +brew services stop elasticsearch # 임시로 중지 + +# Swap 사용량 확인 +sysctl vm.swapusage + +# 메모리 정리 +sudo purge +``` + +#### 디스크 공간 부족 시 +```bash +# Homebrew 캐시 정리 +brew cleanup + +# Docker 이미지 정리 +docker system prune -a + +# 로그 파일 정리 +sudo rm -rf /opt/homebrew/var/log/*.log.* +``` + +--- + +## 📚 추가 리소스 + +### 유용한 명령어 모음 +```bash +# 모든 Homebrew 서비스 상태 확인 +brew services list + +# 설치된 패키지 목록 +brew list + +# 패키지 정보 확인 +brew info postgresql@15 + +# 의존성 확인 +brew deps --tree postgresql@15 + +# 업데이트 가능한 패키지 확인 +brew outdated +``` + +### 개발 워크플로우 +```bash +# 일일 개발 시작 루틴 +cd /Users/hyungi/news-project +source venv/bin/activate +brew services start postgresql@15 redis elasticsearch + +# 일일 개발 종료 루틴 +deactivate +brew services stop elasticsearch # 메모리 절약을 위해 +``` + +### 백업 및 복원 +```bash +# PostgreSQL 백업 +pg_dump industrial_info > backup.sql + +# PostgreSQL 복원 +psql industrial_info < backup.sql + +# 설정 파일 백업 +cp ~/.zshrc ~/.zshrc.backup +cp .env .env.backup +``` + +--- + +이 가이드를 따라하면 macOS에서 Homebrew를 사용하여 완전한 개발환경을 구축할 수 있습니다. 각 단계별로 진행하면서 문제가 발생하면 문제 해결 섹션을 참조하세요. diff --git a/SYNOLOGY_SETUP.md b/SYNOLOGY_SETUP.md new file mode 100644 index 0000000..ca5fada --- /dev/null +++ b/SYNOLOGY_SETUP.md @@ -0,0 +1,721 @@ +# 🏠 시놀로지 NAS 설치 가이드 + +## 📋 개요 + +시놀로지 NAS에서 산업 전문 정보 수집 시스템을 Docker 기반으로 설치하는 가이드입니다. 24시간 안정적인 서비스 운영이 가능하며, 480GB SSD 환경에 최적화된 설정을 제공합니다. + +--- + +## 🔧 사전 요구사항 + +### 하드웨어 요구사항 +- **시놀로지 NAS**: DS220+, DS720+, DS920+ 이상 (Docker 지원 모델) +- **메모리**: 4GB 이상 (8GB 권장) +- **저장공간**: 480GB SSD (충분함) +- **네트워크**: 기가비트 이더넷 + +### 소프트웨어 요구사항 +- **DSM**: 7.0 이상 +- **Docker**: Container Manager 패키지 +- **Git Server**: Git 저장소 관리용 (선택사항) + +--- + +## 🐳 1단계: Docker 환경 설정 + +### Container Manager 설치 +``` +1. 패키지 센터 → Container Manager 검색 및 설치 +2. Container Manager 실행 +3. 레지스트리 탭에서 필요한 이미지 다운로드 준비 +``` + +### 필요한 Docker 이미지 다운로드 +```bash +# SSH로 NAS 접속 후 실행 +docker pull python:3.11-slim +docker pull postgres:15-alpine +docker pull redis:7-alpine +docker pull elasticsearch:8.11.0 +docker pull nginx:alpine +``` + +### 볼륨 및 네트워크 설정 +```bash +# 전용 네트워크 생성 +docker network create industrial-net + +# 데이터 볼륨 생성 +docker volume create postgres-data +docker volume create elasticsearch-data +docker volume create redis-data +docker volume create app-logs +``` + +--- + +## 📁 2단계: 디렉토리 구조 설정 + +### NAS 내 프로젝트 디렉토리 생성 +```bash +# SSH 접속 후 디렉토리 생성 +mkdir -p /volume1/docker/industrial-info/{ + app, + data/{postgres,elasticsearch,redis,logs}, + config, + backup +} + +# 권한 설정 +chown -R 1000:1000 /volume1/docker/industrial-info +``` + +### 디렉토리 구조 +``` +/volume1/docker/industrial-info/ +├── app/ # 애플리케이션 코드 +├── data/ # 데이터 저장소 +│ ├── postgres/ # PostgreSQL 데이터 +│ ├── elasticsearch/ # Elasticsearch 데이터 +│ ├── redis/ # Redis 데이터 +│ └── logs/ # 애플리케이션 로그 +├── config/ # 설정 파일들 +└── backup/ # 백업 파일들 +``` + +--- + +## 🐘 3단계: PostgreSQL 설정 + +### PostgreSQL 컨테이너 생성 +```yaml +# docker-compose.yml의 PostgreSQL 부분 +version: '3.8' +services: + postgres: + image: postgres:15-alpine + container_name: industrial-postgres + environment: + POSTGRES_DB: industrial_info + POSTGRES_USER: industrial_user + POSTGRES_PASSWORD: secure_password_here + POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=C" + volumes: + - /volume1/docker/industrial-info/data/postgres:/var/lib/postgresql/data + - /volume1/docker/industrial-info/config/postgres.conf:/etc/postgresql/postgresql.conf + ports: + - "5432:5432" + networks: + - industrial-net + restart: unless-stopped + deploy: + resources: + limits: + memory: 1G + reservations: + memory: 512M +``` + +### PostgreSQL 최적화 설정 +```bash +# /volume1/docker/industrial-info/config/postgres.conf 생성 +cat > /volume1/docker/industrial-info/config/postgres.conf << EOF +# 시놀로지 NAS 최적화 설정 +shared_buffers = 256MB +effective_cache_size = 1GB +maintenance_work_mem = 64MB +checkpoint_completion_target = 0.9 +wal_buffers = 16MB +default_statistics_target = 100 +random_page_cost = 1.1 +effective_io_concurrency = 200 + +# 로그 설정 +log_destination = 'stderr' +logging_collector = on +log_directory = '/var/log/postgresql' +log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' +log_rotation_age = 1d +log_rotation_size = 100MB +EOF +``` + +--- + +## 🔍 4단계: Elasticsearch 설정 + +### Elasticsearch 컨테이너 (경량화 버전) +```yaml +# docker-compose.yml의 Elasticsearch 부분 + elasticsearch: + image: elasticsearch:8.11.0 + container_name: industrial-elasticsearch + environment: + - discovery.type=single-node + - "ES_JAVA_OPTS=-Xms512m -Xmx1g" # NAS 메모리 고려 + - xpack.security.enabled=false + - xpack.security.enrollment.enabled=false + volumes: + - /volume1/docker/industrial-info/data/elasticsearch:/usr/share/elasticsearch/data + ports: + - "9200:9200" + networks: + - industrial-net + restart: unless-stopped + deploy: + resources: + limits: + memory: 1.5G + reservations: + memory: 1G + ulimits: + memlock: + soft: -1 + hard: -1 +``` + +### Elasticsearch 한국어 분석기 설정 +```bash +# 컨테이너 실행 후 nori 플러그인 설치 +docker exec industrial-elasticsearch elasticsearch-plugin install analysis-nori +docker restart industrial-elasticsearch +``` + +--- + +## 🔴 5단계: Redis 설정 + +### Redis 컨테이너 +```yaml +# docker-compose.yml의 Redis 부분 + redis: + image: redis:7-alpine + container_name: industrial-redis + command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru + volumes: + - /volume1/docker/industrial-info/data/redis:/data + ports: + - "6379:6379" + networks: + - industrial-net + restart: unless-stopped + deploy: + resources: + limits: + memory: 512M + reservations: + memory: 256M +``` + +--- + +## 🐍 6단계: 애플리케이션 설정 + +### 애플리케이션 Dockerfile +```dockerfile +# /volume1/docker/industrial-info/app/Dockerfile +FROM python:3.11-slim + +WORKDIR /app + +# 시스템 패키지 설치 +RUN apt-get update && apt-get install -y \ + gcc \ + g++ \ + curl \ + && rm -rf /var/lib/apt/lists/* + +# Python 의존성 설치 +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# 애플리케이션 코드 복사 +COPY . . + +# 포트 노출 +EXPOSE 8000 + +# 애플리케이션 실행 +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] +``` + +### 애플리케이션 컨테이너 +```yaml +# docker-compose.yml의 애플리케이션 부분 + app: + build: ./app + container_name: industrial-app + environment: + - DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info + - REDIS_URL=redis://redis:6379/0 + - ELASTICSEARCH_URL=http://elasticsearch:9200 + volumes: + - /volume1/docker/industrial-info/app:/app + - /volume1/docker/industrial-info/data/logs:/app/logs + ports: + - "8000:8000" + networks: + - industrial-net + depends_on: + - postgres + - redis + - elasticsearch + restart: unless-stopped + deploy: + resources: + limits: + memory: 1G + reservations: + memory: 512M +``` + +--- + +## 🌐 7단계: Nginx 리버스 프록시 + +### Nginx 설정 +```yaml +# docker-compose.yml의 Nginx 부분 + nginx: + image: nginx:alpine + container_name: industrial-nginx + volumes: + - /volume1/docker/industrial-info/config/nginx.conf:/etc/nginx/nginx.conf + - /volume1/docker/industrial-info/data/logs:/var/log/nginx + ports: + - "80:80" + - "443:443" + networks: + - industrial-net + depends_on: + - app + restart: unless-stopped +``` + +### Nginx 설정 파일 +```nginx +# /volume1/docker/industrial-info/config/nginx.conf +events { + worker_connections 1024; +} + +http { + upstream app { + server app:8000; + } + + server { + listen 80; + server_name _; + + client_max_body_size 100M; + + location / { + proxy_pass http://app; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /api/ { + proxy_pass http://app; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + } +} +``` + +--- + +## 📦 8단계: 통합 Docker Compose + +### 완전한 docker-compose.yml +```yaml +# /volume1/docker/industrial-info/docker-compose.yml +version: '3.8' + +networks: + industrial-net: + driver: bridge + +services: + postgres: + image: postgres:15-alpine + container_name: industrial-postgres + environment: + POSTGRES_DB: industrial_info + POSTGRES_USER: industrial_user + POSTGRES_PASSWORD: secure_password_here + POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=C" + volumes: + - /volume1/docker/industrial-info/data/postgres:/var/lib/postgresql/data + ports: + - "5432:5432" + networks: + - industrial-net + restart: unless-stopped + deploy: + resources: + limits: + memory: 1G + + redis: + image: redis:7-alpine + container_name: industrial-redis + command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru + volumes: + - /volume1/docker/industrial-info/data/redis:/data + ports: + - "6379:6379" + networks: + - industrial-net + restart: unless-stopped + deploy: + resources: + limits: + memory: 512M + + elasticsearch: + image: elasticsearch:8.11.0 + container_name: industrial-elasticsearch + environment: + - discovery.type=single-node + - "ES_JAVA_OPTS=-Xms512m -Xmx1g" + - xpack.security.enabled=false + - xpack.security.enrollment.enabled=false + volumes: + - /volume1/docker/industrial-info/data/elasticsearch:/usr/share/elasticsearch/data + ports: + - "9200:9200" + networks: + - industrial-net + restart: unless-stopped + deploy: + resources: + limits: + memory: 1.5G + ulimits: + memlock: + soft: -1 + hard: -1 + + app: + build: ./app + container_name: industrial-app + environment: + - DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info + - REDIS_URL=redis://redis:6379/0 + - ELASTICSEARCH_URL=http://elasticsearch:9200 + - PYTHONPATH=/app + volumes: + - /volume1/docker/industrial-info/app:/app + - /volume1/docker/industrial-info/data/logs:/app/logs + ports: + - "8000:8000" + networks: + - industrial-net + depends_on: + - postgres + - redis + - elasticsearch + restart: unless-stopped + deploy: + resources: + limits: + memory: 1G + + nginx: + image: nginx:alpine + container_name: industrial-nginx + volumes: + - /volume1/docker/industrial-info/config/nginx.conf:/etc/nginx/nginx.conf + - /volume1/docker/industrial-info/data/logs:/var/log/nginx + ports: + - "80:80" + networks: + - industrial-net + depends_on: + - app + restart: unless-stopped + + # 데이터 수집 워커 (Celery) + worker: + build: ./app + container_name: industrial-worker + command: celery -A main.celery worker --loglevel=info + environment: + - DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info + - REDIS_URL=redis://redis:6379/0 + - ELASTICSEARCH_URL=http://elasticsearch:9200 + volumes: + - /volume1/docker/industrial-info/app:/app + - /volume1/docker/industrial-info/data/logs:/app/logs + networks: + - industrial-net + depends_on: + - postgres + - redis + - elasticsearch + restart: unless-stopped + deploy: + resources: + limits: + memory: 512M + + # 스케줄러 (Celery Beat) + scheduler: + build: ./app + container_name: industrial-scheduler + command: celery -A main.celery beat --loglevel=info + environment: + - DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info + - REDIS_URL=redis://redis:6379/0 + - ELASTICSEARCH_URL=http://elasticsearch:9200 + volumes: + - /volume1/docker/industrial-info/app:/app + - /volume1/docker/industrial-info/data/logs:/app/logs + networks: + - industrial-net + depends_on: + - postgres + - redis + - elasticsearch + restart: unless-stopped + deploy: + resources: + limits: + memory: 256M +``` + +--- + +## 🚀 9단계: 배포 및 실행 + +### 시스템 실행 +```bash +# 프로젝트 디렉토리로 이동 +cd /volume1/docker/industrial-info + +# 컨테이너 빌드 및 실행 +docker-compose up --build -d + +# 로그 확인 +docker-compose logs -f + +# 서비스 상태 확인 +docker-compose ps +``` + +### 데이터베이스 초기화 +```bash +# 애플리케이션 컨테이너에서 마이그레이션 실행 +docker exec industrial-app python manage.py migrate + +# 슈퍼유저 생성 +docker exec -it industrial-app python manage.py createsuperuser +``` + +--- + +## 📊 10단계: 모니터링 및 최적화 + +### 리소스 모니터링 +```bash +# 컨테이너 리소스 사용량 확인 +docker stats + +# 디스크 사용량 확인 +df -h /volume1 + +# 메모리 사용량 확인 +free -h +``` + +### 로그 관리 +```bash +# 로그 로테이션 설정 (crontab) +# 매일 자정에 로그 압축 및 정리 +0 0 * * * find /volume1/docker/industrial-info/data/logs -name "*.log" -mtime +7 -exec gzip {} \; +0 0 * * * find /volume1/docker/industrial-info/data/logs -name "*.gz" -mtime +30 -delete +``` + +### 성능 최적화 설정 +```bash +# 시놀로지 NAS 최적화 +echo 'vm.swappiness=10' >> /etc/sysctl.conf +echo 'vm.vfs_cache_pressure=50' >> /etc/sysctl.conf + +# Docker 로그 크기 제한 +cat > /etc/docker/daemon.json << EOF +{ + "log-driver": "json-file", + "log-opts": { + "max-size": "10m", + "max-file": "3" + } +} +EOF +``` + +--- + +## 🔄 11단계: 백업 및 복원 + +### 자동 백업 스크립트 +```bash +# /volume1/docker/industrial-info/backup/backup.sh +#!/bin/bash + +BACKUP_DIR="/volume1/docker/industrial-info/backup" +DATE=$(date +%Y%m%d_%H%M%S) + +# PostgreSQL 백업 +docker exec industrial-postgres pg_dump -U industrial_user industrial_info > $BACKUP_DIR/postgres_$DATE.sql + +# Elasticsearch 백업 (인덱스 설정만) +curl -X GET "localhost:9200/_cat/indices?v" > $BACKUP_DIR/elasticsearch_indices_$DATE.txt + +# 애플리케이션 코드 백업 +tar -czf $BACKUP_DIR/app_$DATE.tar.gz /volume1/docker/industrial-info/app + +# 7일 이상 된 백업 파일 삭제 +find $BACKUP_DIR -name "*.sql" -mtime +7 -delete +find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete + +echo "Backup completed: $DATE" +``` + +### 백업 스케줄 설정 +```bash +# crontab 설정 +# 매일 새벽 2시에 백업 실행 +0 2 * * * /volume1/docker/industrial-info/backup/backup.sh >> /volume1/docker/industrial-info/data/logs/backup.log 2>&1 +``` + +--- + +## 🌐 12단계: 외부 접근 설정 + +### 시놀로지 방화벽 설정 +``` +제어판 → 보안 → 방화벽 → 규칙 편집 +- 포트 80 (HTTP) 허용 +- 포트 443 (HTTPS) 허용 (SSL 인증서 설정 시) +- 포트 8000 (개발용, 선택사항) +``` + +### DDNS 설정 +``` +제어판 → 외부 액세스 → DDNS +- Synology DDNS 서비스 활용 +- 또는 외부 DDNS 서비스 연동 +``` + +### SSL 인증서 설정 +``` +제어판 → 보안 → 인증서 +- Let's Encrypt 무료 인증서 발급 +- 자동 갱신 설정 +``` + +--- + +## 🚨 문제 해결 + +### 일반적인 문제들 + +#### 1. 메모리 부족 +```bash +# Elasticsearch 메모리 줄이기 +# docker-compose.yml에서 ES_JAVA_OPTS 수정 +- "ES_JAVA_OPTS=-Xms256m -Xmx512m" + +# 불필요한 컨테이너 중지 +docker-compose stop worker scheduler +``` + +#### 2. 디스크 공간 부족 +```bash +# Docker 이미지 정리 +docker system prune -a + +# 로그 파일 정리 +docker-compose exec app find /app/logs -name "*.log" -mtime +3 -delete + +# 백업 파일 정리 +find /volume1/docker/industrial-info/backup -mtime +30 -delete +``` + +#### 3. 네트워크 연결 문제 +```bash +# 네트워크 재생성 +docker network rm industrial-net +docker network create industrial-net + +# 컨테이너 재시작 +docker-compose restart +``` + +### 성능 튜닝 + +#### SSD 최적화 +```bash +# SSD 수명 연장을 위한 설정 +echo 'deadline' > /sys/block/sda/queue/scheduler +echo '1' > /sys/block/sda/queue/iosched/fifo_batch +``` + +#### 네트워크 최적화 +```bash +# TCP 버퍼 크기 조정 +echo 'net.core.rmem_max = 16777216' >> /etc/sysctl.conf +echo 'net.core.wmem_max = 16777216' >> /etc/sysctl.conf +``` + +--- + +## 📈 시놀로지 vs Mac 비교 + +### 시놀로지 NAS 장점 +- ✅ **24시간 안정 운영**: 전력 효율적, 저소음 +- ✅ **자동 백업**: RAID 구성, 스냅샷 기능 +- ✅ **원격 접근**: DDNS, VPN 지원 +- ✅ **비용 효율**: 전력비 절약, 별도 서버 불필요 +- ✅ **확장성**: 패키지 센터, Docker 지원 + +### Mac 개발 환경 장점 +- ✅ **개발 편의성**: 네이티브 도구, IDE 지원 +- ✅ **성능**: 더 빠른 CPU, 메모리 +- ✅ **디버깅**: 직접적인 로그 접근 +- ✅ **유연성**: 패키지 관리 용이 + +### 권장 사용 시나리오 +``` +개발 단계: Mac (HOMEBREW_SETUP.md) + ↓ +테스트/스테이징: 시놀로지 NAS (현재 문서) + ↓ +프로덕션: 클라우드 또는 전용 서버 +``` + +--- + +## 🎯 결론 + +시놀로지 NAS는 다음과 같은 경우에 최적입니다: + +1. **24시간 서비스 운영**이 필요한 경우 +2. **전력 효율성**을 중시하는 경우 +3. **자동 백업 및 데이터 보호**가 중요한 경우 +4. **원격 접근**이 필요한 경우 +5. **비용 절약**을 원하는 경우 + +480GB SSD는 이 프로젝트에 충분하며, 적절한 로그 관리와 백업 정책으로 장기간 안정적인 운영이 가능합니다. + +--- + +**시놀로지 NAS로 더 안정적이고 효율적인 산업 정보 시스템을 구축해보세요!** 🏠🚀 diff --git a/TECH_STACK.md b/TECH_STACK.md new file mode 100644 index 0000000..2f02a65 --- /dev/null +++ b/TECH_STACK.md @@ -0,0 +1,285 @@ +# 🛠️ 기술 스택 (Tech Stack) + +## 📋 개요 + +산업 전문 정보 수집 시스템의 기술 스택을 정리한 문서입니다. 각 기술의 선택 이유와 역할을 포함하여 설명합니다. + +--- + +## 🖥️ Backend + +### 핵심 프레임워크 +- **Python 3.11+** + - 선택 이유: 풍부한 NLP 라이브러리 생태계, 데이터 처리 최적화 + - 역할: 메인 백엔드 언어 + +- **FastAPI** + - 선택 이유: 고성능 비동기 처리, 자동 API 문서 생성, 타입 힌팅 지원 + - 역할: REST API 서버, 웹 애플리케이션 백엔드 + +### 데이터베이스 & 검색 +- **PostgreSQL** + - 선택 이유: 구조화된 메타데이터 저장, ACID 트랜잭션, JSON 지원 + - 역할: 메인 데이터베이스, 사용자 정보, 문서 메타데이터 + +- **Elasticsearch** + - 선택 이유: 전문 검색, 다차원 필터링, 실시간 검색 성능 + - 역할: 문서 검색 엔진, 태그 기반 필터링, 전문 검색 + +- **Redis** + - 선택 이유: 고속 캐싱, 세션 관리, 실시간 데이터 처리 + - 역할: 캐시 레이어, 검색 결과 캐싱, 트렌딩 데이터 + +### NLP & 데이터 처리 +- **spaCy** + - 선택 이유: 산업용 NLP, 커스텀 모델 지원, 한국어 지원 + - 역할: 개체명 인식(NER), 기술 용어 추출 + +- **Transformers (Hugging Face)** + - 선택 이유: 최신 언어 모델, 의미 기반 검색 + - 역할: 문서 임베딩, 의미 유사도 계산 + +- **scikit-learn** + - 선택 이유: 머신러닝 파이프라인, 텍스트 분류 + - 역할: 문서 분류, 태그 예측, 트렌드 분석 + +### 비동기 처리 & 스케줄링 +- **Celery** + - 선택 이유: 분산 태스크 큐, 스케줄링 지원 + - 역할: RSS 수집, 논문 처리, 배치 작업 + +- **Redis (Broker)** + - 선택 이유: Celery 메시지 브로커, 고성능 + - 역할: 태스크 큐 브로커 + +### 문서 처리 +- **PyPDF2 / pdfplumber** + - 선택 이유: PDF 텍스트 추출, 메타데이터 파싱 + - 역할: 논문 PDF 처리, 기술 문서 분석 + +- **BeautifulSoup** + - 선택 이유: HTML 파싱, 웹 스크래핑 + - 역할: RSS 피드 처리, 웹사이트 크롤링 + +- **Scrapy** + - 선택 이유: 대규모 웹 크롤링, 비동기 처리 + - 역할: 표준 기관 웹사이트 모니터링 + +--- + +## 🎨 Frontend + +### 핵심 프레임워크 +- **React 18** + - 선택 이유: 컴포넌트 기반 개발, 풍부한 생태계 + - 역할: 사용자 인터페이스 구축 + +- **Next.js 13+** + - 선택 이유: SSR/SSG 지원, 성능 최적화, 파일 기반 라우팅 + - 역할: React 애플리케이션 프레임워크 + +### UI & 스타일링 +- **Tailwind CSS** + - 선택 이유: 유틸리티 우선, 빠른 개발, 일관된 디자인 + - 역할: CSS 프레임워크, 반응형 디자인 + +- **Material-UI (MUI)** + - 선택 이유: 전문적인 UI 컴포넌트, 접근성 지원 + - 역할: 복잡한 UI 컴포넌트 (테이블, 폼 등) + +### 데이터 시각화 +- **D3.js** + - 선택 이유: 고도로 커스터마이징 가능한 시각화 + - 역할: 기술 네트워크 그래프, 복잡한 차트 + +- **Chart.js** + - 선택 이유: 간단한 차트 생성, React 통합 + - 역할: 트렌드 차트, 통계 그래프 + +### 검색 & 상호작용 +- **Algolia InstantSearch** + - 선택 이유: 실시간 검색, 자동완성, 필터링 + - 역할: 검색 UI 컴포넌트 + +--- + +## 🔧 전문 분야 도구 + +### 학술 데이터 수집 +- **arXiv API** + - 선택 이유: 물리학/공학 논문 접근 + - 역할: 최신 연구 논문 수집 + +- **PubMed API** + - 선택 이유: 의학/보건 관련 논문 + - 역할: 산업안전 의학 연구 수집 + +- **IEEE Xplore API** + - 선택 이유: 전기/전자/컴퓨터 공학 논문 + - 역할: 기술 표준 및 연구 논문 수집 + +### 표준 모니터링 +- **ASME 웹사이트 크롤러** + - 선택 이유: 압력용기 표준 업데이트 추적 + - 역할: BPVC 등 표준 변경사항 모니터링 + +- **KGS 웹사이트 크롤러** + - 선택 이유: 한국 가스안전 기준 추적 + - 역할: 국내 압력용기 기준 업데이트 + +- **API 웹사이트 크롤러** + - 선택 이유: 석유/가스 산업 표준 추적 + - 역할: API 표준 업데이트 모니터링 + +### 전문 용어 처리 +- **압력용기 전문 용어 사전** + - 선택 이유: 정확한 기술 용어 인식 + - 역할: NER 모델 학습 데이터 + +- **플랜트 장비 분류 체계** + - 선택 이유: 체계적인 장비 분류 + - 역할: 태그 정규화 및 분류 + +- **산업안전 용어 온톨로지** + - 선택 이유: 안전 분야 전문 용어 체계화 + - 역할: 안전 관련 문서 분류 + +--- + +## 🏗️ Infrastructure + +### 컨테이너화 +- **Docker** + - 선택 이유: 환경 일관성, 배포 간소화 + - 역할: 애플리케이션 컨테이너화 + +- **Docker Compose** + - 선택 이유: 다중 서비스 오케스트레이션 + - 역할: 로컬 개발 환경 구성 + +### 모니터링 & 로깅 +- **Prometheus** + - 선택 이유: 시계열 메트릭 수집, 알림 시스템 + - 역할: 시스템 메트릭 모니터링 + +- **Grafana** + - 선택 이유: 메트릭 시각화, 대시보드 + - 역할: 모니터링 대시보드 + +- **ELK Stack (Elasticsearch, Logstash, Kibana)** + - 선택 이유: 중앙화된 로그 관리, 검색 가능한 로그 + - 역할: 애플리케이션 로그 수집 및 분석 + +### CI/CD +- **GitHub Actions** + - 선택 이유: GitHub 통합, 무료 사용량 + - 역할: 자동 빌드, 테스트, 배포 + +### 스토리지 +- **MinIO (S3 호환)** + - 선택 이유: 오픈소스 객체 스토리지, S3 호환성 + - 역할: 논문 PDF, 이미지 파일 저장 + +--- + +## 🍺 macOS 개발 환경 (Homebrew 기반) + +### 패키지 매니저 +- **Homebrew** + - 선택 이유: macOS 표준 패키지 매니저 + - 역할: 개발 도구 설치 및 관리 + +### 필수 개발 도구 +```bash +# 언어 런타임 +brew install python@3.11 # Python 런타임 +brew install node@18 # Node.js 런타임 + +# 데이터베이스 +brew install postgresql # PostgreSQL 데이터베이스 +brew install redis # Redis 캐시/브로커 + +# 검색 엔진 +brew install elasticsearch # Elasticsearch 검색 엔진 + +# 개발 도구 +brew install git # 버전 관리 +brew install htop # 시스템 모니터링 + +# GUI 애플리케이션 +brew install --cask docker # Docker Desktop +brew install --cask visual-studio-code # IDE +``` + +### 서비스 관리 +```bash +# 서비스 시작 +brew services start postgresql +brew services start redis +brew services start elasticsearch + +# 서비스 상태 확인 +brew services list +``` + +--- + +## 📊 성능 최적화 전략 + +### 캐싱 계층 +``` +L1: Redis (실시간 검색 결과, 트렌딩 태그) +L2: PostgreSQL (구조화된 메타데이터, 사용자 프로필) +L3: Elasticsearch (전문 검색, 태그 인덱스) +L4: MinIO/S3 (원본 문서, 논문 PDF) +``` + +### 메모리 최적화 (Mac mini 8GB 기준) +```bash +# Elasticsearch JVM 설정 +export ELASTICSEARCH_JAVA_OPTS="-Xms512m -Xmx1g" + +# Redis 메모리 제한 +export REDIS_MAXMEMORY="256mb" + +# Python 프로세스 최적화 +export PYTHONOPTIMIZE=1 +``` + +### 검색 성능 최적화 +- **사전 계산**: 자주 검색되는 조합 캐싱 +- **인덱스 최적화**: 전문 용어 기반 역색인 +- **벡터 검색**: BERT 기반 의미 검색 +- **지역별 샤딩**: 데이터 분산 저장 + +--- + +## 🔄 데이터 파이프라인 + +### 수집 → 처리 → 저장 → 검색 +``` +RSS/API 수집 → NLP 태그 추출 → PostgreSQL 저장 → Elasticsearch 인덱싱 → Redis 캐싱 +``` + +### 실시간 처리 +- **RSS 모니터링**: 5분마다 새 피드 확인 +- **논문 동기화**: 일일 1회 학술 DB 스캔 +- **표준 업데이트**: 주간 공식 사이트 모니터링 + +--- + +## 🚀 확장성 고려사항 + +### 수평 확장 +- **마이크로서비스**: 기능별 서비스 분리 +- **로드 밸런싱**: 검색 서비스 다중 인스턴스 +- **데이터베이스 샤딩**: 지역/분야별 데이터 분산 + +### 성능 모니터링 +- **메트릭 수집**: 응답 시간, 처리량, 에러율 +- **알림 시스템**: 임계값 초과 시 자동 알림 +- **용량 계획**: 데이터 증가율 기반 리소스 계획 + +--- + +이 기술 스택은 산업 전문 정보의 특성을 고려하여 선택되었으며, macOS 환경에서의 개발 편의성과 운영 안정성을 모두 고려한 구성입니다.