📚 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:
607
DS1525_OPTIMIZED_SETUP.md
Normal file
607
DS1525_OPTIMIZED_SETUP.md
Normal 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
592
HOMEBREW_SETUP.md
Normal 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
721
SYNOLOGY_SETUP.md
Normal 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
285
TECH_STACK.md
Normal 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 환경에서의 개발 편의성과 운영 안정성을 모두 고려한 구성입니다.
|
||||
Reference in New Issue
Block a user