설치 전 사전 준비
어떤 OS든 시작 전에 시스템을 최신 상태로 업데이트하고 필수 패키지를 설치합니다. 특히 전용 서비스 계정 생성은 보안과 권한 관리를 위해 프로덕션 환경에서 필수입니다.
Ubuntu 20.04 / 22.04 / 24.04
# 시스템 업데이트 sudo apt update && sudo apt upgrade -y # 필수 패키지 설치 sudo apt install -y \ curl wget git vim \ ca-certificates gnupg \ lsb-release apt-transport-https \ software-properties-common \ htop net-tools # (선택) 전용 서비스 계정 생성 — 프로덕션 권장 sudo useradd -m -s /bin/bash dify sudo usermod -aG sudo dify su - dify
Rocky Linux 8/9 & Oracle Linux 8/9
# 시스템 업데이트 sudo dnf update -y # 필수 패키지 설치 sudo dnf install -y \ curl wget git vim \ ca-certificates \ dnf-plugins-core \ htop net-tools # Oracle Linux 전용 — EPEL 저장소 sudo dnf install -y oracle-epel-release-el$(rpm -E %rhel) # Rocky Linux 전용 — EPEL 저장소 # sudo dnf install -y epel-release # SELinux 상태 확인 (Rocky/Oracle) sestatus
Docker 설치 — Ubuntu
Ubuntu의 기본 apt 저장소에는 구버전 Docker가 포함되어 있습니다. 반드시 Docker 공식 저장소를 추가해서 최신 버전을 설치해야 합니다. Docker 29.x 미만 버전에서는 Watchtower 등 컨테이너 관리 도구에서 API 버전 불일치 문제가 발생할 수 있습니다.
# 1. 기존 Docker 완전 제거 for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt remove -y $pkg 2>/dev/null done # 2. Docker GPG 키 및 저장소 추가 sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \ sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg echo "deb [arch=$(dpkg --print-architecture) \ signed-by=/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 3. Docker Engine 설치 sudo apt update sudo apt install -y \ docker-ce docker-ce-cli containerd.io \ docker-buildx-plugin docker-compose-plugin # 4. docker 그룹에 현재 사용자 추가 sudo usermod -aG docker $USER newgrp docker # 5. 서비스 자동 시작 sudo systemctl enable --now docker # 6. 설치 확인 (버전 확인) docker --version # Docker Engine 29.x+ docker compose version # Docker Compose 2.x+ docker run hello-world # 정상 동작 확인
Ubuntu 24.04에서 sudo snap install docker로 설치하면 구버전이 설치됩니다. snap list | grep docker로 확인 후 snap 버전이 있으면 sudo snap remove docker로 제거 후 위 방법으로 재설치하세요. snap 버전은 Docker API 버전이 낮아 호환성 문제가 발생합니다.
Docker 설치 — Rocky Linux & Oracle Linux
RHEL 계열 OS는 SELinux가 활성화되어 있어 Docker 컨테이너의 볼륨 접근에 추가 설정이 필요합니다. 이 설정을 놓치면 컨테이너가 시작하지 못하거나 파일을 읽지 못하는 문제가 발생합니다.
# 1. 기존 Docker 제거 sudo dnf remove -y docker docker-client docker-client-latest \ docker-common docker-latest docker-latest-logrotate \ docker-logrotate docker-engine 2>/dev/null || true # 2. Docker 공식 저장소 추가 sudo dnf config-manager \ --add-repo https://download.docker.com/linux/rhel/docker-ce.repo # 3. Docker 설치 sudo dnf install -y \ docker-ce docker-ce-cli containerd.io \ docker-buildx-plugin docker-compose-plugin # 4. docker 그룹 추가 및 서비스 시작 sudo usermod -aG docker $USER newgrp docker sudo systemctl enable --now docker # 5. SELinux — 컨테이너 cgroup 접근 허용 (Rocky/Oracle 필수) sudo setsebool -P container_manage_cgroup 1 # 6. SELinux — 볼륨 마운트 컨텍스트 설정 # docker-compose.yml의 볼륨에 :z 또는 :Z 옵션을 추가하거나 # 아래와 같이 SELinux를 permissive 모드로 변경 (테스트 시) # sudo setenforce 0 # 7. 방화벽 설정 sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --reload # 8. 설치 확인 docker --version docker compose version
프로덕션 환경에서는 SELinux Enforcing을 유지하고 각 볼륨 마운트에 :z(공유) 또는 :Z(전용) 레이블을 추가하는 것이 보안상 올바릅니다. 개발/테스트 환경에서는 sudo setenforce 0으로 임시 비활성화하고 안정화 후 Enforcing으로 복원하세요.
디렉토리 구조 설계 & 권한 설정
Dify 데이터를 체계적으로 관리하기 위한 디렉토리 구조를 먼저 설계합니다. 특히 volumes/ 폴더의 권한이 잘못되면 컨테이너가 파일을 읽지 못해 침묵의 오류가 발생합니다.
# 1. Dify 루트 경로 생성 sudo mkdir -p /opt/dify sudo chown -R $USER:$USER /opt/dify cd /opt/dify # 2. Dify 소스 클론 git clone https://github.com/langgenius/dify.git . # 특정 버전 고정 시 (안정성 중요한 경우) # git checkout $(git describe --tags --abbrev=0) # 3. volumes 하위 디렉토리 미리 생성 mkdir -p docker/volumes/{app/storage,db/data,redis/data,qdrant,sandbox/conf} # 4. 소유권 및 권한 설정 sudo chown -R $USER:$USER /opt/dify chmod -R 755 /opt/dify/docker/volumes chmod 700 /opt/dify/docker/volumes/db/data # PostgreSQL 보안 요구사항 # 5. .dockerignore 설정 (빌드 시 데이터 보호 필수) echo "docker/volumes" >> /opt/dify/.dockerignore echo "*.log" >> /opt/dify/.dockerignore # 6. 구조 확인 tree /opt/dify/docker/volumes/ 2>/dev/null || \ find /opt/dify/docker/volumes -type d | head -20
권장 디렉토리 구조
/opt/dify/ ├── docker/ │ ├── docker-compose.yaml ← 컨테이너 오케스트레이션 │ ├── .env ← 환경변수 (민감 정보, git 제외) │ ├── nginx/conf.d/ ← Nginx 가상호스트 설정 │ └── volumes/ ← ★ 모든 영구 데이터 (백업 필수) │ ├── app/storage/ ← 업로드 파일, 임시 파일 │ ├── db/data/ ← PostgreSQL 데이터 │ ├── redis/data/ ← Redis AOF/RDB 파일 │ ├── qdrant/ ← 벡터 임베딩 데이터 │ └── sandbox/conf/ ← Sandbox 설정 ├── .dockerignore ← volumes/ 제외 설정 └── backup/ ← 백업 스크립트 & 아카이브
① docker compose down -v — -v 플래그는 볼륨까지 삭제합니다. 컨테이너만 중지할 때는 docker compose stop 또는 docker compose down(v 없이)을 사용하세요.
② volumes 폴더 이동 상태에서 docker compose up — DB가 초기화됩니다.
③ docker system prune -a --volumes — 모든 볼륨이 삭제됩니다.
.env 환경변수 완전 설정 가이드
.env 파일은 Dify의 모든 동작을 제어합니다. 기본값 그대로 운영하면 보안 취약점이 됩니다. 특히 SECRET_KEY, DB_PASSWORD, REDIS_PASSWORD는 반드시 강력한 값으로 변경해야 합니다.
cd /opt/dify/docker cp .env.example .env # SECRET_KEY 생성 (42바이트 랜덤) openssl rand -base64 42 # DB 비밀번호 생성 openssl rand -base64 24
필수 수정 항목 — 이것만은 반드시
# ── 접속 URL (가장 중요 — 혼용 시 로그인 즉시 만료) ────────── # 도메인 사용 시: https://dify.yourdomain.com # IP 사용 시: http://192.168.1.100 # ★ 반드시 한 가지 URL만 사용하고 그 URL로만 접속 CONSOLE_API_URL=http://YOUR_SERVER_IP_OR_DOMAIN CONSOLE_WEB_URL=http://YOUR_SERVER_IP_OR_DOMAIN SERVICE_API_URL=http://YOUR_SERVER_IP_OR_DOMAIN APP_API_URL=http://YOUR_SERVER_IP_OR_DOMAIN APP_WEB_URL=http://YOUR_SERVER_IP_OR_DOMAIN FILES_URL=http://YOUR_SERVER_IP_OR_DOMAIN # ── 보안 키 (openssl rand -base64 42 결과) ─────────────────── SECRET_KEY=YOUR_GENERATED_SECRET_KEY_HERE # ── DB & Redis 비밀번호 ─────────────────────────────────────── DB_PASSWORD=YourStrongDBPassword123! REDIS_PASSWORD=YourStrongRedisPass123! # ── 벡터 DB (Qdrant 권장) ──────────────────────────────────── VECTOR_STORE=qdrant # ── 포트 변경 필요 시 (기본 80) ───────────────────────────── # EXPOSE_NGINX_PORT=8090 # EXPOSE_NGINX_SSL_PORT=8443 # ── 파일 업로드 크기 제한 ─────────────────────────────────── UPLOAD_FILE_SIZE_LIMIT=15 UPLOAD_FILE_BATCH_LIMIT=5
실제 접속 URL과 CONSOLE_WEB_URL이 다르면 토큰 도메인이 불일치하여 로그인 직후 세션이 즉시 만료됩니다. 로컬 IP(http://192.168.1.100)와 도메인(https://dify.example.com)을 혼용하면 반드시 이 문제가 발생합니다. 하나의 URL만 설정하고, 오직 그 URL로만 접속하세요.
Dify 설치 실행 & 정상 동작 확인
# 1. docker 디렉토리로 이동 cd /opt/dify/docker # 2. 이미지 다운로드 및 실행 (첫 실행 5~15분 소요) docker compose up -d # 3. 실행 상태 확인 — 모두 Up (healthy) 이어야 함 docker compose ps # 4. 전체 로그 실시간 확인 (Ctrl+C로 종료) docker compose logs -f # 5. 특정 서비스 로그만 보기 docker compose logs -f dify-api # API 오류 확인 docker compose logs -f dify-worker # 인덱싱 오류 확인 docker compose logs -f dify-web # 프론트엔드 오류 확인
정상 실행 상태 예시
NAME STATUS PORTS dify-nginx Up 0.0.0.0:80->80/tcp dify-api Up (healthy) 5001/tcp dify-web Up 3000/tcp dify-worker Up - dify-db Up (healthy) 5432/tcp dify-redis Up (healthy) 6379/tcp dify-qdrant Up 6333/tcp, 6334/tcp dify-sandbox Up (healthy) 8194/tcp
브라우저에서 설정한 URL(http://서버IP)에 접속하면 관리자 계정 설정 화면이 나타납니다. 이메일, 비밀번호, 워크스페이스 이름을 설정하면 바로 사용 가능합니다.
systemd 서비스 등록 & 방화벽 / HTTPS 설정
systemd 서비스 등록 (재부팅 자동 시작)
sudo tee /etc/systemd/system/dify.service > /dev/null << 'EOF' [Unit] Description=Dify AI Platform After=docker.service network-online.target Requires=docker.service [Service] Type=oneshot RemainAfterExit=yes WorkingDirectory=/opt/dify/docker ExecStart=/usr/bin/docker compose up -d ExecStop=/usr/bin/docker compose stop ExecReload=/usr/bin/docker compose restart TimeoutStartSec=300 TimeoutStopSec=120 [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable --now dify sudo systemctl status dify
방화벽 설정
sudo ufw allow 80/tcp comment "Dify HTTP" sudo ufw allow 443/tcp comment "Dify HTTPS" sudo ufw --force enable sudo ufw status verbose
sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --reload sudo firewall-cmd --list-all
Cloudflare Tunnel로 HTTPS 공개 (공인 IP 없는 경우)
# cloudflared 설치 (Ubuntu) curl -L --output cloudflared.deb \ https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb sudo dpkg -i cloudflared.deb # 로그인 및 터널 생성 cloudflared tunnel login cloudflared tunnel create dify # Cloudflare 대시보드에서 설정: # Zero Trust → Networks → Tunnels → 생성한 터널 선택 # Public Hostname: dify.yourdomain.com → Service: http://localhost:80 # 서비스 등록 sudo cloudflared service install sudo systemctl enable --now cloudflared
버전 업그레이드 & 마이그레이션 전략
Dify는 빠르게 업데이트됩니다. 업그레이드 전 반드시 백업하고, DB 마이그레이션이 포함된 버전은 특히 주의해야 합니다.
# 1. 업그레이드 전 백업 cd /opt/dify tar -czf /backup/dify-backup-$(date +%Y%m%d).tar.gz docker/volumes/ # 2. 최신 소스 가져오기 git fetch --tags git log --oneline -5 # 최근 변경사항 확인 git pull origin main # 3. .env 변경사항 확인 (새 환경변수 추가 여부) diff .env.example docker/.env | grep "^>" | head -20 # 4. 최신 이미지 다운로드 cd docker && docker compose pull # 5. 서비스 재시작 docker compose up -d # 6. DB 마이그레이션 확인 docker compose logs dify-api | grep -i "migration\|alembic" # 7. 정상 동작 확인 docker compose ps
다음 단계: 설치가 완료됐다면 다음 글에서 Ollama, OpenAI, Claude API 연동과 CUDA/VRAM 최적화를 진행합니다.
