Files
news-project/SYNOLOGY_SETUP.md
hyungi 2fb0637ad1 📚 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
2025-09-14 12:23:35 +09:00

722 lines
17 KiB
Markdown

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