- 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
17 KiB
17 KiB
🏠 시놀로지 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 이미지 다운로드
# 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
볼륨 및 네트워크 설정
# 전용 네트워크 생성
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 내 프로젝트 디렉토리 생성
# 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 컨테이너 생성
# 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 최적화 설정
# /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 컨테이너 (경량화 버전)
# 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 한국어 분석기 설정
# 컨테이너 실행 후 nori 플러그인 설치
docker exec industrial-elasticsearch elasticsearch-plugin install analysis-nori
docker restart industrial-elasticsearch
🔴 5단계: Redis 설정
Redis 컨테이너
# 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
# /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"]
애플리케이션 컨테이너
# 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 설정
# 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 설정 파일
# /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
# /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단계: 배포 및 실행
시스템 실행
# 프로젝트 디렉토리로 이동
cd /volume1/docker/industrial-info
# 컨테이너 빌드 및 실행
docker-compose up --build -d
# 로그 확인
docker-compose logs -f
# 서비스 상태 확인
docker-compose ps
데이터베이스 초기화
# 애플리케이션 컨테이너에서 마이그레이션 실행
docker exec industrial-app python manage.py migrate
# 슈퍼유저 생성
docker exec -it industrial-app python manage.py createsuperuser
📊 10단계: 모니터링 및 최적화
리소스 모니터링
# 컨테이너 리소스 사용량 확인
docker stats
# 디스크 사용량 확인
df -h /volume1
# 메모리 사용량 확인
free -h
로그 관리
# 로그 로테이션 설정 (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
성능 최적화 설정
# 시놀로지 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단계: 백업 및 복원
자동 백업 스크립트
# /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"
백업 스케줄 설정
# 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. 메모리 부족
# Elasticsearch 메모리 줄이기
# docker-compose.yml에서 ES_JAVA_OPTS 수정
- "ES_JAVA_OPTS=-Xms256m -Xmx512m"
# 불필요한 컨테이너 중지
docker-compose stop worker scheduler
2. 디스크 공간 부족
# 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. 네트워크 연결 문제
# 네트워크 재생성
docker network rm industrial-net
docker network create industrial-net
# 컨테이너 재시작
docker-compose restart
성능 튜닝
SSD 최적화
# SSD 수명 연장을 위한 설정
echo 'deadline' > /sys/block/sda/queue/scheduler
echo '1' > /sys/block/sda/queue/iosched/fifo_batch
네트워크 최적화
# 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는 다음과 같은 경우에 최적입니다:
- 24시간 서비스 운영이 필요한 경우
- 전력 효율성을 중시하는 경우
- 자동 백업 및 데이터 보호가 중요한 경우
- 원격 접근이 필요한 경우
- 비용 절약을 원하는 경우
480GB SSD는 이 프로젝트에 충분하며, 적절한 로그 관리와 백업 정책으로 장기간 안정적인 운영이 가능합니다.
시놀로지 NAS로 더 안정적이고 효율적인 산업 정보 시스템을 구축해보세요! 🏠🚀