콘텐츠로 이동

Dify RAG 시스템 구축 계획서

장비사양용도
맥미니 M4 PromacOS, Tailscale: 100.96.177.124게이트웨이 (OpenClaw)
메인컴i7-14700K + RTX 4070 + 96GB RAM, WSL2Dify 주력 서버
보조컴3900X + RTX 3080 + 64GB RAM, WSL2백업/장애 대응
주영나스WebDAV데이터 저장소
ps-bk-nasSSH백업 전용 나스
Ollamaglm-5.1, qwen3.5, minimax-m2.5, gemma4:31b, nomic-embed-textLLM/임베딩
  • 웹 기반 UI ✓ (Dify 기본 제공)
  • RBAC (역할 기반 접근 통제) ✓ (Dify内置)
  • 파일 업로드 ✓
  • 버전 관리 ✓ (Git-like 저장소)
  • RAG 검색 ✓
  • Dify 사용 ✓

1. Tailscale VPN 경유 접근 시 보안 설정

섹션 제목: “1. Tailscale VPN 경유 접근 시 보안 설정”
인터넷 → (포트 제한) → Tailscale VPN → 메인컴 Dify
Terminal window
# 나스/보조컴의 ACL 파일 설정
{
"acls": [
# 메인컴에서만 Dify 접근 가능
{
"src": ["tag:dify-server"],
"dst": ["*:*"]
},
# 특정 기기만 접근 허용 (게이트웨이, 메인컴, 보조컴)
{
"src": ["100.96.177.124", "100.105.122.120", "100.124.61.85"],
"dst": ["*:*"]
}
],
"ssh": [
# SSH 접근 제한
{
"src": ["group:admin"],
"dst": ["tag:server"],
"users": ["root"]
}
]
}
Terminal window
# Tailscale 인터페이스만 허용
ufw allow from 100.96.177.124/32 to any port 3000 comment "게이트웨이"
ufw allow from 100.105.122.120/32 to any port 3000 comment "메인컴 WSL"
ufw allow from 100.124.61.85/32 to any port 3000 comment "보조컴 WSL"
# 외부 접근 차단
ufw default deny incoming
ufw enable

1.3 Nginx 리버스 프록시 + Basic Auth (선택)

섹션 제목: “1.3 Nginx 리버스 프록시 + Basic Auth (선택)”
/etc/nginx/sites-available/dify
server {
listen 3000;
server_name _;
location / {
# Basic Auth (선택적)
auth_basic "Dify Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:3001;
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;
}
}

1.4 Dify 컨테이너 직접 노출 방지

섹션 제목: “1.4 Dify 컨테이너 직접 노출 방지”
# docker-compose.yml - services/api/container_ports 수정
services:
api:
ports:
- "127.0.0.1:3001:3000" # 로컬만 listening

데이터 종류저장 위치백업 주기보관 기간
PostgreSQL (메타데이터)Docker 볼륨일 1회 + 주 1회30일/1년
벡터 DB (pgvector)Docker 볼륨일 1회 + 주 1회30일/1년
업로드 파일/data/storage일 1회30일
Dify 설정 (env, yaml)Git Repo버전별무제한
Docker 이미지로컬 레지스트리업데이트 시3개 버전
/opt/backup/dify-backup.sh
#!/bin/bash
BACKUP_DIR="/mnt/nas/dify-backups"
DATE=$(date +%Y%m%d)
CONTAINER_NAME="dify-api-1"
# PostgreSQL 백업
docker exec $CONTAINER_NAME pg_dump -U postgres dify > "$BACKUP_DIR/postgres/dify_${DATE}.sql"
# 벡터 DB 백업 (pgvector)
docker exec $CONTAINER_NAME pg_dump -U postgres pgvector > "$BACKUP_DIR/vector/pgvector_${DATE}.sql"
# 파일 백업
rsync -avz /data/storage/ "$BACKUP_DIR/storage/${DATE}/"
# 나스로 복사 (주영나스 WebDAV)
curl -u user:pass -T "$BACKUP_DIR/postgres/dify_${DATE}.sql" \
"https://nas.minicity.kr/webdav/dify-backups/"
# 30일 이상된 파일 삭제
find $BACKUP_DIR -type f -mtime +30 -delete
echo "[$(date)] Backup completed" >> /var/log/dify-backup.log
Terminal window
# crontab -e
# 매일 새벽 3시 백업
0 3 * * * /opt/backup/dify-backup.sh >> /var/log/dify-backup.log 2>&1
# 매주 일요일 전체 백업
0 4 * * 0 /opt/backup/dify-full-backup.sh >> /var/log/dify-full-backup.log 2>&1

3. 장애 대응 (메인컴 다운 시 복구)

섹션 제목: “3. 장애 대응 (메인컴 다운 시 복구)”
  • RTO (복구 시간 목표): 4시간 이내
  • RPO (복구 지점 목표): 24시간 이전 데이터
┌─────────────────┐ ┌─────────────────┐
│ 메인컴 │ │ 보조컴 │
│ (Dify 주력) │────▶│ (Dify 대기) │
│ 14700K+4070 │ │ 3900X+3080 │
└─────────────────┘ └─────────────────┘
│ │
▼ ▼
[데이터 동기화] [자동 페일오버]

3.3.1 실시간 동기화 ( GlusterFS 또는 rsync)

섹션 제목: “3.3.1 실시간 동기화 ( GlusterFS 또는 rsync)”
Terminal window
# 보조컴에서 메인컴 데이터 동기화
rsync -avz --delete \
--exclude='*.log' \
--exclude='.cache' \
user@100.105.122.120:/data/dify/ \
/data/dify-standby/
/opt/failover/dify-failover.sh
#!/bin/bash
MAIN_HOST="100.105.122.120"
STANDBY_HOST="100.124.61.85"
CHECK_INTERVAL=60
while true; do
# 메인컴 health check
if ! curl -sf http://$MAIN_HOST:3000/health > /dev/null 2>&1; then
echo "[$(date)] 메인컴 연결 실패 - 페일오버 시작"
# Dify 서비스 중단 (메인컴)
ssh user@$MAIN_HOST "docker-compose -f /opt/dify/docker-compose.yml down"
# 보조컴에서 Dify 시작
ssh user@$STANDBY_HOST "cd /opt/dify && docker-compose up -d"
# DNS 또는 IP 변경 알림
echo "Dify 서비스가 보조컴으로 이동되었습니다." >> /var/log/failover.log
fi
sleep $CHECK_INTERVAL
done
  1. 메인컴 상태 확인 (ping, SSH)
  2. 장애 원인 분석 (로그 확인)
  3. 데이터 동기화 상태 확인
  4. 보조컴에서 Dify 정상 동작 확인
  5. 사용자에게 새 접근 주소 안내

Dify는 기본적으로 다음과 같은 역할을 제공:

  • ** Owner** (소유자): 전체 관리 권한
  • ** Admin** (관리자): 워크플로우/앱 관리
  • ** Editor** (편집자): 앱 생성/편집
  • ** Viewer** (뷰어): 읽기 전용
# Dify의 API를 통한 사용자 관리 예시
# 필요 시 Keycloak 연동 고려
역할권한范围사용 상황
Admin전체 관리시스템 관리자
Editor생성/편집/실행개발자
Viewer읽기/실행최종 사용자
API-UserAPI만 사용외부 연동

Terminal window
# Dify API 키 생성 (관리자 페이지에서)
# 웹 UI → 설정 → API 키
# 사용 예시
curl -X POST 'http://100.105.122.120:3000/v1/chat-messages' \
-H 'Authorization: Bearer sk-xxxxx' \
-H 'Content-Type: application/json' \
-d '{"query": "안녕하세요", "response_mode": "blocking"}'
  1. 환경 변수로 관리

    Terminal window
    # .env 파일
    DIFY_API_KEY=sk-xxxxxxxxxxxxx
    DIFY_API_URL=http://localhost:3000
  2. 나스 분리 저장

    • API 키는 나스에 별도 파일로 암호화 저장
    • 서버에서는 환경 변수만 참조
  3. 키 순환 주기

    • 90일마다 키 재발급
    • 사용하지 않는 키는 즉시 폐기

Terminal window
# 전체 컨테이너 로그
docker-compose -f /opt/dify/docker-compose.yml logs -f
# 특정 서비스만
docker logs -f dify-api-1
docker logs -f dify-worker-1
# docker-compose.yml에 Loki 추가
services:
loki:
image: grafana/loki:latest
ports:
- "3100:3100"
volumes:
- ./loki-config.yml:/etc/loki/config.yml
/opt/monitor/dify-alert.sh
LOG_FILE="/var/log/dify.log"
# 오류 감지 시 알림
tail -f $LOG_FILE | while read line; do
if echo "$line" | grep -q "ERROR\|CRITICAL"; then
# 텔레그램 알림
curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
-d "chat_id=${CHAT_ID}&text=[Dify 오류] $line"
fi
done
도구용도자원
Prometheus + Grafana메트릭 수집/시각화
Loki로그 수집
AlertManager알림

  1. 테스트 환경 먼저: 보조컴에서 먼저 테스트
  2. 백업 필수: 업데이트 전 항상 전체 백업
  3. 마이너 업데이트 우선: 0.3.x → 0.3.y 순서로
  4. 릴리스 노트 확인: Breaking Changes 체크
Terminal window
# 1. 백업
/opt/backup/dify-backup.sh
# 2. 현재 버전 확인
cd /opt/dify
docker-compose version
# 3. 이미지 다운로드
docker-compose pull
# 4. 컨테이너 재시작
docker-compose up -d
# 5. 마이그레이션 확인
docker logs dify-api-1 | grep -i migration
# 6. 동작 확인
curl http://localhost:3000/health
Terminal window
# 이전 버전으로 롤백
docker-compose -f /opt/dify/docker-compose.yml down
# docker-compose.yml에서 이미지 태그 변경
# 예: image: langgenius/dify:0.14.0 → 0.13.0
docker-compose up -d
버전업데이트 날짜비고
0.15.0-현재 사용 중
0.14.02026-02-15이전 버전
0.13.02026-01-10롤백용

8. 나스 연결 안정성 (WebDAV vs SMB/CIFS)

섹션 제목: “8. 나스 연결 안정성 (WebDAV vs SMB/CIFS)”
방식장점단점권장 상황
WebDAVHTTP/HTTPS만으로 접근, 방화벽 단순화성능이 SMB보다 느림외부 접근 (주영나스)
SMB/CIFS성능 우수, Windows 호환성Linux에서 추가 설정 필요내부 네트워크
Terminal window
# WebDAV 마운트
sudo mount -t davfs https://nas.minicity.kr/webdav /mnt/nas-dav \
-o user=username,passwd=/opt/.davfs-passwd
# fstab 등록 (부팅 시 자동 마운트)
echo "https://nas.minicity.kr/webdav /mnt/nas-dav davfs user,noauto 0 0" | sudo tee -a /etc/fstab

8.2.2 로컬 나스 (SMB) - 데이터 저장용

섹션 제목: “8.2.2 로컬 나스 (SMB) - 데이터 저장용”
Terminal window
# SMB 마운트 (WSL에서)
sudo mount -t cifs //192.168.x.x/share /mnt/nas-smb \
-o username=user,password=pass,vers=3.0
  1. ** mounts 옵션**: soft,timeo=30,retry=3 (연결 실패 시 자동 재시도)
  2. ** cron으로 주기적 마운트 확인**: 연결 끊기면 자동 재연결
  3. ** 로컬 캐시 활용**:频繁 접근 파일은 로컬에 캐시

시나리오대응 방법소요 시간
메인컴 하드웨어 장애보조컴으로 페일오버30분~4시간
데이터 손실 (24시간 이내)나스에서 최신 백업 복원1~2시간
전체 데이터 손실원격 백업 (ps-bk-nas)에서 복원4~8시간
나스 장애ps-bk-nas에서 복원2~4시간
[ ] 하드웨어/서버 준비
[ ] OS 설치 및 기본 설정
[ ] Docker, Docker-compose 설치
[ ] 네트워크 설정 (Tailscale, 방화벽)
[ ] Dify 설치 (docker-compose)
[ ] 백업 데이터 복원
[ ] 서비스 정상 동작 확인
[ ] 사용자 접근 테스트
[ ] Dify 컨테이너 정상 동작 확인
[ ] PostgreSQL 백업 복원
[ ] 벡터 DB 백업 복원
[ ] 업로드 파일 복원
[ ] 인덱스 재구성 (필요 시)
[ ] 데이터 무결성 확인
  • 분기별 (3개월) 1회 복구 훈련 실시
  • 문서화된 절차대로 복구 시간 측정
  • 개선점 발견 시 문서 업데이트

장비전원 소비 (W)일 사용 시간일 전기비 (₩)월 전기비 (₩)
메인컴250W (전체)24시간~1,500~45,000
보조컴150W (전체)24시간 (대기)~900~27,000
맥미니30W24시간~180~5,400
나스 (주영)기존--(별도)
합계~2,580

💡 전기비 계산: 150W × 24h × 30일 = 108kWh × ₩140/kWh

항목비용주기
도메인 (Dify.myhome.local)무료 (내부)-
SSL 인증서 (Let’s Encrypt)무료90일
백업 스토리지 (나스)기존 요금-
도메인/DNS (외부 공개 시)~₩15,000/년yearly
합계~₩15,000/년
  • 월간: ~₩77,400 (전기)
  • 연간: ~₩77,400 × 12 + ₩15,000 = ~₩943,800

  • 메인컴에 Docker, Docker-compose 설치
  • Dify docker-compose.yml 다운로드 및 설정
  • Tailscale 설치 및 연결
  • 방화벽 설정 (ufw)
  • 나스 WebDAV 마운트
  • 백업 스크립트 작성
  • Cron 설정 및 테스트
  • 복원 테스트
  • 보조컴에 동일 환경 구축
  • 데이터 동기화 설정
  • 페일오버 스크립트 작성 및 테스트
  • 로그 시스템 구축
  • 알림 설정 (텔레그램/이메일)
  • Grafana 대시보드 구성
  • 운영 매뉴얼 작성
  • 복구 절차 문서화
  • 사용자 가이드 작성


작성일: 2026-04-20 최종 업데이트: -