🧹 Consolidate documentation

-  Created unified DEVELOPMENT_DEPLOYMENT_GUIDE.md
- 🗑️ Removed individual setup guides:
  - TECH_STACK.md
  - HOMEBREW_SETUP.md
  - SYNOLOGY_SETUP.md
  - DS1525_OPTIMIZED_SETUP.md
  - DEV_DEPLOY_PIPELINE.md
  - DOCKER_DEV_GUIDE.md

All content consolidated into single development-deployment guide
focused on Mac → DS1525+ (32GB RAM) workflow
This commit is contained in:
hyungi
2025-09-14 12:58:55 +09:00
parent 2fb0637ad1
commit 016682269a
5 changed files with 864 additions and 2205 deletions

View File

@@ -0,0 +1,864 @@
# 🚀 개발-배포 통합 가이드 (Mac → DS1525+ 32GB)
## 📋 개요
Mac에서 개발하고 Synology DS1525+ (32GB RAM, 480GB SSD)에 배포하는 완전한 개발-배포 파이프라인 가이드입니다.
---
## 🔧 하드웨어 사양
### 개발 환경: Mac
- **MacBook Pro/Mac Mini** (M1/M2 또는 Intel)
- **메모리**: 16GB 이상 권장
- **저장공간**: 100GB 이상 여유 공간
### 배포 환경: Synology DS1525+
- **CPU**: AMD Ryzen R1600 (4코어 2.6GHz)
- **메모리**: 32GB RAM (대용량!)
- **저장장치**: 시놀로지 정품 2.5" SSD 480GB
- **네트워크**: 기가비트 이더넷 x4
- **OS**: DSM 7.0+
---
## 🐳 Docker 기반 개발-배포 전략
### 아키텍처 호환성 해결
```
Mac (개발) DS1525+ (배포)
├── M1/M2: arm64 → ├── AMD Ryzen: amd64
├── Intel: amd64 → └── Linux 컨테이너
└── Docker Desktop └── Container Manager
```
**핵심 해결책: 멀티 아키텍처 빌드**
- Mac에서 개발: `arm64` 또는 `amd64`
- DS1525+에서 실행: `amd64` 보장
- 크로스 플랫폼 빌드로 호환성 문제 완전 해결
---
## 🛠️ 1단계: Mac 개발 환경 설정
### Docker Desktop 설치 및 최적화
```bash
# Homebrew로 Docker Desktop 설치
brew install --cask docker
# Docker Desktop 리소스 설정 (GUI)
# Memory: 8GB (16GB Mac 기준)
# CPUs: 4 cores
# Swap: 2GB
# Disk: 100GB
```
### Docker Buildx 설정 (멀티 아키텍처 빌드용)
```bash
# 멀티 플랫폼 빌더 생성
docker buildx create --name multiarch --driver docker-container --use
docker buildx inspect --bootstrap
# 지원 플랫폼 확인
docker buildx ls
```
### 프로젝트 구조 설정
```
project/
├── docker/
│ ├── Dockerfile.dev # Mac 개발용
│ ├── Dockerfile.prod # DS1525+ 배포용
│ ├── docker-compose.dev.yml # 로컬 개발
│ └── docker-compose.prod.yml# DS1525+ 배포
├── scripts/
│ ├── dev-start.sh # 개발 시작
│ ├── build-deploy.sh # 빌드 & 배포
│ └── rollback.sh # 롤백
├── src/
│ ├── backend/
│ └── frontend/
├── config/
│ ├── nginx/
│ ├── postgres/
│ └── monitoring/
└── environments/
├── .env.development
└── .env.production
```
---
## 🏗️ 2단계: 개발용 Docker 설정
### 개발용 Dockerfile
```dockerfile
# docker/Dockerfile.dev
FROM --platform=linux/amd64 python:3.11-slim
# 개발 도구 설치
RUN apt-get update && apt-get install -y \
gcc g++ curl vim git \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Python 개발 의존성
COPY requirements.dev.txt .
RUN pip install --no-cache-dir -r requirements.dev.txt
# 환경 설정
ENV PYTHONPATH=/app
ENV PYTHONUNBUFFERED=1
ENV RELOAD=true
EXPOSE 8000 5678
# Hot Reload 개발 서버
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
```
### 개발용 Docker Compose
```yaml
# docker/docker-compose.dev.yml
version: '3.8'
services:
app:
build:
context: ..
dockerfile: docker/Dockerfile.dev
platform: linux/amd64 # DS1525+ 호환성 보장
container_name: app-dev
environment:
- DEBUG=true
- DATABASE_URL=postgresql://dev_user:dev_pass@postgres:5432/app_dev
- REDIS_URL=redis://redis:6379/0
volumes:
- ../src:/app/src:cached # Mac 성능 최적화
- ../config:/app/config:cached
ports:
- "8000:8000"
- "5678:5678" # 디버깅 포트
depends_on:
- postgres
- redis
networks:
- dev-network
postgres:
image: postgres:15-alpine
platform: linux/amd64
container_name: postgres-dev
environment:
POSTGRES_DB: app_dev
POSTGRES_USER: dev_user
POSTGRES_PASSWORD: dev_pass
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
networks:
- dev-network
redis:
image: redis:7-alpine
platform: linux/amd64
container_name: redis-dev
volumes:
- redis_data:/data
ports:
- "6379:6379"
networks:
- dev-network
networks:
dev-network:
driver: bridge
volumes:
postgres_data:
redis_data:
```
### 개발 시작 스크립트
```bash
#!/bin/bash
# scripts/dev-start.sh
echo "🚀 개발 환경 시작"
# 개발 컨테이너 시작
docker-compose -f docker/docker-compose.dev.yml up -d
# 서비스 준비 대기
echo "⏳ 서비스 시작 대기..."
sleep 15
# 헬스체크
if curl -f http://localhost:8000/health > /dev/null 2>&1; then
echo "✅ 개발 환경 준비 완료!"
echo "🌐 애플리케이션: http://localhost:8000"
echo "🗄️ 데이터베이스: localhost:5432"
echo "🔴 Redis: localhost:6379"
else
echo "❌ 서비스 시작 실패"
docker-compose -f docker/docker-compose.dev.yml logs
fi
```
---
## 🏭 3단계: DS1525+ 배포 환경 설정
### DS1525+ 32GB 최적화 구성
```
총 메모리: 32GB 할당 계획
├── DSM 시스템: 2GB
├── PostgreSQL: 4GB (고성능 DB)
├── Elasticsearch: 8GB (대용량 검색)
├── Redis: 2GB (대용량 캐시)
├── 애플리케이션: 4GB (멀티 워커)
├── 모니터링: 2GB (Prometheus + Grafana)
├── 시스템 캐시: 8GB
└── 여유 공간: 2GB
```
### 배포용 Dockerfile (최적화)
```dockerfile
# docker/Dockerfile.prod
FROM --platform=$BUILDPLATFORM python:3.11-slim AS builder
ARG TARGETPLATFORM
ARG BUILDPLATFORM
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
# 프로덕션 이미지
FROM python:3.11-slim AS production
WORKDIR /app
# 빌드된 패키지 복사
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY --from=builder /usr/local/bin /usr/local/bin
# 애플리케이션 코드 복사
COPY src/ ./src/
COPY config/ ./config/
# 헬스체크 추가
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1
EXPOSE 8000
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
```
### DS1525+ 배포용 Docker Compose
```yaml
# docker/docker-compose.prod.yml
version: '3.8'
services:
app:
build:
context: ..
dockerfile: docker/Dockerfile.prod
platforms:
- linux/amd64
container_name: app-prod
environment:
- DATABASE_URL=postgresql://app_user:${DB_PASSWORD}@postgres:5432/app_prod
- REDIS_URL=redis://redis:6379/0
- WORKERS=4
volumes:
- /volume1/docker/app/logs:/app/logs
ports:
- "8000:8000"
networks:
- prod-network
depends_on:
- postgres
- redis
restart: unless-stopped
deploy:
resources:
limits:
memory: 4G
cpus: '2.0'
postgres:
image: postgres:15-alpine
platform: linux/amd64
container_name: postgres-prod
environment:
POSTGRES_DB: app_prod
POSTGRES_USER: app_user
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- /volume1/docker/app/data/postgres:/var/lib/postgresql/data
- ../config/postgresql.conf:/etc/postgresql/postgresql.conf
ports:
- "5432:5432"
networks:
- prod-network
restart: unless-stopped
deploy:
resources:
limits:
memory: 4G
cpus: '2.0'
command: postgres -c config_file=/etc/postgresql/postgresql.conf
redis:
image: redis:7-alpine
platform: linux/amd64
container_name: redis-prod
command: redis-server --maxmemory 2gb --maxmemory-policy allkeys-lru
volumes:
- /volume1/docker/app/data/redis:/data
ports:
- "6379:6379"
networks:
- prod-network
restart: unless-stopped
deploy:
resources:
limits:
memory: 2G
cpus: '1.0'
elasticsearch:
image: elasticsearch:8.11.0
platform: linux/amd64
container_name: elasticsearch-prod
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms4g -Xmx8g"
- xpack.security.enabled=false
volumes:
- /volume1/docker/app/data/elasticsearch:/usr/share/elasticsearch/data
ports:
- "9200:9200"
networks:
- prod-network
restart: unless-stopped
deploy:
resources:
limits:
memory: 10G
cpus: '2.0'
nginx:
image: nginx:alpine
platform: linux/amd64
container_name: nginx-prod
volumes:
- ../config/nginx/nginx.conf:/etc/nginx/nginx.conf
- /volume1/docker/app/logs:/var/log/nginx
ports:
- "80:80"
- "443:443"
networks:
- prod-network
depends_on:
- app
restart: unless-stopped
# 모니터링
prometheus:
image: prom/prometheus:latest
platform: linux/amd64
container_name: prometheus
volumes:
- ../config/prometheus.yml:/etc/prometheus/prometheus.yml
- /volume1/docker/app/data/prometheus:/prometheus
ports:
- "9090:9090"
networks:
- prod-network
restart: unless-stopped
deploy:
resources:
limits:
memory: 1G
grafana:
image: grafana/grafana:latest
platform: linux/amd64
container_name: grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123
volumes:
- /volume1/docker/app/data/grafana:/var/lib/grafana
ports:
- "3000:3000"
networks:
- prod-network
restart: unless-stopped
deploy:
resources:
limits:
memory: 1G
networks:
prod-network:
driver: bridge
volumes:
postgres_data:
redis_data:
elasticsearch_data:
```
---
## 🚀 4단계: 자동화 빌드 & 배포
### 통합 빌드-배포 스크립트
```bash
#!/bin/bash
# scripts/build-deploy.sh
set -e
# 설정
PROJECT_NAME="app"
NAS_HOST="192.168.1.100"
NAS_USER="admin"
VERSION=$(git describe --tags --always --dirty)
echo "🚀 빌드 & 배포 시작: $PROJECT_NAME v$VERSION"
# 1. 로컬 테스트
echo "🧪 로컬 테스트 실행..."
docker-compose -f docker/docker-compose.dev.yml up -d
sleep 30
if curl -f http://localhost:8000/health > /dev/null 2>&1; then
echo "✅ 로컬 테스트 통과"
docker-compose -f docker/docker-compose.dev.yml down
else
echo "❌ 로컬 테스트 실패"
docker-compose -f docker/docker-compose.dev.yml logs
exit 1
fi
# 2. 멀티 아키텍처 빌드 (DS1525+ 호환)
echo "🔨 DS1525+ 호환 이미지 빌드..."
docker buildx build \
--platform linux/amd64 \
--tag $PROJECT_NAME:$VERSION \
--tag $PROJECT_NAME:latest \
--file docker/Dockerfile.prod \
--load \
.
# 3. DS1525+로 이미지 전송
echo "📤 DS1525+로 이미지 전송..."
docker save $PROJECT_NAME:latest | ssh $NAS_USER@$NAS_HOST "docker load"
# 4. 환경변수 동기화
echo "⚙️ 환경변수 동기화..."
scp environments/.env.production $NAS_USER@$NAS_HOST:/volume1/docker/$PROJECT_NAME/.env
# 5. DS1525+에서 배포 실행
echo "🚢 DS1525+ 배포 실행..."
ssh $NAS_USER@$NAS_HOST << EOF
cd /volume1/docker/$PROJECT_NAME
# 기존 컨테이너 백업 (롤백용)
if docker-compose -f docker-compose.prod.yml ps | grep -q "Up"; then
echo "📦 롤백용 백업 생성..."
docker-compose -f docker-compose.prod.yml config > docker-compose.backup.yml
docker images --format "{{.Repository}}:{{.Tag}}" | grep $PROJECT_NAME | head -1 > last_image.txt
fi
# 새 버전 배포
docker-compose -f docker-compose.prod.yml down
docker-compose -f docker-compose.prod.yml up -d
# 이미지 정리
docker image prune -f
EOF
# 6. 배포 후 헬스체크
echo "🏥 배포 후 헬스체크..."
sleep 60
for i in {1..10}; do
if curl -f http://$NAS_HOST:8000/health > /dev/null 2>&1; then
echo "✅ 배포 성공 및 헬스체크 통과"
break
fi
if [ $i -eq 10 ]; then
echo "❌ 헬스체크 실패 - 롤백 필요"
exit 1
fi
echo "⏳ 헬스체크 재시도 ($i/10)..."
sleep 10
done
# 7. 배포 완료 정보
echo ""
echo "🎉 배포 완료!"
echo "📊 배포 정보:"
echo " - 프로젝트: $PROJECT_NAME"
echo " - 버전: $VERSION"
echo " - 대상: DS1525+ (32GB RAM, 480GB SSD)"
echo " - 배포 시간: $(date)"
echo ""
echo "🔗 접속 링크:"
echo " - 애플리케이션: http://$NAS_HOST"
echo " - 모니터링: http://$NAS_HOST:3000 (admin/admin123)"
echo " - Prometheus: http://$NAS_HOST:9090"
```
### 롤백 스크립트
```bash
#!/bin/bash
# scripts/rollback.sh
set -e
NAS_HOST="192.168.1.100"
NAS_USER="admin"
PROJECT_NAME="app"
echo "🔄 롤백 시작..."
ssh $NAS_USER@$NAS_HOST << EOF
cd /volume1/docker/$PROJECT_NAME
# 백업 파일 확인
if [[ ! -f "docker-compose.backup.yml" ]] || [[ ! -f "last_image.txt" ]]; then
echo "❌ 백업 파일을 찾을 수 없습니다"
exit 1
fi
# 현재 컨테이너 중지
docker-compose -f docker-compose.prod.yml down
# 이전 설정으로 복원
cp docker-compose.backup.yml docker-compose.prod.yml
# 컨테이너 시작
docker-compose -f docker-compose.prod.yml up -d
echo "✅ 롤백 완료"
EOF
# 헬스체크
sleep 30
if curl -f http://$NAS_HOST:8000/health > /dev/null 2>&1; then
echo "✅ 롤백 성공 및 헬스체크 통과"
else
echo "❌ 롤백 후 헬스체크 실패"
exit 1
fi
```
---
## 📊 5단계: DS1525+ 성능 최적화
### PostgreSQL 최적화 (32GB 활용)
```ini
# 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
# AMD Ryzen 4코어 활용
max_worker_processes = 4
max_parallel_workers = 4
max_parallel_workers_per_gather = 2
# SSD 최적화
random_page_cost = 1.1
effective_io_concurrency = 200
# 연결 및 체크포인트
max_connections = 200
checkpoint_completion_target = 0.9
checkpoint_timeout = 15min
max_wal_size = 4GB
```
### Nginx 설정 (고성능)
```nginx
# config/nginx/nginx.conf
worker_processes 4; # AMD Ryzen 4코어
events {
worker_connections 2048;
use epoll;
multi_accept on;
}
http {
upstream app {
server app:8000;
keepalive 32;
}
server {
listen 80;
server_name _;
client_max_body_size 100M;
# 정적 파일 캐싱
location /static/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# API 프록시
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;
# 연결 유지
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
}
```
---
## 🔧 6단계: 개발 워크플로우
### 일일 개발 루틴
```bash
# 개발 시작
./scripts/dev-start.sh
# 코드 변경 후 테스트
docker-compose -f docker/docker-compose.dev.yml logs -f app
# 개발 완료 후 배포
git add .
git commit -m "feat: 새로운 기능 추가"
git push origin main
# 배포 실행
./scripts/build-deploy.sh
# 개발 환경 정리
docker-compose -f docker/docker-compose.dev.yml down
```
### 브랜치별 배포 전략
```bash
# develop 브랜치 → 스테이징 자동 배포
git checkout develop
git merge feature/new-feature
git push origin develop
# main 브랜치 → 프로덕션 배포
git checkout main
git merge develop
git tag v1.2.0
git push origin main --tags
./scripts/build-deploy.sh
```
---
## 📈 7단계: 모니터링 및 유지보수
### 리소스 모니터링
```bash
# DS1525+ 리소스 확인
ssh admin@nas.local << 'EOF'
echo "💾 메모리 사용량:"
free -h
echo "🐳 Docker 컨테이너 상태:"
docker stats --no-stream
echo "💿 디스크 사용량:"
df -h /volume1
echo "🔥 CPU 사용률:"
top -bn1 | grep "Cpu(s)"
EOF
```
### 자동 백업 (480GB SSD 최적화)
```bash
#!/bin/bash
# scripts/backup.sh
BACKUP_DIR="/volume1/backup/app"
DATE=$(date +%Y%m%d_%H%M%S)
# 백업 디렉토리 생성
mkdir -p $BACKUP_DIR/{database,volumes,configs}
echo "💾 백업 시작: $DATE"
# 1. 데이터베이스 백업 (압축)
docker exec postgres-prod pg_dump -U app_user app_prod | gzip > $BACKUP_DIR/database/postgres_$DATE.sql.gz
# 2. 중요 볼륨만 백업 (용량 고려)
docker run --rm \
-v app_postgres_data:/source:ro \
-v $BACKUP_DIR/volumes:/backup \
alpine tar czf /backup/postgres_$DATE.tar.gz -C /source .
# 3. 설정 파일 백업
tar czf $BACKUP_DIR/configs/configs_$DATE.tar.gz \
/volume1/docker/app/docker-compose.prod.yml \
/volume1/docker/app/.env \
/volume1/docker/app/config/
# 4. 오래된 백업 정리 (SSD 수명 고려)
find $BACKUP_DIR -name "*.gz" -mtime +7 -delete
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete
echo "✅ 백업 완료: $DATE"
```
---
## 🎯 성능 벤치마크 (DS1525+ 32GB)
### 예상 성능 지표
```
🚀 DS1525+ 32GB 성능 (최적화 후)
├── 동시 사용자: 200명
├── 응답 시간: 50-100ms
├── 처리량: 2,000 req/sec
├── 메모리 사용률: 70-80%
├── CPU 사용률: 30-50%
└── 디스크 I/O: SSD 최적화
```
### 리소스 할당 현황
```
총 32GB 메모리 활용:
├── PostgreSQL: 4GB (12.5%)
├── Elasticsearch: 8GB (25%)
├── Redis: 2GB (6.25%)
├── 애플리케이션: 4GB (12.5%)
├── 모니터링: 2GB (6.25%)
├── 시스템 캐시: 8GB (25%)
├── DSM: 2GB (6.25%)
└── 여유: 2GB (6.25%)
```
---
## 🚨 문제 해결 가이드
### 일반적인 문제들
#### 1. 아키텍처 호환성 오류
```bash
# 오류: exec format error
# 해결: 플랫폼 명시적 지정
docker run --platform linux/amd64 your-image
# 또는 Dockerfile에서
FROM --platform=linux/amd64 python:3.11-slim
```
#### 2. 메모리 부족 (32GB에서는 드물지만)
```bash
# 메모리 사용량 확인
docker stats
# Elasticsearch 메모리 줄이기 (필요시)
ES_JAVA_OPTS="-Xms2g -Xmx4g"
```
#### 3. 디스크 공간 부족 (480GB SSD)
```bash
# Docker 정리
docker system prune -a
# 로그 정리
find /volume1/docker/app/logs -name "*.log" -mtime +3 -delete
# 백업 정리
find /volume1/backup -mtime +30 -delete
```
---
## 📋 배포 체크리스트
### 배포 전 확인사항
```bash
✅ 체크리스트
- [ ] 로컬 테스트 통과
- [ ] 멀티 아키텍처 빌드 성공
- [ ] 환경변수 설정 완료
- [ ] 데이터베이스 마이그레이션 준비
- [ ] 헬스체크 엔드포인트 구현
- [ ] 백업 계획 수립
- [ ] 롤백 계획 준비
- [ ] 모니터링 설정 확인
```
### 배포 후 확인사항
```bash
✅ 배포 후 체크
- [ ] 애플리케이션 정상 동작
- [ ] 데이터베이스 연결 확인
- [ ] 캐시 동작 확인
- [ ] 검색 기능 확인
- [ ] 모니터링 대시보드 확인
- [ ] 로그 수집 확인
- [ ] 백업 자동화 확인
```
---
## 🎉 결론
### DS1525+ 32GB의 압도적 장점
-**충분한 성능**: 32GB RAM으로 모든 서비스 여유롭게 운영
-**24시간 안정성**: 전력 효율적, 저소음 운영
-**완전 자동화**: 개발부터 배포까지 스크립트 기반
-**확장 가능**: 향후 서비스 확장 시에도 여유로움
-**비용 효율**: 클라우드 대비 월등한 비용 절약
### 개발-배포 파이프라인 완성
```
Mac 개발 (Hot Reload)
멀티 아키텍처 빌드
DS1525+ 자동 배포
실시간 모니터링
자동 백업
```
**이제 개발에만 집중하고 배포는 스크립트가 알아서!** 🚀

View File

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

View File

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

View File

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

View File

@@ -1,285 +0,0 @@
# 🛠️ 기술 스택 (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 환경에서의 개발 편의성과 운영 안정성을 모두 고려한 구성입니다.