📚 Add comprehensive setup documentation

- 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
This commit is contained in:
hyungi
2025-09-14 12:23:35 +09:00
parent 64b8501afa
commit 2fb0637ad1
4 changed files with 2205 additions and 0 deletions

607
DS1525_OPTIMIZED_SETUP.md Normal file
View File

@@ -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으로 모든 서비스를 여유롭게 돌릴 수 있어요. 완벽한 선택입니다! 👍

592
HOMEBREW_SETUP.md Normal file
View File

@@ -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를 사용하여 완전한 개발환경을 구축할 수 있습니다. 각 단계별로 진행하면서 문제가 발생하면 문제 해결 섹션을 참조하세요.

721
SYNOLOGY_SETUP.md Normal file
View File

@@ -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로 더 안정적이고 효율적인 산업 정보 시스템을 구축해보세요!** 🏠🚀

285
TECH_STACK.md Normal file
View File

@@ -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 환경에서의 개발 편의성과 운영 안정성을 모두 고려한 구성입니다.