13년차의 서버실

서버, 인프라, 홈랩 기술 블로그

[카테고리:] NAS

  • [Nas] Cloudflare Tunnel 연결 끊김? 5가지 해결법과 최적화 팁

    [Nas] Cloudflare Tunnel 연결 끊김? 5가지 해결법과 최적화 팁

    안녕하세요, 13년차 인프라 엔지니어 ’13년차의 서버실’입니다. 집에서 홈랩(Homelab)을 운영하며 다양한 서비스를 돌리는데, 외부에서 접속이 안 돼서 답답했던 경험, 다들 있으시죠?

    저도 예전엔 공유기 포트포워딩(Port Forwarding)이나 VPN(Virtual Private Network) 서버 구축으로 해결했어요. 근데 보안적으로나 관리적으로나 신경 쓸 게 한두 가지가 아니더라고요. 특히 포트포워딩은 외부 공격에 노출될 위험이 있어서 항상 불안했습니다.

    이런 고민을 한 방에 날려준 게 바로 Cloudflare Tunnel(클라우드플레어 터널)입니다. 제로 트러스트(Zero Trust) 개념을 기반으로 안전하고 쉽게 내부망 자원에 접근할 수 있거든요. 마치 클라우드플레어 네트워크가 우리 서버의 ‘문지기’ 역할을 해주면서, 외부에서 직접 들어오는 길을 완전히 막아버리는 셈이죠.

    근데 이게 가끔 말썽을 부릴 때가 있어요. Cloudflare Tunnel이 연결이 끊기거나 아예 접속이 안 되는 경우 말이죠. 저도 처음엔 ‘뭐가 문제지?’ 싶어서 삽질을 꽤 했습니다. ㅎㅎ 오늘은 제가 직접 겪었던 Cloudflare Tunnel 연결 문제를 해결하는 5단계와 더 안정적으로 운영할 수 있는 최적화 팁까지 풀어보겠습니다. 비슷한 경험을 하고 계시다면 꼭 도움이 될 거예요!

    Cloudflare Tunnel을 이용한 안전한 원격 접속 환경의 전체 구성도입니다. 클라이언트, Cloudflare 엣지, Tunnel, 그리고 내부 서버 간의 연결 흐름을 한눈에 볼 수 있습니다.

    💡 Cloudflare Tunnel이란? (쉽게 풀어보기)

    Cloudflare Tunnel은 내부 네트워크의 자원(웹 서버, SSH, RDP 등)을 인터넷에 직접 노출하지 않고, Cloudflare의 글로벌 엣지(Edge) 네트워크를 통해 안전하게 접근할 수 있도록 해주는 서비스입니다. 기존의 포트포워딩이나 VPN과 다르게, 내부망으로 들어오는 인바운드(Inbound) 포트를 열 필요가 없다는 게 가장 큰 장점이에요.

    우리 서버에 cloudflared라는 경량 데몬(daemon)을 설치하면, 이 데몬이 Cloudflare 엣지 네트워크와 아웃바운드(Outbound) 연결을 맺어요. 클라이언트가 특정 도메인으로 접속하면, Cloudflare 엣지가 요청을 받아 cloudflared가 만들어놓은 터널을 통해 내부 자원으로 안전하게 전달하는 방식입니다. 모든 트래픽은 암호화되어 흐르기 때문에 보안성도 정말 높습니다. 매력적이죠?

    ✅ Cloudflare Tunnel 연결 문제 해결 5단계

    자, 이제 Cloudflare Tunnel 오류를 해결하고 더 안정적으로 운영할 수 있는 실전 가이드를 알아볼게요. 제가 직접 해보면서 터득한 5단계를 따라가시면 대부분의 문제를 해결할 수 있습니다.

    1. cloudflared 서비스 상태 확인

    가장 먼저 확인해야 할 건 역시 cloudflared 데몬이 잘 실행되고 있는지입니다. 이게 멈춰있으면 당연히 Cloudflare Tunnel 연결이 안 되겠죠? 서버에 접속해서 다음 명령어로 상태를 확인해 보세요.

    sudo systemctl status cloudflared

    만약 inactive (dead) 상태라면, 서비스를 재시작합니다.

    sudo systemctl start cloudflared
    sudo systemctl enable cloudflared # 재부팅 시 자동 시작 설정

    서비스가 active (running)상태인데도 문제가 있다면 로그를 확인해야 해요. journalctl 명령어로 최근 로그를 보면 단서를 찾을 수 있습니다.

    sudo journalctl -u cloudflared.service --since "5 minutes ago"

    에러 메시지나 경고(Warning)가 보인다면, 그 내용을 바탕으로 구글링을 시작할 수 있어요.

    2. Tunnel 설정 파일(config.yml) 점검

    다음은 설정 파일이 정확한지 확인해야 합니다. /etc/cloudflared/config.yml (혹은 다른 경로)의 설정 파일은 YAML(YAML Ain’t Markup Language) 문법으로 작성되는데, 스페이스나 탭, 오타 하나에도 오류가 생기기 쉬워요. 특히 hostname이나 service 경로에 오타가 없는지 꼼꼼히 확인해 보세요.

    Cloudflare에서 제공하는 유틸리티로 설정 파일의 유효성을 검사할 수 있습니다.

    cloudflared tunnel validate --config /etc/cloudflared/config.yml

    설정 파일에 문제가 있으면 어떤 부분이 잘못되었는지 알려줍니다. 저는 자주 service URL을 http://localhost:80 대신 http://localhost:80/ 처럼 슬래시를 빼먹거나 더 넣는 실수를 했어요. 아래는 일반적인 config.yml 예시입니다.

    tunnel: <YOUR_TUNNEL_UUID>
    credentials-file: /root/.cloudflared/<YOUR_TUNNEL_UUID>.json
    
    ingress:
      - hostname: myapp.example.com
        service: http://localhost:8080
      - hostname: ssh.example.com
        service: ssh://localhost:22
        # Cloudflare Access를 통한 SSH 접근 시 필요
        originRequest:
          noTLSVerify: true # 개발 환경에서만 사용 권장
      - service: http_status:404 # 일치하는 규칙이 없을 경우 404 반환
    

    3. DNS 레코드 확인

    Cloudflare Tunnel은 DNS(Domain Name System) 레코드와 연동되어 작동합니다. 설정한 도메인이 터널과 제대로 연결되어 있는지 확인해 보세요. Cloudflare 대시보드(Dashboard)에서 해당 도메인의 DNS 설정으로 이동해 CNAME(Canonical Name) 레코드를 확인합니다.

    보통 Cloudflare Tunnel을 만들고 도메인을 연결하면 자동으로 CNAME 레코드가 생성되는데, 가끔 이게 삭제되거나 잘못 변경되곤 해요. CNAME 레코드의 Name은 접속할 도메인(예: myapp), Target은 <YOUR_TUNNEL_UUID>.cfargotunnel.com 형태여야 합니다.

    # cloudflared 명령어로 DNS 라우팅 상태를 확인해볼 수도 있습니다.
    cloudflared tunnel route dns myapp.example.com <YOUR_TUNNEL_NAME_OR_UUID>
    Cloudflare 대시보드에서 Tunnel의 DNS CNAME 레코드 설정 화면

    Cloudflare 대시보드에서 Tunnel에 연결된 DNS CNAME 레코드를 확인하는 화면입니다. 올바른 호스트네임과 Tunnel ID가 지정되었는지 점검하는 데 필수적인 부분이죠.

    4. Cloudflare 엣지 네트워크 연결 확인

    간혹 Cloudflare 엣지 네트워크 자체에 문제가 생기거나, 우리 서버와 엣지 간의 네트워크 경로에 이상이 생길 수 있어요. 드물지만 이런 경우도 있더라고요.

    • cloudflared tunnel health 확인: 터널의 전반적인 상태를 한눈에 볼 수 있습니다.
    cloudflared tunnel health <YOUR_TUNNEL_NAME_OR_UUID>
    • 네트워크 연결 테스트: 서버에서 Cloudflare의 공용 DNS 서버(예: 1.1.1.1)로 ping이나 traceroute를 시도해서 네트워크 상태를 확인해 보세요.
    ping 1.1.1.1
    traceroute 1.1.1.1
    • 방화벽(Firewall) 확인: 서버의 방화벽(ufw, firewalld 등)에서 cloudflared의 아웃바운드 연결을 막고 있지는 않은지 확인합니다. Cloudflare 엣지 네트워크로의 443/TCP 아웃바운드 트래픽은 꼭 허용되어야 합니다.

    5. cloudflared 재설치 또는 버전 업그레이드

    위 단계를 다 해봐도 Cloudflare Tunnel 연결 문제가 해결되지 않는다면, cloudflared 자체에 문제가 있거나 버전이 너무 오래되었을 가능성이 있어요. 저도 예전에 구버전 때문에 꽤나 애먹었거든요. 최신 버전으로 업데이트하거나 재설치해보세요.

    • 업데이트:
    cloudflared update
    • 재설치 (Debian/Ubuntu 기준):
    sudo apt remove cloudflared
    wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64
    sudo mv cloudflared-linux-amd64 /usr/local/bin/cloudflared
    sudo chmod +x /usr/local/bin/cloudflared
    sudo cloudflared service install # 서비스 재설치
    sudo systemctl start cloudflared

    업데이트 후엔 항상 서비스를 재시작하는 것 잊지 마세요! sudo systemctl restart cloudflared

    ⚠️ 제가 겪었던 흔한 삽질들 (Troubleshooting Tips)

    13년차 엔지니어라고 다 아는 건 아니더라고요. Cloudflare Tunnel 운영하면서 다양한 삽질을 겪었는데, 몇 가지 공유해 드릴게요.

    • 높은 메모리(Memory)/CPU 사용량: 가끔 cloudflared 프로세스가 과도하게 리소스를 사용할 때가 있어요. top이나 htop 명령어로 확인하고, 그렇다면 터널 설정을 점검하거나 너무 많은 서비스를 하나의 터널에 연결한 건 아닌지 확인해 보세요. 용도에 따라 터널을 분리하는 것도 좋은 방법입니다.
    • Cloudflare WAF(Web Application Firewall) 또는 Rate Limiting: Cloudflare에서 설정한 보안 규칙이 의도치 않게 여러분의 트래픽을 막을 수 있어요. Cloudflare 대시보드의 ‘Security(보안)’ 섹션에서 ‘Events(이벤트)’ 로그를 확인해 보세요.
    • Origin(오리진) 서버의 문제: 터널 자체는 잘 작동하는데, 뒤에 있는 실제 서비스(웹 서버 등)가 죽어있을 수도 있어요. http://localhost:8080 같은 로컬 URL로 직접 접속해서 서비스가 살아있는지 확인해 보세요.
    • 로그 레벨(Log Level) 조정: 문제 발생했을 때 config.yml 파일에 loglevel: debug를 추가하면 더 자세한 로그를 얻을 수 있어요. 디버그 로그는 정말 신의 한 수입니다.
    Cloudflare Tunnel의 연결 상태 및 트래픽 현황을 보여주는 대시보드 시각화 차트

    Cloudflare 대시보드에서 Tunnel의 실시간 연결 상태와 트래픽 패턴을 모니터링하는 차트입니다. 연결이 끊어졌을 때 어떤 지표가 변하는지 확인할 수 있죠.

    🚀 Cloudflare Tunnel 최적화 팁

    연결 끊김 문제를 해결했다면, 이제 더 안정적이고 효율적으로 터널을 운영하기 위한 최적화 팁들을 알아볼까요?

    1. 로드 밸런싱(Load Balancing) 활용

    하나의 Origin 서버에 트래픽이 몰리는 것을 피하기 위해 여러 개의 Origin을 설정하고 로드 밸런싱을 활용할 수 있습니다. 특히 홈랩에서 Docker Swarm이나 Kubernetes(쿠버네티스) 환경에서 여러 인스턴스를 띄워두고 연결할 때 정말 유용하더라고요.

    ingress:
      - hostname: myapp.example.com
        service: http://localhost:8080
        originRequest:
          originMaxConcurrentConnections: 200 # 동시 연결 수 제한
      - hostname: myapp.example.com
        service: http://192.168.1.100:8080 # 다른 서버의 동일 서비스
      - service: http_status:404
    

    2. 제로 트러스트 액세스 정책(Zero Trust Access Policies) 강화

    Cloudflare Access(클라우드플레어 액세스)를 활용해서 사용자 인증 및 접근 정책을 강화해 보세요. 이메일, SSO(Single Sign-On) 연동 등 다양한 방법을 지원하기 때문에 보안을 한층 더 높일 수 있습니다. ‘누구도 믿지 않는다’는 제로 트러스트 원칙을 따르는 거죠.

    3. 헬스 체크(Health Checks) 설정

    config.yml 파일에 health_check를 설정하면 Origin 서버의 상태를 주기적으로 체크할 수 있어요. 서버가 죽었을 때 자동으로 다른 Origin으로 트래픽을 돌리거나 알림을 받을 수 있어서 서비스 안정성에 정말 큰 도움이 됩니다.

    ingress:
      - hostname: myapp.example.com
        service: http://localhost:8080
        originRequest:
          httpHostHeader: myapp.example.com
          noTLSVerify: true # 개발 환경에서만 사용
          connectTimeout: 5s
          tcpKeepAlive: 30s
          retries: 3
    

    4. 지속적인 연결(Persistent Connection) 유지

    config.yml 파일 내 originRequest 섹션에서 tcpKeepAlive 같은 옵션을 활성화하면 터널 연결을 더 오래 유지할 수 있어요. 짧은 시간 동안의 네트워크 불안정으로 인한 Cloudflare Tunnel 연결 끊김을 줄일 수 있습니다.

    🎉 검증 및 결과 확인

    이 모든 단계를 거치고 나면, 드디어 Cloudflare Tunnel이 안정적으로 작동하는 걸 볼 수 있을 겁니다! 브라우저에서 설정한 도메인으로 접속해보고, cloudflared 로그를 다시 확인해 보세요. 에러 없이 깔끔하게 연결되는 걸 보면 정말 뿌듯해요.

    특히 Cloudflare 대시보드의 ‘Analytics(분석)’ 섹션에서 트래픽이 정상적으로 흐르는 걸 확인하면, ‘아, 이제 좀 안심이다!’ 싶어요. 연결 끊김 없이 안정적으로 서비스가 제공되는 모습을 보면 그동안의 삽질이 다 보상받는 기분이죠. 드디어 됐다!

    Cloudflare Tunnel 최적화 팁을 시각적으로 요약한 인포그래픽

    Cloudflare Tunnel 최적화 팁들을 한눈에 보기 쉽게 정리한 인포그래픽입니다. 로드 밸런싱, Zero Trust Access, Health Checks 등 핵심적인 개선 방안들을 담고 있습니다.

    마무리하며: 삽질은 성장의 밑거름!

    Cloudflare Tunnel은 정말 강력하고 편리한 도구지만, 가끔씩 예상 밖의 문제로 우리를 당황하게 만들 때가 있어요. 그래도 대부분의 문제는 오늘 제가 알려드린 5단계 점검과 최적화 팁으로 충분히 해결할 수 있을 거예요. 저도 처음엔 헷갈렸는데, 몇 번 겪어보니 ‘아, 이거구나!’ 싶더라고요.

    인프라 엔지니어의 삶이란 게 결국 삽질의 연속이잖아요? ㅎㅎ 그 삽질을 통해 얻은 경험이 다른 분들께 조금이라도 도움이 되었으면 좋겠어요. 항상 새로운 기술을 실험하고, 문제를 해결하는 과정에서 성장하는 것 같습니다.

    다음 글에서는 Cloudflare Tunnel과 Docker를 연동해서 서비스 배포를 자동화하는 방법에 대해 좀 더 깊이 다뤄볼 예정이니 기대해주세요! 그때까지 모두 안정적인 서버실 운영하시길 바랍니다!

  • [Nas] Nextcloud S3 스토리지 연동: 성능, 비용 효율성 심층 분석

    [Nas] Nextcloud S3 스토리지 연동: 성능, 비용 효율성 심층 분석

    안녕하세요, 13년차의 서버실 주인장입니다. 오늘은 제가 홈랩에서 정말 유용하게 쓰고 있는 Nextcloud와 S3 스토리지 연동에 대한 이야기를 해보려고 합니다. 사실 처음 Nextcloud를 구축했을 때, 저장 공간 확장에 대한 고민이 많았거든요. 로컬 디스크는 언젠가 한계에 부딪히기 마련이고, 안정성과 확장성을 모두 잡으려면 뭔가 다른 방법이 필요했습니다. 혹시 여러분도 이런 고민 해보신 적 있으신가요?

    그래서 제가 직접 여러 방법을 탐색하고 삽질해본 끝에, Nextcloud S3 스토리지 연동이 가장 합리적인 해결책이라는 결론에 도달했습니다. 특히 MinIO 같은 S3 호환 오브젝트 스토리지를 활용하면, 비용 효율적으로 대용량 스토리지를 구축하면서도 성능까지 잡을 수 있다는 걸 깨달았죠. 오늘은 그 경험을 바탕으로 Nextcloud와 S3 스토리지 연동의 A부터 Z까지, 그리고 성능과 비용 효율성을 어떻게 분석하고 최적화할 수 있는지 심층적으로 파헤쳐 보겠습니다.

    Nextcloud와 S3 오브젝트 스토리지 연동의 전체 아키텍처 개요

    Nextcloud S3 스토리지 연동의 전체 아키텍처 개요입니다.

    Nextcloud와 S3 오브젝트 스토리지, 왜 중요할까요?

    먼저, 핵심 개념부터 짚고 넘어가겠습니다. Nextcloud는 오픈 소스 기반의 개인 클라우드 솔루션입니다. Dropbox나 Google Drive처럼 파일을 저장하고 공유하며, 캘린더, 연락처, 문서 편집 등 다양한 기능을 웹 인터페이스를 통해 제공하죠. 제가 이걸 홈랩에 구축해서 가족 사진이나 문서 백업용으로 아주 잘 쓰고 있거든요.

    그럼 S3 오브젝트 스토리지(Object Storage)는 뭘까요? 쉽게 말해, 파일을 ‘오브젝트’라는 단위로 저장하는 방식입니다. 기존의 파일 시스템처럼 계층 구조가 아니라, 고유한 키(Key)를 통해 데이터를 관리하는데요. Amazon Web Services(AWS)의 S3가 가장 대표적인 서비스인데, 저는 홈랩 환경에서 S3 API를 지원하는 MinIO를 주로 사용합니다. MinIO는 온프레미스 환경이나 클라우드에서 직접 S3 호환 오브젝트 스토리지를 구축할 수 있게 해주는 솔루션이거든요. 마치 AWS S3를 내 서버에 직접 설치해서 쓰는 느낌이라고 생각하시면 됩니다.

    ✅ Nextcloud + S3 연동의 장점

    • 무한한 확장성(Scalability): S3는 이론적으로 무한대에 가까운 저장 공간을 제공합니다. 디스크를 추가하거나 서버를 교체할 필요 없이 필요한 만큼 용량을 늘릴 수 있어요.
    • 높은 안정성(Durability): 데이터가 여러 노드에 분산 저장되기 때문에, 특정 디스크나 서버에 문제가 생겨도 데이터 손실 위험이 적습니다. MinIO도 분산 모드로 구성하면 이 장점을 누릴 수 있죠.
    • 비용 효율성(Cost-Effectiveness): 사용한 만큼만 비용을 지불하는 종량제 모델이라, 초기 투자 비용 부담이 적습니다. 특히 MinIO는 오픈 소스라 소프트웨어 비용이 들지 않고요.
    • 성능 최적화: S3는 대규모 분산 환경에 최적화되어 있어, 적절히 구성하면 빠른 데이터 접근 속도를 기대할 수 있습니다.

    MinIO를 활용한 Nextcloud S3 스토리지 연동 실전 가이드

    자, 이제 실제로 Nextcloud에 S3 스토리지를 연동하는 방법을 알아보겠습니다. 저는 주로 Docker Compose를 사용해서 MinIO를 구축하는데요, 이게 제일 빠르고 간편하더라고요.

    1단계: MinIO 서버 구축 (Docker Compose)

    먼저 MinIO 서버를 준비해야 합니다. 저는 MinIO 공식 문서를 참고해서 Docker Compose 파일을 만들었어요. 아래처럼 docker-compose.yaml 파일을 생성해줍니다.

    
    version: '3.8'
    services:
      minio:
        image: quay.io/minio/minio:latest
        ports:
          - "9000:9000"
          - "9001:9001"
        environment:
          MINIO_ROOT_USER: minioadmin # 관리자 사용자 이름 (꼭 바꿔주세요!)
          MINIO_ROOT_PASSWORD: minioadminpassword # 관리자 비밀번호 (꼭 바꿔주세요!)
          MINIO_SERVER_URL: "http://minio.yourdomain.com:9000" # MinIO 서버 URL
        command: server /data --console-address ":9001"
        volumes:
          - ./minio_data:/data # MinIO 데이터가 저장될 경로
        healthcheck:
          test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
          interval: 30s
          timeout: 20s
          retries: 3
    

    위 파일에서 MINIO_ROOT_USER와 MINIO_ROOT_PASSWORD는 반드시 강력한 비밀번호로 변경해주세요! 그리고 ./minio_data 경로는 실제 MinIO 데이터가 저장될 디렉터리입니다. 저는 보통 /mnt/minio_data 같은 경로로 지정해서 영구 저장소를 사용하곤 합니다. 파일 생성 후, 아래 명령어로 MinIO를 실행합니다.

    
    docker compose up -d
    

    MinIO가 실행되면 http://your_server_ip:9001로 접속해서 웹 콘솔에 로그인할 수 있습니다. 여기서 버킷(Bucket)을 생성해줘야 하는데요, Nextcloud에서 사용할 버킷을 미리 만들어두면 편리합니다. 예를 들어 nextcloud-bucket이라는 이름으로 생성해볼게요.

    2단계: Nextcloud S3 External Storage 설정

    이제 Nextcloud 관리자 페이지에서 외부 스토리지를 연결할 차례입니다. Nextcloud에 로그인한 후, 관리자 설정(Settings) > 관리(Administration) > 외부 저장소(External storages) 메뉴로 이동합니다. 여기서 새로운 저장소를 추가합니다.

    1. 폴더 이름(Folder name): Nextcloud 내에서 보일 폴더 이름입니다. 예를 들어 S3 Storage라고 입력합니다.
    2. 외부 저장소(External storage): 드롭다운에서 Amazon S3 compatible을 선택합니다.
    3. 인증(Authentication): Access key & secret key를 선택합니다.
    4. 버킷(Bucket): MinIO에서 생성한 버킷 이름을 입력합니다 (예: nextcloud-bucket).
    5. 호스트(Hostname): MinIO 서버의 IP 주소 또는 도메인과 포트 번호를 입력합니다 (예: your_minio_server_ip:9000).
    6. 포트(Port): MinIO 서비스 포트 (예: 9000).
    7. SSL/TLS 사용(Enable SSL/TLS): MinIO에 SSL/TLS를 적용했다면 체크합니다. 홈랩에서는 처음에는 HTTP로 시작하고, 나중에 Traefik 같은 리버스 프록시를 통해 SSL을 적용하는 경우가 많습니다.
    8. 버킷 URL(Bucket URL): MinIO 콘솔에서 확인할 수 있는 버킷의 URL을 입력합니다. (예: http://your_minio_server_ip:9000/nextcloud-bucket)
    9. 액세스 키(Access key): MinIO 설정 시 사용했던 MINIO_ROOT_USER (또는 새로 생성한 사용자)
    10. 시크릿 키(Secret key): MinIO 설정 시 사용했던 MINIO_ROOT_PASSWORD (또는 새로 생성한 사용자 비밀번호)
    Nextcloud 외부 저장소 설정 화면: MinIO 정보 입력 예시

    Nextcloud 외부 저장소 설정 화면입니다. MinIO 정보를 정확히 입력하는 것이 중요해요.

    모든 정보를 입력하고 나면, 초록색 체크 표시가 뜨면서 정상적으로 연결되었음을 확인할 수 있을 겁니다. 만약 빨간색 X 표시가 뜬다면, 뭔가 잘못된 거겠죠? ⚠️

    ⚠️ 삽질 경험: “Failed to connect to S3” 에러

    제가 이 과정에서 가장 많이 겪었던 삽질 중 하나가 바로 “Failed to connect to S3” 에러였습니다. 처음엔 MinIO 서버가 문제인가 싶어서 MinIO 로그만 계속 들여다봤거든요. 근데 알고 보니 Nextcloud 서버에서 MinIO 서버로의 네트워크 연결 문제인 경우가 많더라고요.

    트러블슈팅 팁:

    1. 방화벽 확인: Nextcloud 서버에서 MinIO 서버의 9000번 포트(API)와 9001번 포트(콘솔)로의 아웃바운드 연결이 허용되어 있는지 확인하세요. MinIO 서버에서도 인바운드 연결이 허용되어야 합니다.
    2. 네트워크 연결 테스트: Nextcloud 서버에서 curl http://your_minio_server_ip:9000 명령어를 실행해서 MinIO API에 접근 가능한지 테스트해보세요.
    3. SSL/TLS 설정 확인: MinIO에 SSL/TLS를 적용했는데 Nextcloud 설정에서 “Enable SSL/TLS”를 체크하지 않았거나, 그 반대의 경우에도 연결 오류가 발생합니다. 특히 홈랩에서 자가 서명(self-signed) 인증서를 사용하는 경우, Nextcloud가 해당 인증서를 신뢰하지 못해서 문제가 생길 수 있어요. 이럴 때는 Nextcloud 서버에 MinIO의 CA 인증서를 등록해주거나, 테스트 목적으로는 “SSL/TLS 사용”을 잠시 끄고 시도해볼 수도 있습니다 (운영 환경에서는 절대 권장하지 않습니다!).
    4. 액세스 키/시크릿 키 오타: 너무 기본적인 실수지만, 의외로 많이 하는 실수입니다. 대소문자 구분도 중요하니 꼼꼼하게 확인해주세요.
    5. 버킷 이름 확인: MinIO에 생성한 버킷 이름과 Nextcloud에 입력한 버킷 이름이 정확히 일치하는지 확인해야 합니다.

    이런 문제들을 하나씩 해결해가면서 드디어 초록색 체크 표시를 봤을 때의 그 쾌감이란! 🎉 여러분도 꼭 성공하시길 바랍니다.

    Nextcloud S3 연동 결과 검증 및 성능 분석

    연동이 완료되었다면, 이제 Nextcloud 웹 인터페이스에서 S3 Storage라는 이름의 폴더가 보일 겁니다. 여기에 파일을 업로드해보세요. 파일이 MinIO 버킷으로 정상적으로 업로드되는지 MinIO 콘솔에서도 확인해볼 수 있습니다.

    Nextcloud에 마운트된 S3 스토리지 폴더와 업로드된 파일 목록

    Nextcloud에 성공적으로 마운트된 S3 스토리지와 업로드된 파일들입니다.

    성능 분석: 기대와 현실

    저는 Nextcloud를 S3에 연동한 후, 로컬 스토리지와 비교해서 파일 업로드/다운로드 성능을 직접 테스트해봤습니다. 결론부터 말씀드리면, “대용량 파일”이나 “다수의 작은 파일” 처리에서 S3 연동의 이점을 명확히 느낄 수 있었습니다.

    • 대용량 파일(Large Files): 단일 대용량 파일(예: 1GB 이상)의 경우, MinIO가 백엔드 디스크의 성능을 충분히 활용하면서도 Nextcloud 서버의 I/O 부하를 줄여주기 때문에, 체감 성능이 로컬 디스크와 크게 다르지 않거나 오히려 더 안정적인 모습을 보여주기도 했습니다. 특히 MinIO를 분산 환경으로 구성하면 여러 노드가 병렬로 처리하여 더욱 빠르죠.
    • 다수의 작은 파일(Many Small Files): 수천, 수만 개의 작은 파일을 업로드할 때는 S3 오브젝트 스토리지의 특성상 메타데이터 처리 오버헤드가 발생할 수 있습니다. 하지만 Nextcloud의 캐싱 메커니즘과 MinIO의 최적화 덕분에, 일반적인 사용 환경에서는 큰 불편함 없이 사용할 수 있었습니다. 다만, 파일 동기화 클라이언트에서 초기 동기화 시에는 시간이 좀 더 걸릴 수 있습니다.
    • 랜덤 액세스(Random Access): Nextcloud가 S3에 저장된 파일을 스트리밍하거나 부분적으로 액세스할 때, S3의 바이트 범위 요청(Byte-range requests) 기능 덕분에 효율적으로 동작합니다. 이건 로컬 디스크와 거의 동일한 사용자 경험을 제공해줍니다.

    결론적으로, Nextcloud와 S3의 연동은 파일 I/O 성능보다는 안정성, 확장성, 그리고 관리 용이성 측면에서 큰 이점을 가져다줍니다. 특히 Nextcloud 서버의 디스크 용량 고민에서 해방될 수 있다는 점이 정말 매력적이었어요.

    비용 효율성 심층 분석

    비용 효율성은 S3 스토리지 연동의 핵심 이유 중 하나입니다. 제가 홈랩에서 MinIO를 쓰는 주된 이유도 바로 이것인데요.

    MinIO (온프레미스 S3) vs. Public Cloud S3 (AWS S3)

    저처럼 홈랩에서 MinIO를 운영한다면, 초기 하드웨어 투자 비용(서버, 디스크)은 발생하지만, 그 이후에는 데이터 저장량에 따른 추가 비용이 거의 들지 않습니다. 전기세 정도가 들겠네요. 장기적으로 대용량 데이터를 저장할 계획이라면 매우 비용 효율적인 선택이 될 수 있습니다.

    반면 AWS S3 같은 퍼블릭 클라우드 서비스를 이용하면, 초기 하드웨어 투자 없이 바로 사용할 수 있습니다. 하지만 데이터 저장량(Storage), 데이터 전송량(Data Transfer), API 요청(Requests)에 따라 요금이 부과됩니다. 특히 데이터 전송량(특히 Ingress/Egress, 외부로 나가는 트래픽) 요금이 예상보다 많이 나올 수 있으니, 요금 구조를 잘 이해하고 사용해야 합니다.

    구분 로컬 디스크 (Nextcloud 기본) MinIO (온프레미스 S3) AWS S3 (퍼블릭 클라우드)
    확장성 제한적 (서버 디스크 용량에 의존) 높음 (스케일 아웃 가능) 매우 높음 (무제한에 가까움)
    안정성 단일 서버 장애에 취약 분산 구성 시 높음 매우 높음 (다중 가용영역)
    초기 비용 디스크 구매 비용 서버/디스크 구매 비용 없음 (클라우드 서비스)
    운영 비용 전기세, 유지보수 전기세, 유지보수 저장량, 전송량, 요청 수에 따라 과금
    성능 서버 I/O 성능에 직접 영향 백엔드 스토리지 성능에 영향, 분산 시 향상 대규모 분산 환경에 최적화
    관리 편의성 쉬움 중간 (직접 구축/관리) 쉬움 (클라우드 제공)
    Nextcloud 스토리지 옵션(로컬, MinIO, AWS S3)의 비용 및 성능 특성 비교표

    Nextcloud 스토리지 옵션별 주요 특성 비교표입니다. 각 환경에 맞는 최적의 선택을 할 수 있도록 도와줍니다.

    개인적으로는 MinIO를 홈랩에 구축하고, 중요한 데이터는 퍼블릭 클라우드 S3에 백업하는 하이브리드 전략을 추천합니다. 이렇게 하면 비용과 안정성을 동시에 잡을 수 있거든요. 저는 MinIO에 가족 사진을 저장하고, 이 MinIO 버킷을 다시 AWS S3 Glacier Deep Archive 같은 저렴한 스토리지 클래스에 비동기적으로 백업하는 식으로 활용하고 있습니다.

    마무리하며: 얻은 교훈과 다음 단계

    오늘은 Nextcloud와 S3 오브젝트 스토리지 연동에 대해 심층적으로 다뤄봤습니다. 제가 직접 경험하며 배운 점들을 정리해보자면 이렇습니다.

    • 확장성과 안정성: Nextcloud의 저장 공간 고민을 S3 연동으로 깔끔하게 해결할 수 있었습니다. 로컬 디스크의 한계를 넘어서는 유연함을 제공하죠.
    • MinIO의 매력: 홈랩 환경에서 S3 호환 스토리지를 구축하기에 MinIO는 정말 훌륭한 선택입니다. 오픈 소스라 비용 부담도 적고, 직접 관리하는 재미도 있고요.
    • 트러블슈팅은 기본: 역시 인프라 엔지니어의 숙명은 삽질 후 해결이죠! 네트워크, 방화벽, 인증서 문제는 늘 꼼꼼하게 확인해야 합니다.
    • 비용과 성능의 균형: 퍼블릭 클라우드 S3와 온프레미스 MinIO의 장단점을 잘 이해하고 자신의 환경에 맞는 최적의 솔루션을 선택하는 지혜가 필요합니다.

    이 글을 통해 Nextcloud S3 스토리지 연동에 대한 궁금증이 해소되고, 여러분의 홈랩이나 서버실 운영에 도움이 되었으면 좋겠습니다. 다음번에는 MinIO 클러스터 구성으로 고가용성(High Availability)을 확보하는 방법이나, Nextcloud 성능 최적화를 위한 Redis 캐싱 설정에 대해 다뤄볼까 합니다. 그때까지 다들 즐거운 삽질(?) 되시길 바랍니다! 궁금한 점이 있다면 언제든지 댓글로 남겨주세요.

  • [NAS 파일 시스템] Btrfs, 데이터 무결성을 위한 현명한 선택일까?

    [NAS 파일 시스템] Btrfs, 데이터 무결성을 위한 현명한 선택일까?

    [NAS 파일 시스템] Btrfs, 데이터 무결성을 위한 현명한 선택일까?

    안녕하세요, 13년차 서버실 지킴이입니다. 오늘은 NAS를 운영하시는 분들이라면 한 번쯤 고민해봐야 할 주제, 바로 Btrfs 파일 시스템에 대해 얘기해보려고 합니다. 저도 처음엔 ZFS(Zettabyte File System)만 최고인 줄 알았거든요. 근데 홈랩에서 다양한 파일 시스템을 직접 써보고 삽질도 좀 해보면서, Btrfs가 NAS 환경에서 얼마나 매력적인 선택지가 될 수 있는지 깨달았습니다. 특히 데이터 무결성(Data Integrity)을 중요하게 생각하신다면, 오늘 제 경험담이 도움이 될 거예요.

    소중한 데이터, 한순간의 실수나 하드웨어 오류로 날아가면 정말 끔찍하잖아요? 저도 예전에 백업 없이 중요한 자료를 날려본 경험이 있어서, 그때부터는 파일 시스템 선택에 정말 신중해졌습니다. Btrfs는 이런 걱정을 덜어줄 수 있는 강력한 기능들을 제공하더라고요. 과연 Btrfs가 여러분의 NAS 데이터를 안전하게 지켜줄 수 있을지, 함께 파헤쳐 봅시다!

    Btrfs 파일 시스템의 Copy-on-Write(CoW) 및 스냅샷 작동 방식 개념도

    Btrfs 파일 시스템의 Copy-on-Write(CoW) 및 스냅샷 작동 방식 개념도

    Btrfs, 너는 누구냐? 핵심 기능 파헤치기

    Btrfs는 ‘B-tree file system’의 약자로, 오라클에서 개발을 시작한 차세대 파일 시스템입니다. 리눅스 환경에서 널리 사용되고 있죠. 사실 처음엔 이게 뭔가 싶었는데, 몇 가지 핵심 기능들을 알고 나니 “이거 진짜 물건이더라고요!” 하는 생각이 들었습니다. 특히 NAS에 적용했을 때 빛을 발하는 기능들이 많더라고요.

    1. Copy-on-Write (CoW, 카피 온 라이트)

    이름 그대로 ‘쓸 때 복사한다’는 의미입니다. 기존 데이터를 변경할 때, 해당 데이터를 덮어쓰지 않고 새로운 위치에 변경된 데이터를 쓴 다음, 메타데이터(Metadata)만 업데이트하는 방식이죠. 이게 왜 중요하냐면요?

    • 데이터 손상 방지: 전원이 갑자기 나가거나 시스템에 문제가 생겨도, 작업 중이던 데이터는 손상될지언정 기존 데이터는 온전히 보존됩니다.
    • 스냅샷의 기반: 이 CoW 덕분에 스냅샷(Snapshot) 기능이 아주 효율적으로 작동합니다.

    사실 CoW 방식은 ZFS에서도 볼 수 있는 강력한 기능인데, Btrfs도 이걸 아주 잘 활용하고 있더라고요.

    2. 스냅샷 (Snapshot)

    스냅샷은 특정 시점의 파일 시스템 상태를 저장하는 기능입니다. 마치 게임에서 세이브 포인트를 만드는 것과 같아요. Btrfs의 스냅샷은 CoW 덕분에 용량을 거의 차지하지 않는다는 게 정말 큰 장점입니다. 변경된 블록만 저장하면 되니까요.

    • 실수로 파일 삭제/수정: 걱정 마세요! 스냅샷으로 쉽게 특정 시점으로 되돌릴 수 있어요.
    • 랜섬웨어 공격: 이것 때문에 저도 Btrfs를 더 신뢰하게 됐는데요, 만약 랜섬웨어에 감염되더라도 감염되기 전 스냅샷으로 복원하면 피해를 최소화할 수 있습니다. 정말 든든하죠!

    3. 데이터 무결성 (Data Integrity)을 위한 체크섬 (Checksum)

    Btrfs는 데이터 블록과 메타데이터 블록에 각각 체크섬을 적용합니다. 데이터를 읽을 때마다 체크섬을 확인해서, 혹시라도 데이터가 손상(Bit Rot, 비트 로트)되었는지 검사하죠. 만약 손상된 부분을 발견하면, RAID 1이나 RAID 10처럼 미러링된 구성에서는 자동으로 손상되지 않은 사본으로 복구해버립니다. 이게 바로 자가 복구(Self-Healing) 능력입니다.

    제가 실제로 써보니까, 이런 기능들이 작은 홈랩 NAS부터 기업용 스토리지까지 데이터의 신뢰성을 크게 높여주더라고요. 처음엔 “굳이 이렇게까지 해야 하나?” 싶었는데, 한 번 데이터를 잃고 나면 생각이 확 달라집니다.

    NAS에서 Btrfs 실전 활용: 어떻게 적용할까?

    많은 NAS 제조사들이 Btrfs를 채택하고 있습니다. 특히 Synology(시놀로지) 같은 경우 Btrfs를 적극적으로 활용해서 스냅샷, 데이터 무결성 기능을 사용자에게 제공하고 있죠. 하지만 직접 리눅스 서버에 NAS를 구축한다면, Btrfs를 직접 설정해야 합니다.

    1. Btrfs 파일 시스템 생성

    먼저 Btrfs로 포맷할 디스크를 준비해야 합니다. 저는 주로 여러 디스크를 묶어서 사용하는데요, Btrfs는 자체적으로 소프트웨어 RAID 기능을 제공합니다. (물론 안정성 측면에서는 하드웨어 RAID나 mdadm 위에 Btrfs를 쓰는 것도 고려할 수 있습니다.)

    # /dev/sdb, /dev/sdc 두 개의 디스크로 RAID1 Btrfs 파일 시스템 생성
    sudo mkfs.btrfs -d raid1 -m raid1 /dev/sdb /dev/sdc
    
    # 기존 디스크를 Btrfs 풀에 추가할 경우
    sudo btrfs device add /dev/sdd /mnt/btrfs_pool
    sudo btrfs balance start -dusage=50 /mnt/btrfs_pool # 데이터 분배

    이렇게 생성된 Btrfs 볼륨을 원하는 마운트 포인트에 마운트하면 됩니다.

    2. 서브볼륨 (Subvolume) 생성 및 관리

    Btrfs의 서브볼륨은 일반적인 디렉토리와 비슷하지만, 독립적인 스냅샷을 찍거나 할당량(Quota)을 설정할 수 있는 등 더 강력한 기능을 제공합니다. 저는 보통 용도별로 서브볼륨을 나눠서 사용해요. 예를 들어, ‘Documents’, ‘Media’, ‘Backup‘ 이런 식으로요.

    sudo mount /dev/sdb /mnt/btrfs_pool
    
    # 'data'라는 서브볼륨 생성
    sudo btrfs subvolume create /mnt/btrfs_pool/data
    
    # 'data' 서브볼륨을 /srv/nas에 마운트 (fstab에도 등록하여 부팅 시 자동 마운트)
    sudo mount -o subvol=data /dev/sdb /srv/nas

    3. 스냅샷 생성 및 관리

    이제 서브볼륨에 데이터를 저장하고, 주기적으로 스냅샷을 찍어줍니다. 스냅샷은 읽기 전용(Read-Only)으로 생성하는 것이 일반적입니다.

    # 'data' 서브볼륨의 스냅샷 생성
    sudo btrfs subvolume snapshot -r /srv/nas /srv/nas/.snapshots/data_$(date +%Y%m%d_%H%M%S)
    
    # 생성된 스냅샷 목록 확인
    sudo btrfs subvolume list -t -o /mnt/btrfs_pool

    스냅샷을 자동으로 찍어주는 스크립트나 서비스(예: <code>btrfs-autosnap, snapper)를 활용하면 훨씬 편리하게 관리할 수 있어요. 저도 처음엔 수동으로 찍다가, 나중엔 스크립트 걸어놓고 마음 편하게 쓰고 있습니다.

    Btrfs 파일 시스템을 활용한 NAS 구성 개념도

    Btrfs 파일 시스템을 활용한 NAS 구성 개념도

    ⚠️ 주의사항 및 트러블슈팅: 제가 겪었던 삽질들

    Btrfs가 만능은 아닙니다. 제가 직접 써보면서 몇 가지 주의할 점과 삽질 경험을 공유해 드릴게요.

    1. 성능 오버헤드 (Performance Overhead)

    Copy-on-Write 방식은 데이터 무결성을 높여주지만, 쓰기(Write) 작업 시 약간의 성능 저하가 발생할 수 있습니다. 특히 랜덤 쓰기(Random Write)가 많은 환경에서는 체감될 수 있어요. 처음엔 “왜 이렇게 느리지?” 싶었는데, 알고 보니 CoW 때문이더라고요. 그래서 고성능이 최우선인 환경보다는 데이터 안정성이 중요한 환경에 더 적합하다고 생각합니다.

    2. 디스크 공간 관리 (Disk Space Management)

    스냅샷은 공간을 효율적으로 사용하지만, 너무 많은 스냅샷을 오랫동안 보관하면 결국 디스크 공간을 많이 차지하게 됩니다. 특히 삭제된 파일이 스냅샷에 남아있다면 실제 공간은 회수되지 않거든요. 주기적으로 오래된 스냅샷을 삭제해주는 정책이 필요해요.

    # 오래된 스냅샷 삭제 예시 (가장 최신 스냅샷 10개만 남기고 삭제)
    # 실제 사용 시에는 신중하게 접근해야 합니다.
    LATEST_SNAPSHOTS=$(sudo btrfs subvolume list -t -o /mnt/btrfs_pool | grep 'snapshots' | sort -r | head -n 10 | awk '{print $9}')
    ALL_SNAPSHOTS=$(sudo btrfs subvolume list -t -o /mnt/btrfs_pool | grep 'snapshots' | awk '{print $9}')
    
    for SNAPSHOT in $ALL_SNAPSHOTS; do
        IS_LATEST=false
        for LATEST in $LATEST_SNAPSHOTS; do
            if [ "$SNAPSHOT" == "$LATEST" ]; then
                IS_LATEST=true
                break
            fi
        done
        if ! $IS_LATEST; then
            echo "Deleting old snapshot: $SNAPSHOT"
            sudo btrfs subvolume delete "$SNAPSHOT"
        fi
    done

    ⚠️ 경고: 스냅샷 삭제는 신중하게! 복구 불가능합니다.

    3. RAID 기능의 성숙도

    Btrfs는 자체 RAID0, RAID1, RAID5, RAID6 기능을 제공해요. 하지만 RAID5/6의 경우 초기에는 안정성 문제가 보고되기도 했습니다. 지금은 많이 개선되었지만, 아직까지는 mdadm RAID1 위에 Btrfs를 사용하거나, RAID10을 선호하는 경우가 많습니다. 저도 안정성을 위해 RAID10을 주로 사용하거나, 디스크 두 개만 쓰는 NAS에는 Btrfs RAID1을 쓰는 편입니다.

    ✅ 검증 및 결과: 내 데이터는 안전한가?

    Btrfs를 설정하고 나면, 데이터가 정말 안전하게 관리되고 있는지 확인해야겠죠? 저는 주기적으로 btrfs scrub 명령어를 실행해서 파일 시스템의 데이터 무결성을 검사합니다. 이 명령은 모든 데이터와 메타데이터 블록의 체크섬을 확인하고, 손상된 부분이 있으면 자동으로 복구해줍니다.

    # Btrfs 파일 시스템 스크럽 시작
    sudo btrfs scrub start /mnt/btrfs_pool
    
    # 스크럽 진행 상황 확인
    sudo btrfs scrub status /mnt/btrfs_pool

    스크럽이 완료되면 “드디어 됐다!” 하는 안도감이 들어요. 이 기능을 통해서 디스크 자체의 물리적인 오류나 비트 로트 현상으로부터 데이터를 보호할 수 있습니다. NAS를 며칠씩 켜놓는 저에게는 정말 필수적인 기능이라고 생각해요.

    Btrfs scrub 및 스냅샷 목록 확인 터미널 출력 화면

    Btrfs scrub 및 스냅샷 목록 확인 터미널 출력 화면

    마무리: Btrfs, NAS 데이터 무결성을 위한 현명한 선택일까?

    결론부터 말씀드리자면, Btrfs는 NAS 환경에서 데이터 무결성과 관리 유연성을 크게 향상시켜 줄 수 있는 현명한 선택지가 될 수 있습니다. 특히 스냅샷 기능은 랜섬웨어 방어나 실수로 인한 데이터 손실 복구에 엄청난 강점을 보여주거든요. CoW 기반의 효율적인 공간 활용도 정말 매력적입니다.

    하지만 성능 오버헤드나 RAID 기능의 성숙도 등 고려해야 할 부분도 분명히 있습니다. 완벽한 파일 시스템은 없으니까요. 여러분의 NAS 사용 목적과 중요도에 따라 Btrfs가 최적의 선택이 될 수도, 아닐 수도 있겠죠. 저처럼 홈랩에서 다양한 시도를 해보면서 자신에게 맞는 최적의 조합을 찾아가는 과정 자체가 인프라 엔지니어의 숙명 아닐까요? ㅎㅎ

    다음 글에서는 Btrfs와 ZFS를 좀 더 심층적으로 비교해보는 시간을 가져볼까 합니다. 혹시 Btrfs를 사용하면서 겪었던 재미있는 삽질 경험이 있으시다면 댓글로 공유해주세요! 저도 배우는 재미가 쏠쏠하거든요. 긴 글 읽어주셔서 감사합니다!

    Btrfs 파일 시스템의 NAS 적용 장단점 인포그래픽 요약

    Btrfs 파일 시스템의 NAS 적용 장단점 인포그래픽 요약

  • [Nas] Synology Photos 동기화 1년 사용 후기: 불편했던 점과 해결책

    [Nas] Synology Photos 동기화 1년 사용 후기: 불편했던 점과 해결책

    Synology Photos 동기화 1년 사용 후기: 불편했던 점과 해결책

    안녕하세요. 13년차 인프라 엔지니어, 홈랩 운영자인 제가 돌아왔습니다. 오늘은 많은 분들이 궁금해하실 만한 주제, 바로 Synology Photos 동기화에 대한 1년 사용 후기를 들려드리려고 합니다. 사진은 우리의 소중한 추억이 담긴 데이터잖아요. 이걸 어떻게 안전하고 편리하게 관리하고 동기화할지가 늘 고민이었는데, Synology Photos를 사용하면서 느꼈던 점들을 솔직하게 공유하고, 특히 사용하면서 겪었던 불편함과 그 해결 과정까지 자세히 알려드릴게요. 혹시 Synology NAS를 사용하며 사진 관리에 대한 고민이 있으셨다면, 오늘 제 이야기가 큰 도움이 될 거라고 생각합니다. 자, 그럼 시작해 볼까요?

    Synology Photos는 Synology NAS 사용자라면 누구나 한 번쯤 사용해보거나 고려해봤을 법한 서비스입니다. 개인 클라우드 스토리지의 대표 주자라고 할 수 있죠. 사진을 NAS로 백업하고, 여러 기기에서 접근하며, 가족들과 공유하는 등 다양한 기능을 제공하는데, 특히 ‘자동 동기화’ 기능은 스마트폰 사진을 일일이 옮기는 수고를 덜어주기 때문에 정말 매력적이더라고요. 저도 이 자동 동기화 기능 때문에 Synology Photos를 메인 사진 관리 솔루션으로 선택하게 되었습니다. 제 홈랩 환경에서 Synology NAS는 이미 다양한 서비스들을 안정적으로 운영하고 있었기에, 사진 관리까지 맡기기에 충분하다고 판단했죠.

    Synology Photos 동기화, 무엇이 문제였을까?

    1년이라는 시간 동안 Synology Photos 동기화 기능을 정말 열심히 사용했습니다. 스마트폰으로 찍은 사진이 자동으로 NAS로 백업되는 편리함은 이루 말할 수 없었죠. 하지만 완벽할 수는 없었습니다. 1년이라는 시간은 충분히 많은 문제점을 발견하고, 또 해결하기 위한 ‘삽질’의 시간을 갖기에 충분했거든요. 특히 제 경험상 가장 불편했던 점은 다음과 같았습니다.

    • 불안정한 동기화 속도: 사진 몇 장은 금방 올라가지만, 사진이 많아지거나 동영상이 섞이면 속도가 현저히 느려지거나 멈추는 현상이 잦았습니다.
    • 중복 파일 문제: 간혹 같은 사진이 여러 번 백업되거나, 이미 백업된 파일이 다시 동기화 대상으로 잡히는 경우가 있었습니다.
    • 모바일 앱의 불안정성: 특정 조건에서 모바일 앱이 비정상적으로 종료되거나, 동기화 상태가 제대로 반영되지 않는 문제가 있었습니다.
    • 설정의 복잡성: 처음 Synology Photos를 설정할 때, 어떤 옵션을 선택해야 최적의 동기화가 이루어지는지 이해하기 어려웠습니다.

    이런 문제들 때문에 처음엔 ‘이거 제대로 작동하는 거 맞나?’ 싶을 정도로 답답했어요. 매번 수동으로 확인하고, 겹치는 파일을 정리하는 과정은 자동 백업의 의미를 퇴색시키기에 충분했죠. 하지만 13년차 인프라 엔지니어로서, 저는 포기할 수 없었어요. 바로 이 문제들을 해결하기 위한 여정을 시작했죠. 사실 저만 이런 불편함을 겪는 건 아닐 거라고 생각합니다. 많은 분들이 비슷한 경험을 하고 계실 거예요. 그래서 오늘은 제가 겪었던 문제들과, 그것들을 어떻게 해결했는지 구체적인 방법을 공유하려고 합니다.

    Synology Photos 모바일 앱 동기화 설정 화면: 자동 백업, Wi-Fi 전용, 중복 파일 처리 옵션을 보여줍니다.

    위 이미지는 Synology Photos 모바일 앱의 동기화 설정 화면입니다. 언뜻 보기에는 간단해 보이지만, 각 옵션이 실제 동기화에 미치는 영향을 정확히 이해하는 것이 중요합니다. 예를 들어, ‘중복 파일 건너뛰기’ 옵션을 제대로 설정하지 않으면 앞서 말씀드린 중복 파일 문제가 발생할 확률이 높아지죠. 저도 처음에는 이 설정들을 제대로 이해하지 못해서 몇 번의 시행착오를 겪었습니다.

    핵심 개념: Synology Photos 동기화 작동 방식 이해하기

    Synology Photos의 동기화는 크게 두 가지 방식으로 작동합니다. 하나는 ‘백업(Backup)’이고, 다른 하나는 ‘사진 백업(Photo Backup)’입니다. 좀 더 정확히 말하면, ‘사진 백업’은 주로 모바일 앱에서 NAS로 사진을 옮기는 데 초점을 맞추고, ‘백업’이라는 용어는 좀 더 포괄적인 의미로 사용될 수 있습니다. 여기서 중요한 것은 모바일 앱의 ‘사진 백업’ 기능인데요.

    사진 백업 (Photo Backup):

    • 스마트폰 사진 자동 업로드: 사용자가 스마트폰으로 찍은 사진과 동영상을 Synology NAS의 지정된 폴더로 자동으로 업로드하는 기능입니다.
    • Wi-Fi 전용/모바일 데이터 사용: Wi-Fi 환경에서만 업로드하도록 설정하거나, 모바일 데이터를 사용해서도 업로드하도록 설정할 수 있습니다. 비용과 데이터 사용량을 고려하여 선택해야 하죠.
    • 실시간/예약 업로드: 사진이 찍히는 즉시 업로드하거나, 특정 시간에만 업로드하도록 예약할 수도 있습니다.
    • 중복 파일 처리: 이미 업로드된 파일은 건너뛰거나, 덮어쓰거나, 새 파일로 저장하는 옵션을 선택할 수 있습니다. 이 옵션이 매우 중요합니다!

    이 ‘사진 백업’ 기능은 Synology Photos의 핵심이라고 할 수 있습니다. 이 기능이 안정적으로 작동해야 우리가 원하는 ‘편리한 사진 관리’가 가능해지거든요. 저는 이 기능을 ‘스마트폰 사진의 외부 저장소(External Storage for Smartphone Photos)‘라고 생각하고 사용하고 있습니다. 즉, 스마트폰의 저장 공간을 절약하고, 혹시 모를 스마트폰 분실이나 고장으로부터 사진 데이터를 안전하게 보호하는 역할을 하는 것이죠.

    실전 해결: Synology Photos 동기화 속도 개선과 중복 파일 해결하기

    가장 골치 아팠던 ‘불안정한 동기화 속도’와 ‘중복 파일 문제’를 해결하기 위해 제가 했던 방법들을 단계별로 설명해 드릴게요. 이 방법들은 제 경험을 바탕으로 한 것이므로, 모든 환경에 완벽하게 적용되지 않을 수도 있습니다. 하지만 많은 분들에게 도움이 될 것이라고 확신합니다.

    1. Synology NAS 및 Synology Photos 패키지 최신 업데이트 확인:

      가장 기본적인 단계이지만, 의외로 많은 문제의 원인이 될 수 있습니다. Synology DSM(DiskStation Manager) 운영체제와 Synology Photos 패키지가 최신 버전인지 항상 확인하세요. 업데이트는 종종 버그 수정과 성능 개선을 포함하거든요.

      • DSM 업데이트: 제어판 > 업데이트 및 복원
      • Synology Photos 업데이트: 패키지 센터 > 설치됨 > Synology Photos > 업데이트
    2. 모바일 앱 ‘사진 백업’ 설정 최적화:

      이 부분이 가장 중요합니다. 앞서 언급했던 ‘중복 파일 처리’ 옵션을 신중하게 선택해야 합니다. 저는 다음과 같이 설정했어요.

      • 업로드 대상: ‘Wi-Fi 전용’으로 설정하여 모바일 데이터 사용을 최소화했습니다.
      • 중복 파일 처리: ‘중복된 파일 건너뛰기‘ 옵션을 선택했습니다. 이게 핵심이에요. 만약 ‘덮어쓰기’나 ‘새 파일로 저장’을 선택하면 중복 파일이 계속 쌓이거나, 예상치 못한 문제가 발생할 수 있습니다.
      • 업로드 시 사진 자동 회전: 이 옵션은 개인의 선호에 따라 선택하면 됩니다. 저는 ‘사용 안 함’으로 설정했습니다.
    3. 동기화 폴더 분리 및 체계적 관리:

      모든 사진을 한 번에 동기화하려고 하면 NAS에 부하가 많이 걸리고 속도가 느려질 수 있습니다. 저는 사진을 연도별, 월별로 나누어 동기화 폴더를 관리했습니다. 예를 들어, ‘2023’ 폴더, ‘2024’ 폴더 등으로 나누고, 각 폴더 안에서 다시 월별로 나누는 식이죠. 이렇게 하면 특정 폴더에 파일이 집중되는 것을 막고, 동기화 과정에서 발생하는 오류를 특정 폴더에 국한시킬 수 있습니다.

    4. 네트워크 환경 점검 및 최적화:

      Synology Photos 동기화는 네트워크 속도에 매우 민감합니다. NAS와 스마트폰이 연결된 네트워크 환경이 안정적인지 확인하는 것이 중요합니다. 특히 Wi-Fi 신호가 약한 곳에서는 동기화 속도가 현저히 느려지거나 끊길 수 있어요. 가능하다면 NAS는 유선 LAN으로 연결하고, 스마트폰도 Wi-Fi 신호가 강한 곳에서 동기화하는 것이 좋습니다. 또한, 공유기(Router)의 펌웨어가 최신인지 확인하고, 필요하다면 재부팅하는 것도 도움이 될 수 있습니다.

    5. Synology Photos의 ‘파일 목록 다시 생성’ 활용:

      간혹 동기화 상태가 꼬이거나 파일 목록이 제대로 표시되지 않을 때가 있습니다. 이럴 때는 Synology Photos 설정에서 ‘파일 목록 다시 생성‘ 기능을 활용해 보세요. 이 기능은 Synology Photos가 모든 사진 파일 목록을 처음부터 다시 읽어오도록 하여 동기화 관련 문제를 해결하는 데 도움이 될 수 있습니다. 물론 이 과정에서 시간이 다소 소요될 수 있습니다.

    Synology Photos PC 앱 백업 설정 화면: 실시간 및 예약 백업 옵션을 보여줍니다.

    위 이미지는 Synology Photos PC 앱의 설정 화면입니다. PC에서도 Synology Photos를 이용하면 NAS에 있는 사진을 관리하거나, PC의 사진을 NAS로 백업하는 등의 작업을 할 수 있습니다. 모바일 앱과 마찬가지로 PC 앱에서도 동기화 관련 설정을 꼼꼼히 확인하는 것이 중요합니다. 특히 ‘백업’ 탭에서 ‘실시간 백업‘ 또는 ‘예약 백업‘ 옵션을 어떻게 설정하느냐에 따라 동기화의 효율성이 크게 달라질 수 있습니다.

    주의사항 및 트러블슈팅: 겪었던 황당한 순간들 ⚠️

    앞서 소개한 해결책들 외에도, 1년 동안 Synology Photos를 사용하면서 정말 다양한 ‘황당한’ 순간들을 겪었습니다. 몇 가지를 공유하며 주의사항을 알려드릴게요.

    • ⚠️ 모바일 데이터 사용 시 주의:

      Wi-Fi 환경이 아닌 모바일 데이터 환경에서 동기화를 허용했다가 데이터 요금이 폭탄처럼 나온 경험이 있습니다. (물론 저는 무제한 요금제라 괜찮았지만요! ㅎㅎ) 꼭 ‘Wi-Fi 전용’ 옵션을 사용하거나, 데이터 사용량을 미리 확인하는 습관을 들이세요. 특히 동영상이 많은 경우, 데이터 소모가 정말 어마어마합니다.

    • ⚠️ 초기 동기화 시 NAS 부하 주의:

      수천, 수만 장의 사진을 처음 동기화할 때는 NAS에 상당한 부하가 걸립니다. CPU 사용률이 높아지고, 디스크 I/O가 증가하죠. 이 시기에는 NAS로 다른 무거운 작업을 하는 것을 피하는 것이 좋습니다. 저도 처음에는 NAS가 왜 이렇게 느려졌나 한참을 헤맸던 기억이 납니다.

    • ⚠️ iOS 및 Android 버전별 호환성:

      가끔 특정 iOS 또는 Android 버전과 Synology Photos 앱 버전 간의 호환성 문제로 동기화 오류가 발생하는 경우가 있었습니다. 이런 경우, Synology 커뮤니티나 포럼에서 다른 사용자들의 경험을 찾아보고, 앱 업데이트를 기다리거나, 임시로 동기화를 중지하는 등의 조치가 필요할 수 있습니다.

    • ⚠️ Synology Photos 재설치 후 데이터 손실(?):

      정말 극단적인 경우지만, Synology Photos 패키지를 삭제하고 다시 설치하는 과정에서 데이터가 손실되었다고 생각했던 적이 있습니다. 하지만 실제로는 설정만 초기화된 것이고, NAS의 사진 데이터는 그대로 남아 있었어요. 다만, 동기화 설정 등을 처음부터 다시 해야 했죠. **중요한 것은, Synology Photos 패키지를 삭제하더라도 NAS에 저장된 사진 원본 데이터는 삭제되지 않는다는 점입니다.** 하지만 혹시 모르니 중요한 데이터는 항상 별도로 백업해두는 것이 좋습니다.

    결과 확인: 1년 사용 후 달라진 점 ✅

    위에서 설명드린 여러 가지 방법들을 적용하고 꾸준히 관리한 결과, Synology Photos 동기화는 이전보다 훨씬 안정적으로 작동하게 되었습니다. 더 이상 ‘이거 왜 안 되지?’라며 스트레스받는 일은 거의 없어졌어요. 이제 저는 다음과 같은 변화를 체감하고 있습니다.

    • 일관되고 빠른 동기화: ‘중복 파일 건너뛰기’ 옵션과 폴더 분리 덕분에 동기화 속도가 눈에 띄게 향상되었고, 중복 파일 문제도 거의 사라졌습니다.
    • 안정적인 앱 성능: 모바일 앱이 비정상적으로 종료되거나 멈추는 현상이 현저히 줄었습니다.
    • 효율적인 NAS 자원 사용: 불필요한 재동기화나 중복 파일 처리 과정이 줄어들어 NAS의 CPU 및 디스크 사용률이 안정적으로 유지됩니다.
    • 데이터 관리 스트레스 감소: 이제 사진을 찍고 나면 ‘자동으로 잘 백업되었겠지’라는 믿음이 생겨 마음이 편안해졌습니다.
    Synology Photos 동기화 설정 최적화 전후 비교표: 안정성, 속도, 중복 파일, NAS 부하 측면의 개선점을 요약합니다.

    위 표는 Synology Photos 동기화 설정 전후의 변화를 간략하게 요약한 것입니다. 보시는 것처럼, 몇 가지 설정 변경과 관리만으로도 동기화의 안정성과 속도 면에서 큰 개선을 이룰 수 있었습니다. 이제 Synology Photos는 제가 생각했던 ‘스마트폰 사진의 완벽한 자동 백업 솔루션’에 한 발짝 더 다가섰다고 할 수 있습니다. 물론 완벽하게 ‘매직’처럼 작동하는 것은 아니지만, 이 정도면 충분히 만족스러운 수준이라고 생각합니다.

    마무리하며: Synology Photos, 잘 활용하면 최고의 동반자

    Synology Photos 동기화 기능을 1년 동안 사용하면서 겪었던 불편함과 그 해결 과정을 솔직하게 공유해 드렸습니다. 처음에는 몇 가지 문제점 때문에 사용을 망설이기도 했지만, 꾸준한 설정 최적화와 문제 해결 노력을 통해 이제는 제 사진 데이터를 안전하게 관리해주는 든든한 동반자가 되었습니다.

    핵심은 **’중복 파일 건너뛰기’ 옵션의 올바른 설정**과 **네트워크 환경 점검**, 그리고 **체계적인 폴더 관리**였습니다. 이런 기본적인 부분들을 놓치지 않는다면, Synology Photos는 여러분의 소중한 사진들을 안전하게 보관하고 편리하게 관리할 수 있는 최고의 솔루션이 될 수 있습니다. 혹시 저와 비슷한 문제를 겪고 계셨다면, 오늘 제가 알려드린 방법들을 꼭 시도해 보시길 바랍니다. 분명 좋은 결과를 얻으실 수 있을 거예요.

    다음 글에서는 Synology Photos의 ‘공유 앨범’ 기능과 ‘페이스 태그’ 기능에 대한 1년 사용 후기를 다룰 예정이니, 많은 기대 부탁드립니다! 감사합니다.

  • [NAS] OpenMediaVault에 Immich 구축 6개월 사용기: 자가 호스팅 사진 관리의 명과 암

    [NAS] OpenMediaVault에 Immich 구축 6개월 사용기: 자가 호스팅 사진 관리의 명과 암

    OpenMediaVault에 Immich 구축 6개월 사용기: 자가 호스팅 사진 관리의 명과 암

    안녕하세요, 13년차 서버실입니다. 홈랩을 운영하며 이것저것 시도하는 게 제 낙인데요. 오늘은 많은 분들이 관심을 가지시는 자가 호스팅 사진 관리 솔루션, Immich를 OpenMediaVault(OMV)에 구축하고 6개월간 사용해 본 경험을 솔직하게 공유해 보려 합니다. 직접 써보니 정말 편한 부분도 많았지만, 예상치 못한 문제점들도 꽤 있더라고요. 이번엔 제 경험을 바탕으로 명과 암을 낱낱이 파헤쳐 보겠습니다.

    OpenMediaVault와 Immich를 활용한 홈랩 사진 관리 아키텍처 개요

    Immich와 OpenMediaVault를 활용한 전체 홈랩 사진 관리 아키텍처 개요

    왜 자가 호스팅 사진 관리인가? 🤔

    스마트폰 용량은 늘 부족하고, 사진은 기하급수적으로 늘어나죠. 클라우드 서비스는 편리하지만, 월마다 나가는 비용 부담이나 개인 정보 유출에 대한 걱정에서 자유롭지 못합니다. 특히 소중한 사진 데이터가 서비스 제공 업체의 정책 변화나 개인정보 유출 사고로 날아갈까 봐 불안한 마음, 다들 한 번쯤은 느껴보셨을 겁니다. 저도 그랬어요. 그래서 자가 호스팅 사진 관리, 특히 Immich 같은 오픈소스 솔루션에 눈을 돌리게 되었습니다. 내 손안의 작은 클라우드, 이게 가능하다는 게 신기하더라고요.

    Immich, 뭐가 그렇게 좋은데? 💡

    Immich는 Google Photos와 유사한 기능을 제공하는 오픈소스 사진 백업 및 관리 솔루션이에요. 핵심은 내 서버에 직접 설치해서 사용한다는 점이죠. 주요 기능들을 살펴보면:

    • 자동 백업: 스마트폰 사진을 자동으로 서버에 백업해 줘요. Google Photos의 자동 백업 기능과 거의 똑같다고 보시면 됩니다.
    • AI 기반 기능: 사진 내 객체 인식, 얼굴 인식, 중복 사진 제거 등 강력한 AI 기능을 제공합니다. 이게 또 은근히 편하더라고요.
    • 웹 UI & 모바일 앱: 깔끔한 웹 인터페이스와 함께 iOS, Android 모바일 앱을 지원해서 언제 어디서든 사진에 접근하고 관리할 수 있어요.
    • 다양한 포맷 지원: JPG, PNG뿐만 아니라 RAW 파일, 비디오 파일도 지원합니다.

    이런 강력한 기능들을 무료로, 내 마음대로 사용할 수 있다는 점이 Immich의 가장 큰 매력이에요. 물론, 이걸 구현하기 위해 몇 가지 기술적인 장벽을 넘어야 하긴 합니다.

    OpenMediaVault(OMV) 위에 Immich 올리기 🛠️

    저는 NAS(Network Attached Storage) 솔루션으로 OpenMediaVault(OMV)를 사용하고 있어요. OMV는 Debian 기반의 NAS 운영체제로, 웹 UI를 통해 스토리지 관리, 사용자 관리, 다양한 플러그인 설치 등을 쉽게 할 수 있게 해줍니다. Immich는 Docker 컨테이너로 배포되기 때문에 OMV의 Docker 플러그인과 함께라면 설치가 한결 수월합니다.

    1단계: OpenMediaVault 준비

    OMV가 설치되어 있고, Docker 플러그인이 활성화된 상태여야 해요. 만약 Docker 플러그인이 없다면, OMV 웹 UI의 ‘플러그인’ 메뉴에서 설치해 주세요. 그 후, Immich 데이터를 저장할 볼륨(Volume)을 위한 디스크나 파티션을 준비하고 OMV에서 파일 시스템으로 마운트해 두는 게 좋아요. 저는 `/srv/dev-disk-by-uuid/<UUID>/immich` 경로에 데이터를 저장하도록 구성했습니다.

    2단계: Immich Docker Compose 설정

    Immich는 Docker Compose를 사용하여 쉽게 배포할 수 있어요. GitHub 저장소에 예제 `docker-compose.yml` 파일이 제공되니 이를 활용하는 게 좋습니다. 저는 다음과 같이 설정을 구성했습니다.

    version: "3.8"
    
    services:
      immich-server:
        image: ghcr.io/immich-app/immich-server:latest
        container_name: immich_server
        ports:
          - "3001:3001"
        volumes:
          - ./library:/usr/src/app/upload
        environment:
          - DB_HOSTNAME=immich_db
          - DB_USERNAME=immich
          - DB_PASSWORD=your_strong_password
          - DB_NAME=immich
          - REDIS_HOSTNAME=immich_redis
        depends_on:
          - immich-db
          - immich-redis
        restart: unless-stopped
    
      immich-ml:
        image: ghcr.io/immich-app/immich-ml:latest
        container_name: immich_ml
        volumes:
          - ./model-cache:/cache
        environment:
          - TRANSFORMERS_CACHE=/cache
        restart: unless-stopped
    
      immich-db:
        image: postgres:15
        container_name: immich_db
        volumes:
          - ./postgres:/var/lib/postgresql/data
        environment:
          - POSTGRES_USER=immich
          - POSTGRES_PASSWORD=your_strong_password
          - POSTGRES_DB=immich
        restart: unless-stopped
    
      immich-redis:
        image: redis:7-alpine
        container_name: immich_redis
        restart: unless-stopped
    
    networks:
      default:
        name: immich_network
    

    주의: 위 설정에서 <UUID> 부분은 실제 OMV에서 마운트한 디스크의 UUID로 변경해야 합니다. 또한, `your_strong_password` 부분은 복잡하고 안전한 비밀번호로 바꿔주세요. 특히 AI 기능(얼굴 인식, 객체 인식)을 사용하려면 `immich-ml` 서비스가 필수이니까 꼭 포함시켜야 해요. 데이터베이스 비밀번호는 모든 컨테이너에서 동일하게 설정해야 합니다.

    3단계: Docker Compose 실행

    OMV의 SSH 기능을 활성화하거나, Docker 플러그인에서 제공하는 ‘Compose’ 기능을 사용하여 위 내용을 `docker-compose.yml` 파일로 저장한 후 실행해요. 저는 SSH로 접속하여 해당 디렉토리에서 docker compose up -d 명령어를 실행했습니다.

    OpenMediaVault Docker 플러그인에서 Immich 컨테이너 실행 모습

    OpenMediaVault에서 Docker 플러그인을 통해 Immich 컨테이너가 실행되고 있는 모습

    컨테이너가 모두 정상적으로 실행되면, 웹 브라우저에서 http://<OMV IP 주소>:3001 으로 접속하여 Immich 초기 설정을 진행할 수 있어요. 처음에는 관리자 계정을 생성하고, 이후 사용자 계정을 추가하며 사진을 업로드하면 됩니다.

    6개월간 사용하며 겪은 명과 암 ⛰️

    6개월간 Immich를 사용하면서 느낀 점들을 솔직하게 말씀드리겠습니다.

    ✨ 명 (장점)

    • 뛰어난 자동 백업 및 동기화: 스마트폰에서 찍은 사진이 실시간으로 서버에 백업되는 경험은 정말 혁신적이었어요. 용량 걱정 없이 마음껏 사진을 찍을 수 있게 되었죠.
    • 강력한 AI 기능: 사진 검색 시 객체나 장소로 검색하는 기능은 정말 편리했습니다. 잃어버렸던 사진을 찾거나 특정 테마의 사진을 모아볼 때 유용하더라고요. 중복 사진 제거 기능도 꽤 정확해서 스토리지 공간을 절약하는 데 큰 도움이 되었어요.
    • 깔끔한 UI/UX: 웹 인터페이스와 모바일 앱 모두 직관적이고 사용하기 편리했습니다. Google Photos에 익숙하다면 금방 적응할 수 있어요.
    • 오픈소스의 자유로움: 비용 부담 없이 원하는 대로 커스터마이징하고 관리할 수 있다는 점이 가장 큰 매력이에요.

    ⚠️ 암 (단점 및 주의사항)

    • 초기 설정의 복잡함: Docker, Docker Compose, 네트워크 설정 등 기본적인 이해가 없다면 설치 과정에서 어려움을 겪을 수 있어요. 저도 처음에는 Docker Compose 파일 설정 때문에 몇 번을 헤맸습니다.
    • 리소스 요구량: Immich는 AI 기능 등을 포함하여 꽤 많은 시스템 리소스(CPU, RAM)를 요구합니다. 특히 사진을 대량으로 업로드하거나 AI 분석을 실행할 때 서버 부하가 체감될 정도였어요. 저사양 홈랩 서버에서는 성능 저하가 발생할 수 있으니까 주의해야 합니다.
    • 업데이트 시 주의 필요: Immich는 활발하게 개발되고 있어 업데이트가 잦은 편입니다. 업데이트 과정에서 데이터베이스 스키마 변경 등으로 인해 문제가 발생할 수 있어서 항상 백업 후 업데이트하는 습관이 정말 중요해요. 저도 한 번 업데이트 후에 DB 연결에 문제가 생겨 잠시 당황했던 경험이 있습니다.
    • 안정성 이슈 (가끔): 가끔 예상치 못한 오류나 컨테이너 재시작이 필요한 경우가 있었어요. 특히 대규모 파일 업로드나 백업 작업 중에 발생하면 좀 당황스럽더라고요.
    • 데이터 무결성 책임: 모든 데이터 관리는 사용자 본인의 책임입니다. 백업, 스토리지 관리 등 모든 것을 직접 신경 써야 해요. 클라우드 서비스처럼 자동화된 백업/복구 시스템이 기본 제공되는 건 아니니까요.
    Immich 대시보드: 사진 업로드 및 AI 분석 진행 상황

    Immich 대시보드에서 사진 업로드 진행 상황과 AI 분석 상태를 보여주는 화면

    트러블슈팅: 흔히 겪는 문제들 🚨

    6개월간 사용하면서 몇 가지 문제에 부딪혔고, 이를 해결했던 경험을 공유합니다.

    • 문제 1: 컨테이너 재시작 후 DB 연결 실패
    • 원인: Immich 서버 컨테이너가 DB 컨테이너보다 먼저 시작되면서 발생할 수 있어요.
    • 해결책: `docker-compose.yml` 파일에서 `depends_on` 설정을 명확히 하고, Immich 서버 컨테이너에 재시도 로직을 추가하거나, 컨테이너 재시작 후 잠시 기다렸다가 수동으로 재시작하는 방법이 있습니다. 저는 `depends_on` 설정을 활용했어요.
    • 문제 2: 사진 업로드가 간헐적으로 실패
    • 원인: 서버 리소스 부족, 네트워크 불안정, 혹은 Immich 자체의 버그일 수 있습니다.
    • 해결책: 서버의 CPU, RAM 사용량을 확인하고, 필요하다면 리소스를 증설하거나 백업/AI 분석 작업 시간을 조정했어요. 네트워크 상태도 점검하고, Immich의 최신 버전을 사용하며 커뮤니티 피드백을 확인하는 것이 좋습니다.
    • 문제 3: AI 기능 (얼굴 인식 등)이 제대로 동작하지 않음
    • 원인: AI 모델 다운로드 실패, 설정 오류, 또는 리소스 부족으로 인한 백그라운드 작업 지연이에요.
    • 해결책: Immich의 `docker-compose.yml` 파일에서 `immich-ml` 서비스와 관련 볼륨 설정을 확인하고, 필요한 경우 `docker compose down` 후 `docker compose pull immich-ml` 명령어로 이미지를 최신 버전으로 다시 받아준 후 `docker compose up -d`로 재시작했어요. 서버 리소스가 충분한지 다시 한번 확인하는 것도 정말 중요합니다.

    결론: 6개월간의 자가 호스팅 사진 관리 여정 📝

    OpenMediaVault 위에 Immich를 구축하여 6개월간 사용해 본 결과, 자가 호스팅 사진 관리 솔루션으로서 Immich는 충분히 매력적이고 강력한 대안이라고 생각합니다. 특히 Google Photos의 편리함에 익숙하지만, 개인 정보 보호나 비용 절감을 원하는 분들에게는 최고의 선택지가 될 수 있어요.

    하지만 만능은 아닙니다. 초기 설정의 장벽, 시스템 리소스 요구량, 업데이트 시의 주의, 그리고 데이터 관리에 대한 전적인 책임 등 고려해야 할 부분들이 분명히 있거든요. 마치 잘 길들여진 애완동물처럼, 꾸준한 관심과 관리가 필요한 셈이죠.

    Immich 사진 갤러리 보기와 검색 기능 비교 인포그래픽

    Immich의 사진 갤러리 보기와 검색 기능을 비교하는 인포그래픽

    만약 여러분이…

    • 기술적인 도전을 즐기시고,
    • 직접 시스템을 구축하고 관리하는 것을 좋아하며,
    • 개인 데이터의 프라이버시와 통제권을 최우선으로 생각한다면,

    Immich는 분명 여러분의 홈랩에 훌륭한 추가가 될 거예요. 처음에는 조금 어렵게 느껴질 수 있지만, 한번 구축해두면 그 편리함에 만족하실 겁니다. 저도 앞으로도 Immich를 계속 사용하며 홈랩 사진 관리의 여정을 이어갈 생각이에요.

    다음 글에서는 Immich의 백업 및 복구 전략에 대해 좀 더 자세히 다뤄보도록 하겠습니다. 감사합니다!

  • [Nas] TrueNAS iSCSI로 가상머신 마이그레이션: ESXi 스토리지 이전 완벽가이드

    [Nas] TrueNAS iSCSI로 가상머신 마이그레이션: ESXi 스토리지 이전 완벽가이드

    TrueNAS iSCSI로 가상머신 마이그레이션: ESXi 스토리지 이전 완벽가이드

    안녕하세요, 13년차 서버실 지킴이입니다. 오늘은 많은 인프라 엔지니어들이 한 번쯤 고민해봤을 주제, VMware ESXi 가상머신(Virtual Machine, VM)을 TrueNAS iSCSI 스토리지로 마이그레이션(Migration, 이전)하는 성공 사례를 들려드리려고 합니다. 저도 홈랩을 운영하면서 스토리지 확장의 필요성을 절감했고, 이 과정에서 꽤나 삽질을 했거든요. 하지만 결국 성공했고, 그 경험을 여러분과 나누고 싶습니다. 💡

    기존에 사용하던 로컬 스토리지의 용량이 부족해지거나, 더 나은 성능과 유연성을 위해 중앙 집중식 스토리지로 옮겨야 할 때가 있죠. 특히 ESXi 스토리지 이전은 단순히 데이터 복사 이상의 복잡한 과정이 필요합니다. 이때 TrueNAS iSCSI는 비용 효율적이면서도 강력한 대안이 될 수 있습니다. iSCSI VM 마이그레이션을 고민 중이라면, 오늘 이야기가 큰 도움이 될 겁니다.

    ESXi와 TrueNAS iSCSI 스토리지를 활용한 가상머신 마이그레이션 전체 구성도입니다.

    1. 핵심 개념 이해: ESXi, TrueNAS, 그리고 iSCSI

    본격적인 마이그레이션에 앞서, 핵심 기술들이 무엇인지 간단히 짚고 넘어갈게요. “아, 이건 또 뭐야?” 싶으실 수도 있지만, 기본을 알아야 삽질을 줄일 수 있거든요. 😉

    • VMware ESXi (이엑스아이): VMware에서 개발한 베어메탈(Bare-metal) 하이퍼바이저(Hypervisor)입니다. 쉽게 말해, 물리 서버 위에 직접 설치되어 여러 가상머신을 효율적으로 운영할 수 있게 해주는 소프트웨어죠. 저희 서버실의 모든 가상머신은 ESXi 위에서 돌아가고 있습니다.
    • TrueNAS (트루나스): 오픈소스 네트워크 스토리지(Network Attached Storage, NAS) 운영체제입니다. 강력한 ZFS 파일 시스템을 기반으로 데이터 무결성과 유연성을 제공하며, 파일 공유는 물론 iSCSI와 같은 블록 스토리지 서비스도 지원합니다. 저의 홈랩에서는 TrueNAS Core 버전을 사용하고 있습니다.
    • iSCSI (아이 스카시, Internet Small Computer System Interface): IP 네트워크를 통해 SCSI(Small Computer System Interface) 명령을 전송하는 기술 표준입니다. 원격 서버에 마치 로컬 디스크처럼 블록 스토리지(Block Storage)를 연결할 수 있게 해줍니다. NAS iSCSI 설정은 ESXi가 TrueNAS의 스토리지를 마치 물리 디스크처럼 인식하게 만드는 핵심 단계라고 할 수 있죠.

    2. TrueNAS iSCSI 타겟 설정: 스토리지 준비하기

    이제 TrueNAS에서 ESXi가 사용할 iSCSI 스토리지를 만들어볼 차례입니다. “어렵지 않을까?” 걱정 마세요. 제가 직접 해보니 몇 가지 단계만 잘 따라가면 됩니다.

    단계별 TrueNAS iSCSI 설정

    1. ZFS 데이터셋(Dataset) 생성: 먼저 iSCSI 타겟으로 사용할 ZFS 데이터셋을 만듭니다. 저는 pool01/iscsi-vm이라는 데이터셋을 만들었어요.
    2. iSCSI 서비스 활성화: TrueNAS 웹 GUI에서 Services -> iSCSI로 이동하여 서비스를 활성화하고, Start Automatically를 체크해줍니다.
    3. 포털(Portal) 생성: iSCSI 통신에 사용할 IP 주소와 포트를 지정합니다. Sharing -> Block Shares (iSCSI) -> Portals 탭에서 Add를 클릭하고 TrueNAS의 IP 주소를 입력합니다.
    4. 이니시에이터(Initiator) 및 인증 설정 (선택 사항): 보안을 위해 특정 ESXi 호스트만 접근하도록 제한하거나, CHAP(Challenge-Handshake Authentication Protocol) 인증을 설정할 수 있습니다. 저는 홈랩이라 간단히 모든 이니시에이터(ALL Initiators)를 허용했지만, 프로덕션 환경에서는 반드시 제한해야 합니다.
    5. 익스텐트(Extent, LUN) 생성: 실제 스토리지 공간을 정의합니다. Extents 탭에서 Add를 클릭하고, 이전에 생성한 ZFS 데이터셋을 경로로 지정합니다. 이 익스텐트가 ESXi에 LUN(Logical Unit Number)으로 보이게 됩니다.
    6. 타겟(Target) 생성 및 연결: 마지막으로 익스텐트와 포털을 연결하여 타겟을 만듭니다. Targets 탭에서 Add를 클릭하고, 이름을 지정한 후 생성한 포털과 익스텐트를 연결합니다.

    이렇게 하면 TrueNAS에서 iSCSI 타겟 설정이 완료됩니다. 생각보다 간단하죠? ✅

    TrueNAS 웹 인터페이스에서 iSCSI 타겟을 설정하는 화면

    TrueNAS 웹 인터페이스에서 iSCSI 타겟을 설정하는 모습입니다.

    3. ESXi iSCSI 이니시에이터 설정: 서버 연결하기

    이제 ESXi 호스트가 TrueNAS의 iSCSI 스토리지를 인식하도록 설정해야 합니다. vSphere Client를 이용하면 GUI 환경에서 쉽게 설정할 수 있습니다.

    단계별 ESXi 설정

    1. iSCSI 소프트웨어 어댑터 활성화: vSphere Client에서 ESXi 호스트를 선택하고 Configure -> Storage Adapters로 이동합니다. Add Software Adapter를 클릭하여 Software iSCSI 어댑터를 추가합니다.
    2. 동적 검색(Dynamic Discovery) 설정: 새로 추가된 iSCSI 어댑터를 선택하고 Adapters 탭에서 Dynamic Discovery를 클릭, Add를 눌러 TrueNAS의 iSCSI 포털 IP 주소를 입력합니다.
    3. 네트워크 리스캔(Rescan): Storage Adapters 뷰로 돌아와 Rescan Adapters를 클릭합니다. 잠시 후 TrueNAS의 iSCSI LUN이 새로운 디바이스로 나타나는 걸 확인할 수 있어요.
    4. 새로운 데이터스토어(Datastore) 생성: Storage -> Datastores 탭으로 이동하여 New Datastore를 클릭합니다. VMFS 타입을 선택하고, 방금 검색된 TrueNAS iSCSI LUN을 선택하여 데이터스토어를 생성합니다. 원하는 이름을 지정하고 VMFS 버전을 선택하면 됩니다.

    자, 이제 ESXi 호스트가 TrueNAS의 iSCSI 스토리지를 사용할 준비가 끝났습니다. “진짜 되는 거야?” 싶으시겠지만, 여기까지 잘 오셨다면 거의 다 된 겁니다! 🎉

    4. 가상머신 마이그레이션: iSCSI 스토리지 이전의 핵심

    가장 중요한 단계, 가상머신 마이그레이션입니다. ESXi 환경에서는 Storage vMotion(스토리지 v모션)이라는 멋진 기능 덕분에 가상머신을 끄지 않고도 스토리지를 이전할 수 있습니다. 하지만 vCenter Server가 없는 홈랩 환경에서는 콜드 마이그레이션(Cold Migration, VM 종료 후 이전)을 해야 할 수도 있어요.

    Storage vMotion을 이용한 마이그레이션 (vCenter Server 환경)

    1. vSphere Client에서 마이그레이션할 가상머신을 선택합니다.
    2. 가상머신을 오른쪽 클릭하고 Migrate를 선택합니다.
    3. Change storage only 옵션을 선택한 후 Next를 클릭합니다.
    4. 대상 데이터스토어로 TrueNAS iSCSI를 통해 생성한 새 데이터스토어를 선택합니다.
    5. 설정을 확인하고 Finish를 클릭하면 마이그레이션이 시작됩니다.

    콜드 마이그레이션을 이용한 마이그레이션 (vCenter Server 없는 환경)

    1. 마이그레이션할 가상머신을 종료(Power Off)합니다.
    2. vSphere Client에서 가상머신을 선택하고 Migrate를 선택합니다.
    3. Change storage only 또는 Change compute resource and storage 옵션을 선택합니다. (호스트도 변경할 경우)
    4. 대상 데이터스토어로 TrueNAS iSCSI 데이터스토어를 선택하고 마이그레이션을 진행합니다.

    마이그레이션 진행 상황은 vSphere Client의 Recent Tasks에서 확인할 수 있습니다. 저도 처음엔 “이게 진짜 되는 건가?” 반신반의했는데, 진행률이 올라가는 걸 보니 너무 뿌듯하더라고요. 😊

    VMware vSphere Client에서 가상머신 스토리지 마이그레이션이 진행되는 화면입니다.

    5. iSCSI 마이그레이션 중 겪었던 문제들과 해결법 ⚠️

    “13년차 엔지니어도 삽질을 하나요?” 네, 물론이죠! 저도 이 과정에서 몇 번의 난관에 부딪혔고, 덕분에 많은 것을 배웠습니다. 😅

    • 네트워크 설정 문제: 처음에는 마이그레이션 속도가 너무 느려서 답답했어요. 알고 보니 ESXi의 iSCSI 전용 VMkernel 어댑터에 점보 프레임(Jumbo Frames)을 설정하지 않았더라고요. MTU(Maximum Transmission Unit) 값을 9000으로 올리니 속도가 훨씬 빨라졌습니다. TrueNAS와 ESXi 양쪽 모두 설정해야 한다는 점을 잊지 마세요! 💡

      \n# ESXi CLI에서 MTU 설정 예시 (vmnic0이 iSCSI용 NIC일 경우)\nesxcli network ip interface set -i vmkX -m 9000\n    
    • iSCSI 타겟/이니시에이터 불일치: TrueNAS에서 설정한 iSCSI ACL(Access Control List)이나 CHAP 인증 정보가 ESXi와 일치하지 않아 연결이 안 되는 경우가 있었습니다. “왜 안 되는 거야!” 하며 몇 시간을 헤맸는데, 결국 사소한 오타 때문이었죠. 설정값을 꼼꼼히 확인하는 것이 정말 중요합니다.
    • TrueNAS 방화벽: 간혹 TrueNAS의 내장 방화벽이 iSCSI 트래픽을 막는 경우가 있어요. iSCSI 기본 포트(3260)가 열려 있는지 확인하거나, ESXi 호스트의 IP를 허용 목록에 추가해야 합니다.

    이런 문제들을 해결하면서 “아, 이래서 경험이 중요하구나” 싶더라고요. 멘토처럼 알려드리는 제 글이 여러분의 삽질을 조금이나마 줄여주기를 바랍니다.

    6. iSCSI 마이그레이션 검증: 드디어 성공했습니다! 🎉

    모든 설정과 마이그레이션이 끝나고, 이제 결과를 확인할 차례입니다. “잘 작동하는지”를 보는 건 엔지니어의 가장 큰 기쁨이죠.

    1. vSphere Client에서 확인: 마이그레이션된 가상머신의 Summary 탭을 확인하면 스토리지가 새로운 TrueNAS iSCSI 데이터스토어로 변경된 것을 볼 수 있어요. 가상머신을 구동해보세요!
    2. TrueNAS 대시보드 확인: TrueNAS 웹 GUI의 Reporting 또는 Dashboard에서 iSCSI 서비스의 활성화 여부, 연결된 이니시에이터 수, 그리고 스토리지 I/O(Input/Output) 성능 그래프를 통해 실제 데이터 통신이 이루어지고 있는지 확인할 수 있습니다.
    3. 성능 모니터링: 가상머신 내부에서 디스크 I/O 벤치마크 툴(예: CrystalDiskMark, fio)을 사용하여 성능이 예상대로 나오는지 확인해보는 것도 좋습니다.

    제가 직접 확인해보니, 기존 로컬 스토리지 대비 디스크 I/O 성능이 크게 개선된 것을 체감할 수 있었습니다. 특히 여러 가상머신이 동시에 디스크를 사용하는 환경에서 더욱 빛을 발하더라고요. iSCSI VM 마이그레이션은 정말 성공적인 선택이었습니다!

    TrueNAS 대시보드에서 iSCSI 스토리지의 실시간 성능을 모니터링하는 대시보드

    TrueNAS 대시보드에서 iSCSI 스토리지의 실시간 성능을 모니터링하는 모습입니다.

    7. 마무리: ESXi iSCSI 마이그레이션 과정에서 얻은 교훈

    VMware ESXi 가상머신을 TrueNAS iSCSI 스토리지로 마이그레이션하는 과정은 쉽지 않았지만, 그만큼 얻은 것도 많습니다. 유연한 스토리지 확장, 향상된 성능, 그리고 무엇보다 “내가 해냈다!”는 성취감이 가장 큰 소득이었죠.

    이 경험을 통해 저는 다음과 같은 교훈을 얻었습니다.

    • 사전 계획의 중요성: 네트워크 구성, IP 주소 할당, 인증 방식 등 모든 설정을 미리 계획하는 것이 삽질을 줄이는 지름길입니다.
    • 문서화의 생활화: 삽질 과정을 기록하고 해결책을 문서화하면 다음번에 비슷한 문제가 발생했을 때 시간을 크게 절약할 수 있습니다. (사실 저도 이 글을 쓰면서 다시 한번 정리하는 거거든요 ㅎㅎ)
    • 오픈소스의 힘: TrueNAS 같은 오픈소스 솔루션은 상용 제품 못지않은 강력한 기능을 제공하며, 홈랩 환경에서 다양한 실험을 가능하게 합니다.

    혹시 여러분도 가상머신 스토리지 마이그레이션을 고민하고 계셨다면, TrueNAS iSCSI를 한 번 고려해보세요. 물론 처음엔 헷갈릴 수 있지만, 제 경험담이 여러분의 길을 밝혀주는 작은 등불이 되기를 바랍니다. 다음번에는 ESXi와 TrueNAS를 활용한 고가용성(High Availability) 구성에 대해서도 다뤄볼 예정이니 기대해주세요! 👍

  • [Nas] Cloudflare Tunnel vs. VPN: 홈서버 원격 접속 비용 효율성 비교 2026년 9월 업데이트

    [Nas] Cloudflare Tunnel vs. VPN: 홈서버 원격 접속 비용 효율성 비교 2026년 9월 업데이트

    💡 도입: 홈서버 원격 접속, 이젠 선택이 아닌 필수!

    안녕하세요, 13년차의 서버실 주인장입니다. 홈랩을 운영하는 인프라 엔지니어라면 누구나 한 번쯤은 이런 고민을 해봤을 거예요. “집에 있는 내 소중한 서버에 외부에서 안전하게 접속하고 싶다!” 저도 처음엔 공유기 포트 포워딩(Port Forwarding)으로 시작했었죠. 특정 포트를 열어두고 DDNS(Dynamic DNS)를 걸어서 접속했었는데, 이게 보안적으로 너무 취약하더라고요.

    그러다 보니 자연스럽게 VPN(Virtual Private Network), WireGuard, OpenVPN 같은 기술을 살펴보게 됐어요. 그런데 VPN도 서버를 직접 구축하고 관리하는 게 생각보다 손이 많이 가거든요. 그러다 Cloudflare Tunnel이라는 녀석을 알게 됐는데, 이거 진짜 물건이더라고요. 포트 포워딩 없이, 심지어 개인 홈랩 기준으로는 무료 플랜만으로도 꽤 강력한 보안 구성을 만들 수 있으니까요.

    그래서 오늘은 Cloudflare Tunnel과 VPN, 이 두 가지 홈서버 원격 접속 방법을 2026년 9월 기준으로 다시 비교해보려고 합니다. 특히 Cloudflare Zero Trust, WARP, private network routing, NAS 원격 접속, 홈랩 보안 같은 키워드가 중요해진 만큼 예전 글에서 살짝 오래된 부분도 같이 손봤습니다.

    홈서버 원격 접속을 위한 Cloudflare Tunnel과 VPN의 개념도를 나타낸 그림입니다. 외부에서 안전하게 홈서버에 접근하는 방식을 한눈에 볼 수 있습니다.

    🤔 Cloudflare Tunnel, VPN: 개념부터 잡아봅시다!

    본격적인 비교에 앞서, 두 기술이 정확히 어떤 것인지 개념부터 확실하게 짚고 넘어가는 게 좋겠죠? 쉽게 말해드릴게요.

    Cloudflare Tunnel (클라우드플레어 터널)

    Cloudflare Tunnel은 제로 트러스트(Zero Trust) 보안 모델을 기반으로 하는 서비스예요. 내부 네트워크의 포트를 외부로 직접 열지 않고, 홈서버에 설치한 cloudflared가 Cloudflare 네트워크로 아웃바운드 터널을 만드는 방식입니다.

    • 작동 방식: 홈서버의 cloudflared가 Cloudflare 에지 네트워크로 먼저 연결합니다. 외부 사용자가 your-service.example.com 같은 도메인으로 접속하면 Cloudflare가 해당 요청을 터널을 통해 홈서버 내부 서비스로 전달해요.
    • 주요 장점: 포트 포워딩이 필요 없고, 실제 공인 IP가 노출되지 않으며, SSL/TLS와 DDoS 보호를 Cloudflare 앞단에서 활용할 수 있습니다.
    • 2026년 기준 보완점: 예전에는 “특정 웹 서비스 공개” 느낌이 강했지만, 지금은 Cloudflare One Client(WARP)와 Tunnel CIDR 라우팅을 조합해 사설 IP 대역까지 연결하는 구성이 더 자연스러워졌습니다. 다만 이 경우에는 클라이언트 등록, Split Tunnel, Gateway 정책까지 같이 설계해야 합니다.

    VPN (Virtual Private Network, 가상 사설망)

    VPN은 이름 그대로 가상 사설망을 구축해서 외부 네트워크에서도 마치 집 안 네트워크에 있는 것처럼 접속하는 기술이에요. 홈랩에서는 여전히 WireGuard가 가장 가볍고 빠른 선택지로 많이 쓰이고, OpenVPN은 호환성이 좋은 편입니다.

    • 작동 방식: VPN 클라이언트가 VPN 서버로 암호화된 터널을 만들고, 클라이언트는 할당받은 내부 IP를 통해 NAS, Proxmox, Docker 서비스, 관리 페이지 등에 접근합니다.
    • 주요 장점: 네트워크 전체 접근이 쉽습니다. 특정 웹 서비스뿐 아니라 SSH, SMB, RDP, 내부 DNS 등 홈 네트워크 전체를 다뤄야 한다면 여전히 VPN이 편해요.
    • 주의할 점: VPN 서버 포트를 외부에 열어야 하는 경우가 많고, 인증키 관리, 방화벽, 라우팅, 업데이트를 꾸준히 챙겨야 합니다.

    ⚔️ Cloudflare Tunnel vs. VPN: 비용 효율성 및 주요 차이점 비교

    이제 두 기술의 가장 중요한 차이점, 그리고 홈랩 운영자의 입장에서 어떤 방식이 더 비용 효율적인지 비교해볼까요?

    기준 Cloudflare Tunnel VPN
    비용
    • 무료 플랜: 개인 홈서버, NAS 원격 접속, 소규모 홈랩에는 여전히 충분한 편입니다.
    • 팀 단위 Access, Gateway, 로그 보관, 고급 보안 정책이 필요하면 유료 플랜을 검토해야 합니다.
    • 홈서버에서 직접 운영하면 추가 서버 비용은 거의 없지만, 전기료와 유지보수 비용은 발생합니다.
    • 클라우드 VPS에 VPN을 두면 월별 요금이 붙습니다.
    설정 난이도
    • 웹 서비스 공개만 한다면 비교적 간단합니다.
    • 2026년 기준으로는 Cloudflare Zero Trust 대시보드에서 터널과 퍼블릭 호스트네임을 만드는 방식이 가장 편합니다.
    • WireGuard는 예전보다 쉬워졌지만, 라우팅과 방화벽을 이해해야 삽질이 줄어듭니다.
    • 공유기, DDNS, 포트 포워딩, 키 관리가 필요할 수 있습니다.
    보안 모델
    • 제로 트러스트: 서비스별 접근 정책, 이메일 OTP, MFA, IdP 연동을 붙이기 좋습니다.
    • 내부 포트를 직접 열지 않는 구조라 공격 표면을 줄이기 좋습니다.
    • 경계 기반 보안: VPN에 들어오면 내부망에 들어온 것과 비슷한 권한을 갖기 쉽습니다.
    • 키 유출, 취약한 VPN 서버, 과도한 내부 접근 권한을 조심해야 합니다.
    접속 범위
    • 웹 앱, SSH, RDP 같은 서비스 단위 공개에 강합니다.
    • WARP와 Tunnel CIDR 라우팅을 쓰면 사설 IP 대역 접근도 가능하지만, 설정은 단순 웹 공개보다 복잡합니다.
    • 네트워크 전체 접근이 가장 자연스럽습니다.
    • NAS 파일 공유, 내부 DNS, 여러 장비 관리에는 여전히 강합니다.
    성능
    • Cloudflare 에지 네트워크를 거치므로 웹 서비스에는 체감이 좋은 경우가 많습니다.
    • 대용량 파일 전송이나 실시간 내부망 작업은 구성에 따라 VPN이 더 단순하고 빠를 수 있습니다.
    • 성능은 집 인터넷 업로드 속도, VPN 서버 성능, 암호화 오버헤드에 좌우됩니다.
    • WireGuard는 대체로 가볍고 빠른 편입니다.
    추가 기능
    • Cloudflare Access, Gateway 정책, WAF, Turnstile, 로그, IdP 연동과 결합하기 좋습니다.
    • 원격 접속 자체에 집중합니다. 세밀한 사용자별 웹 접근 제어는 별도 솔루션이 필요할 수 있습니다.
    Cloudflare Tunnel과 VPN 기능 및 비용 효율성 비교 인포그래픽

    정리하자면, Cloudflare Tunnel은 웹 기반 홈서버 서비스, NAS 관리 페이지, 개인 대시보드, SSH 접속을 안전하게 노출하고 싶을 때 비용 효율이 좋습니다. 반면 VPN은 홈 네트워크 전체 접근, SMB 파일 공유, 내부 장비 관리, 모든 트래픽 암호화가 필요할 때 여전히 강력합니다.

    🛠️ Cloudflare Tunnel 실전 구축: 홈서버 원격 접속!

    이제 이론은 충분히 봤으니, 홈랩에 Cloudflare Tunnel을 구축하는 과정을 2026년 기준으로 정리해볼게요. 예전처럼 CLI만으로 만들 수도 있지만, 지금은 Cloudflare Zero Trust 대시보드에서 터널을 만들고 Connector 토큰으로 서버를 등록하는 방식이 가장 직관적입니다.

    1단계: Cloudflare 계정, 도메인, Zero Trust 조직 준비

    먼저 Cloudflare 계정을 만들고, 사용할 도메인을 Cloudflare DNS에 등록합니다. 그다음 Cloudflare 대시보드에서 Zero Trust 조직을 생성해야 해요. Free 플랜을 선택해도 결제 정보 입력 단계가 나올 수 있지만, 무료 플랜 자체는 개인 홈랩 테스트에 충분합니다.

    도메인은 꼭 비싼 걸 살 필요는 없고, NAS 원격 접속용으로 nas.example.com, home.example.com, ssh.example.com처럼 서브도메인을 나눠 쓰면 관리가 편합니다.

    2단계: cloudflared 설치 및 최신 버전 확인

    2026년 9월 기준 최신 cloudflared 릴리스는 2026.9.1입니다. 2026.8.0 계열에는 일부 HTTP origin 요청에서 trailing slash 처리 문제가 보고됐기 때문에, 가능하면 2026.8.2 이상 또는 최신 버전으로 올리는 걸 추천합니다.

    # 리눅스 AMD64 기준 cloudflared 설치 예시
    curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o /usr/local/bin/cloudflared
    chmod +x /usr/local/bin/cloudflared
    
    # 설치 확인
    cloudflared --version

    라즈베리 파이나 ARM 서버를 쓴다면 cloudflared-linux-arm64 또는 패키지 저장소 방식을 쓰는 게 좋습니다. 그리고 2027년부터는 32비트 Windows와 Intel 기반 macOS용 cloudflared 신규 빌드가 중단될 예정이라, 오래된 장비에 설치해둔 분들은 미리 ARM64, x86_64 Linux, Apple Silicon macOS 환경으로 옮길 계획을 세워두는 게 좋아요.

    3단계: 터널 생성 및 설정

    CLI로 직접 만드는 방식은 여전히 사용할 수 있습니다.

    # Cloudflare 계정 로그인
    cloudflared tunnel login
    
    # 터널 생성
    cloudflared tunnel create my-homelab-tunnel

    설정 파일은 보통 /etc/cloudflared/config.yaml에 둡니다.

    tunnel: [YOUR_TUNNEL_UUID]
    credentials-file: /root/.cloudflared/[YOUR_TUNNEL_UUID].json
    
    ingress:
      - hostname: your-service.your-domain.com
        service: http://localhost:8080
      - service: http_status:404

    요즘 제가 더 추천하는 방식은 Zero Trust 대시보드에서 Networks > Tunnels로 들어가 터널을 만들고, 안내되는 Connector 설치 명령을 서버에 붙여 넣는 방법입니다. 이 방식은 자격 증명 파일과 서비스 등록 과정이 덜 헷갈려요.

    4단계: DNS 레코드 설정

    CLI 방식이라면 다음 명령으로 CNAME 레코드를 만들 수 있습니다.

    cloudflared tunnel route dns my-homelab-tunnel your-service.your-domain.com

    대시보드 방식이라면 터널 설정의 Public Hostname에서 your-service.your-domain.com을 추가하고, 내부 서비스 주소를 http://localhost:8080처럼 입력하면 됩니다. 생성된 CNAME은 [YOUR_TUNNEL_UUID].cfargotunnel.com 형태이며, Cloudflare 프록시가 켜져 있어야 보안과 성능 이점을 제대로 활용할 수 있습니다.

    5단계: 터널 실행 및 서비스 등록

    CLI 방식에서는 다음처럼 systemd 서비스로 등록할 수 있습니다.

    sudo cloudflared tunnel service install
    sudo systemctl enable --now cloudflared
    sudo systemctl status cloudflared

    대시보드에서 만든 터널은 보통 아래처럼 토큰이 포함된 설치 명령을 제공합니다.

    sudo cloudflared service install [TOKEN]
    sudo systemctl status cloudflared

    systemctl status cloudflared에서 active (running) 상태가 보이면 1차 성공입니다. 이후 Cloudflare Zero Trust 대시보드에서도 터널 상태가 Healthy로 표시되는지 확인해보세요.

    Cloudflare Zero Trust 대시보드 터널 연결 성공 스크린샷

    ⚠️ 삽질 경험: Service Tunnel Error 해결하기

    제가 처음 Cloudflare Tunnel을 설정할 때 가장 많이 겪었던 오류 중 하나가 바로 Service Tunnel Error였어요. 터널은 생성됐는데, 실제 서비스가 안 열리는 답답한 상황이죠.

    1. config.yaml 파일 오류: YAML은 들여쓰기에 민감합니다. 탭 대신 스페이스를 쓰고, ingress 마지막에는 http_status:404 같은 기본 규칙을 넣어주세요.
    2. 잘못된 service 주소: http://localhost:8080으로 적었는데 실제 컨테이너가 다른 포트에서 떠 있거나, Docker 네트워크 때문에 localhost가 맞지 않는 경우가 많습니다.
    3. 내부 서비스 미실행: docker ps, systemctl status, ss -tulnp로 실제 서비스가 리스닝 중인지 확인하세요.
    4. 방화벽 문제: ufw, firewalld, NAS 자체 방화벽이 cloudflared의 내부 접근을 막을 수 있습니다.
    5. cloudflared 버전 문제: 특정 릴리스에서 회귀 버그가 생길 수 있으니, 이상 증상이 있으면 최신 안정 버전으로 올려보세요.
    6. 로그 확인: journalctl -u cloudflared --since '10 minutes ago' 또는 대시보드 Connector 로그를 보면 원인이 훨씬 빨리 보입니다.

    저도 “아, 이거 왜 안 되지?” 하면서 한참을 붙잡고 있다가 로그를 보니 내부 서비스 포트가 틀렸던 적이 있습니다. 결국 터널 문제처럼 보여도 절반은 origin 서비스 주소 문제더라고요.

    ✅ 검증 및 결과: 제로 트러스트 원격 접속의 편리함

    모든 설정을 마쳤다면 브라우저에서 your-service.your-domain.com으로 접속해보세요. 정상적으로 홈서버 서비스 화면이 뜨면 성공입니다.

    • 안전한 접속: 포트 포워딩 없이 실제 IP를 숨긴 채 홈서버에 접속할 수 있습니다.
    • Cloudflare 보호: HTTPS, DDoS 방어, 프록시 기반 보호를 쉽게 붙일 수 있습니다.
    • Zero Trust Access 연동: 이메일 OTP, MFA, Google Workspace, GitHub 같은 IdP 연동으로 사용자 인증을 추가할 수 있습니다.
    • NAS 원격 접속 최적화: Synology, TrueNAS, Unraid, Proxmox 대시보드처럼 웹 기반 관리 화면을 공개할 때 특히 편합니다.
    Cloudflare Tunnel을 통한 홈서버 웹 서비스 접속 화면

    🆕 2026년 9월 기준 새로 챙겨볼 변화

    원문 작성 이후 홈서버 원격 접속 쪽에서 체크할 만한 변화가 몇 가지 있었습니다.

    • cloudflared 최신 버전: 2026년 9월 기준 최신 릴리스는 2026.9.1입니다. 자동 업데이트나 정기 업데이트 루틴을 잡아두는 걸 추천합니다.
    • 오래된 클라이언트 지원 축소: 2027년부터 32비트 Windows와 Intel 기반 macOS용 신규 cloudflared 빌드가 중단될 예정입니다. 오래된 맥 미니나 구형 Windows 장비를 터널 서버로 쓰고 있다면 이전 계획이 필요합니다.
    • Private Network Routing 강화: Cloudflare Tunnel은 이제 단순 웹 앱 공개뿐 아니라 WARP 클라이언트와 Tunnel CIDR 라우팅을 통해 사설망 접근 시나리오에도 자주 쓰입니다. 전통적인 VPN 대체 구성이 더 현실적이 됐어요.
    • Access for Infrastructure: SSH 같은 인프라 접근을 사용자, 포트, 프로토콜 단위로 더 세밀하게 제어하는 기능도 계속 강화되고 있습니다. 홈랩에서도 SSH를 그냥 인터넷에 열어두는 방식은 이제 굳이 선택할 이유가 줄었습니다.
    • 보안 키워드 변화: 단순 “원격 접속”보다 Zero Trust NAS, Cloudflare WARP, 홈랩 보안, 포트포워딩 대체, self-hosted secure access 같은 관점으로 설계하는 흐름이 강해졌습니다.

    💡 마무리: 어떤 방식이 나에게 맞을까?

    결론은 꽤 명확합니다. 웹 기반 서비스 몇 개를 안전하게 공개하고 싶다면 Cloudflare Tunnel이 비용 효율과 관리 편의성 면에서 아주 좋습니다. NAS 관리 페이지, 개인 위키, 홈 대시보드, 개발용 웹앱, SSH 접근 정도라면 포트 포워딩 없이 깔끔하게 운영할 수 있어요.

    반대로 내부망 전체를 내 노트북으로 끌고 와야 한다면 VPN이 아직도 편합니다. SMB 파일 공유, 내부 DNS, 여러 장비의 관리 포트, 대용량 파일 작업이 많다면 WireGuard 기반 VPN이 더 단순할 수 있어요.

    개인적으로는 두 가지를 같이 씁니다. 평소 자주 쓰는 웹 서비스는 Cloudflare Tunnel로 열고, 내부망 전체 접근이 필요할 때만 WireGuard VPN을 켜는 식이죠. 홈서버 원격 접속은 하나만 고집하기보다, 서비스 성격에 맞게 나눠 쓰는 게 제일 편하더라고요.

    🔄 마지막 업데이트: 2026년 09월

  • [Nas] OpenMediaVault와 Immich 연동 사례: 나만의 프라이빗 사진 클라우드 구축

    [Nas] OpenMediaVault와 Immich 연동 사례: 나만의 프라이빗 사진 클라우드 구축

    OpenMediaVault와 Immich 연동 사례: 나만의 프라이빗 사진 클라우드 구축

    안녕하세요, 13년차 인프라 엔지니어 서버실입니다. 오늘은 많은 분들이 고민하시는 사진 관리 문제, 특히 프라이빗 클라우드 구축에 대한 이야기를 해볼까 합니다. 구글 포토의 정책 변경 이후, ‘내 사진을 내 손으로 관리하고 싶다!’는 열망이 더 커진 것 같아요. 저도 처음엔 클라우드 서비스가 편해서 잘 썼는데, 역시 데이터 주권(Data Sovereignty)은 중요하더라고요. 그래서 홈랩에서 직접 OpenMediaVault(OMV)와 Immich를 연동해서 저만의 프라이빗 사진 클라우드를 구축했습니다. 나스(NAS) 환경에서 사진을 자동으로 백업하고 관리할 수 있게 된 과정을 솔직하게 공유해 드릴게요.

    그림 1: OpenMediaVault 기반 Immich 프라이빗 사진 클라우드 아키텍처

    OpenMediaVault와 Immich, 왜 이 조합일까요?

    먼저, 이 두 친구가 어떤 역할을 하는지 간단히 짚어보고 갈까요? 쉽게 말해, OpenMediaVault(OMV)는 나스(NAS, Network Attached Storage)의 뼈대 역할을 하고, Immich는 그 위에 멋진 옷을 입혀주는 사진 관리 솔루션이라고 생각하시면 됩니다.

    • OpenMediaVault (OMV): 데비안(Debian) 리눅스 기반의 무료 오픈소스 NAS 운영체제입니다. 파일 공유(SMB/NFS), RAID 관리, 플러그인 확장성, 그리고 무엇보다 도커(Docker) 컨테이너 지원이 강력해서 홈랩에서 활용도가 정말 높아요. 튼튼한 스토리지 백엔드를 제공하는 셈이죠. 제가 직접 써보니 안정성도 뛰어나고 관리도 편하더라고요.

    • Immich: 요즘 뜨는 셀프 호스팅(Self-hosted) 사진 및 비디오 백업 솔루션입니다. 구글 포토와 비슷한 사용자 경험을 제공하면서, AI 기반 얼굴 인식(Facial Recognition), 객체 감지(Object Detection), 검색 기능, 타임라인(Timeline) 뷰, 공유 앨범 등 고급 기능까지 갖추고 있어요. 모바일 앱(iOS/Android)도 있어서 자동 백업도 가능합니다. 이 정도면 ‘나만의 구글 포토’라고 불러도 손색이 없죠.

    OMV가 안정적인 스토리지 공간을 제공하고, Immich가 그 공간에 저장된 사진들을 스마트하게 관리해주니, 이보다 더 좋은 조합이 있을까요? 👍

    OMV에 도커와 Immich 설치하기: 실전 구현

    이제 본격적으로 OMV 위에 Immich를 올려볼 차례입니다. OMV에 도커와 포테이너(Portainer)가 이미 설치되어 있다고 가정할게요. (아직 설치 안 하셨다면, OMV 웹 UI에서 OMV-Extras 플러그인을 통해 쉽게 설치할 수 있습니다.)

    1. Immich용 공유 폴더 생성

    먼저 OMV에서 Immich가 사진을 저장할 공유 폴더를 만들어야 합니다. 저는 /srv/dev-disk-by-uuid-XXXX/data/immich 경로에 immich라는 공유 폴더를 만들었어요. 여기서 정말 중요한 부분이 바로 권한 설정입니다. 도커 컨테이너 내부의 프로세스가 이 폴더에 접근하고 파일을 쓸 수 있도록 적절한 권한을 부여해야 하는데, 보통 PUID와 PGID를 사용합니다. 저는 1000:1000 (기본 사용자/그룹)으로 설정했습니다.

    2. Docker Compose 파일 준비

    Immich는 여러 서비스(PostgreSQL, Redis, Microservices 등)로 구성되어 있어서 도커 컴포즈(Docker Compose)로 한 번에 배포하는 게 가장 편리합니다. Immich 공식 GitHub 저장소에서 예시 docker-compose.yaml 파일을 가져오는 게 좋아요. 저는 항상 최신 버전을 확인하고 수정해서 사용합니다.

    # OMV SSH 접속 후 작업 디렉토리 생성
    mkdir -p /srv/dev-disk-by-uuid-XXXX/config/immich
    cd /srv/dev-disk-by-uuid-XXXX/config/immich
    
    # Immich GitHub에서 docker-compose.yaml 다운로드 (최신 버전 확인 필수)
    wget https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
    wget https://github.com/immich-app/immich/releases/latest/download/.env
    

    다운로드한 .env 파일과 docker-compose.yml 파일을 열어서 몇 가지를 수정해야 합니다.

    • .env 파일 수정:
      • UPLOAD_LOCATION=./upload 부분을 OMV에서 생성한 공유 폴더 경로로 변경합니다. 예: UPLOAD_LOCATION=/data/immich/upload (컨테이너 내부 경로)
      • DB_PASSWORD, REDIS_PASSWORD 등을 강력한 비밀번호로 변경하세요.
      • TZ=Asia/Seoul 처럼 시간대를 설정합니다.
    • docker-compose.yml 파일 수정:
      • 각 서비스의 volumes 섹션에서 OMV 공유 폴더와 연결되는 부분을 확인하고 수정합니다. 특히 ./upload:/usr/src/app/upload 부분을 /srv/dev-disk-by-uuid-XXXX/data/immich:/usr/src/app/upload (호스트 경로:컨테이너 내부 경로) 형태로 맞춰줘야 합니다.
      • PUID, PGID 환경 변수를 OMV에서 설정한 사용자/그룹 ID에 맞춰주세요.

    이 부분이 사실 제가 겪었던 가장 큰 삽질의 핵심이었습니다. 😅 볼륨 마운트 경로를 잘못 지정하거나 권한이 없어서 컨테이너가 파일을 못 읽는 경우가 정말 많거든요. 항상 호스트 경로와 컨테이너 내부 경로가 정확히 매핑되는지, 그리고 해당 호스트 폴더에 컨테이너가 접근할 수 있는 권한이 있는지 꼼꼼히 확인해야 합니다.

    Immich Docker Compose 설정 파일 예시 (볼륨 및 환경 변수)

    그림 2: Immich Docker Compose 설정 파일 예시 (볼륨 및 환경 변수)

    3. Immich 서비스 실행

    파일 수정이 끝났다면, 이제 도커 컴포즈를 이용해 서비스를 실행합니다. OMV SSH 터미널에서 docker-compose.yml 파일이 있는 디렉토리로 이동한 다음 아래 명령어를 실행하세요.

    docker compose up -d
    

    -d 옵션은 백그라운드에서 컨테이너를 실행하라는 의미입니다. 컨테이너들이 모두 정상적으로 올라오는지 docker compose ps 명령어로 확인해볼 수 있습니다.

    ⚠️ 주의사항 및 트러블슈팅: 제가 겪은 삽질들

    제가 이 OpenMediaVault와 Immich 연동 구성을 하면서 가장 많이 겪었던 문제들은 역시 권한(Permissions)과 볼륨 마운트(Volume Mount)였습니다. 특히 OMV의 공유 폴더와 도커 컨테이너 간의 권한 문제가 많았어요. 홈랩에서 사진 백업을 구축할 때 이 부분을 간과하면 정말 답답하더라고요.

    1. 권한 문제 (Permission Denied): Immich 컨테이너가 OMV 공유 폴더에 사진을 저장하거나 데이터베이스 파일을 생성할 때 ‘Permission Denied’ 에러가 발생하는 경우가 많았습니다. 이럴 때는 OMV에서 해당 공유 폴더의 ACL(Access Control List) 설정을 확인하거나, SSH로 접속해서 직접 chown 명령어로 소유권을 변경해줘야 합니다. 예를 들어, sudo chown -R 1000:1000 /srv/dev-disk-by-uuid-XXXX/data/immich 이런 식으로요. PUID, PGID 값과 일치시켜주는 게 정말 중요합니다.

    2. 리소스 부족 (Resource Exhaustion): Immich는 생각보다 많은 리소스를 사용합니다. 특히 처음 사진을 인덱싱(Indexing)하고 AI 기능을 사용할 때 CPU와 RAM 사용량이 급증할 수 있어요. 저사양 NAS나 라즈베리 파이(Raspberry Pi) 같은 장비에선 버벅거릴 수 있습니다. 저는 N100 기반 미니 PC에 16GB RAM을 사용하는데, 이 정도면 충분하더라고요. 나스 환경의 사양을 고려해서 구축해야 합니다.

    3. 포트 충돌 (Port Conflict): 만약 OMV에서 다른 서비스가 Immich와 동일한 포트(기본 2283)를 사용하고 있다면 충돌이 발생할 수 있습니다. docker-compose.yml 파일에서 Immich 서버의 포트를 다른 번호로 변경해주거나, 기존 서비스의 포트를 변경해야 합니다.

    이런 문제들을 하나씩 해결해나가면서 ‘아, 역시 인프라 엔지니어는 삽질의 연속이구나’ 싶었지만, 각각을 해결할 때마다 느껴지는 성취감이 있었어요. 💡

    설치 검증 및 결과 확인 🎉

    모든 컨테이너가 정상적으로 실행되면, 웹 브라우저를 열고 http://[OMV_IP_주소]:2283으로 접속하면 됩니다. 처음 접속하면 관리자 계정을 생성하라는 화면이 나올 거예요. 계정을 만들고 로그인하면 드디어 Immich의 멋진 인터페이스를 만날 수 있습니다!

    모바일 앱을 설치해서 OMV 서버의 IP 주소와 포트를 입력하면 스마트폰 사진을 자동으로 백업할 수 있어요. 실제로 제가 갤러리 앱에서 사진 몇 장을 찍어보니 Immich 웹 UI에 바로바로 동기화되더라고요. 정말 신기하고 뿌듯했습니다. 🤩

    Immich 웹 UI 메인 화면 (사진 업로드 및 타임라인)

    그림 3: Immich 웹 UI (사진 업로드 및 타임라인)

    가족 사진, 여행 사진, 친구들과의 추억까지! 이제 모두 제 OMV 나스에 안전하게 보관되고, Immich의 강력한 기능으로 편리하게 관리할 수 있게 되었습니다. 프라이버시(Privacy) 걱정 없이, 원하는 만큼의 용량을 마음껏 쓸 수 있다는 점이 가장 큰 장점 같아요.

    마무리하며: 나만의 사진 클라우드, 그 다음은?

    OpenMediaVault와 Immich를 연동해서 나만의 프라이빗 사진 클라우드를 구축하는 과정, 어떠셨나요? 처음에는 조금 복잡하게 느껴질 수도 있지만, 한 번 구축해두면 정말 든든한 나만의 사진 보관소가 생기는 겁니다. 데이터 주권을 되찾고, 클라우드 서비스 구독료도 절약할 수 있으니 일석이조죠.

    저는 여기서 멈추지 않고, Nginx Proxy Manager 같은 리버스 프록시(Reverse Proxy)를 이용해 외부에서도 안전하게 접속할 수 있도록 설정할 계획입니다. 또, 백업 전략(Backup Strategy)도 빠뜨리지 않고 구현해야 하겠더라고요. Raid는 백업이 아니라는 점, 다들 아시죠? 😉

    여러분도 제 경험을 바탕으로 나만의 프라이빗 사진 클라우드 구축에 도전해 보시길 강력히 추천합니다. 궁금한 점이 있으시다면 언제든지 댓글로 남겨주세요! 다음에는 Nginx Proxy Manager를 활용한 외부 접속 설정에 대해 다뤄볼까 합니다. 기대해주세요!

    OMV와 Immich 연동의 주요 장점 요약 인포그래픽

    그림 4: OMV + Immich 연동의 주요 장점

  • [Nas] Nextcloud S3 호환 스토리지 연동 사례: 대용량 클라우드 확장 전략

    [Nas] Nextcloud S3 호환 스토리지 연동 사례: 대용량 클라우드 확장 전략

    Nextcloud S3 호환 스토리지 연동 사례: 대용량 클라우드 확장 전략

    안녕하세요, 13년차 서버실 블로그의 운영자입니다. 어느덧 13년이라는 시간 동안 수많은 서버실과 씨름하며 인프라의 최전선에서 땀 흘렸던 경험을 여러분과 나누고 있습니다. 오늘은 개인적으로도, 그리고 많은 기업에서도 겪을 수 있는 ‘스토리지 용량 압박’ 문제에 대한 현실적인 해결책, 바로 Nextcloud와 S3 호환 스토리지 연동에 대한 이야기를 해볼까 합니다. 홈랩을 운영하며 다양한 시도를 해왔는데, 이 부분이 정말 꿀팁이 될 것 같아 준비했습니다.

    많은 분들이 Nextcloud를 사용하시면서 ‘아, 용량이 부족한데?’라는 고민을 한 번쯤은 해보셨을 겁니다. 특히 사진, 동영상 같은 미디어 파일이나 백업 데이터를 쌓아두다 보면 금방 한계에 부딪히곤 하죠. 그렇다고 매번 스토리지 용량을 늘리는 건 비용 부담도 만만치 않고, 관리도 번거롭습니다. 이럴 때 등장하는 것이 바로 오브젝트 스토리지(Object Storage)거든요. 쉽게 말해, 파일 단위로 저장하는 NAS나 SAN과 달리, 데이터를 ‘객체(Object)’ 단위로 저장하고 관리하는 방식이에요. 훨씬 유연하고 확장성이 뛰어나 대용량 데이터 처리에 특화되어 있습니다. 그리고 이 오브젝트 스토리지를 Nextcloud와 연결할 수 있다면? 상상만 해도 든든하지 않나요? 오늘은 바로 이 Nextcloud S3 스토리지 연동에 대한 실제 경험을 공유하며, 여러분의 클라우드 스토리지 확장 전략에 대한 인사이트를 드리고자 합니다. MinIO 같은 S3 호환 스토리지를 활용하는 방법을 중심으로 설명드릴게요. S3 호환 스토리지는 AWS S3와 API 호환이 되기 때문에, AWS S3를 직접 사용하지 않더라도 비슷한 방식으로 연동이 가능합니다.

    Nextcloud와 S3 호환 스토리지 연동 아키텍처 개요

    Nextcloud와 S3 호환 스토리지 연동 아키텍처 개요

    1. 왜 S3 호환 스토리지를 Nextcloud에 연동해야 할까요?

    제가 13년간 인프라 엔지니어로 일하면서 가장 많이 들었던 질문 중 하나가 바로 ‘스토리지 확장’에 관한 것이었어요. 특히 Nextcloud 같은 프라이빗 클라우드 솔루션을 사용하다 보면, 사용자 수가 늘어나거나 데이터 사용량이 폭증할 때 스토리지 용량 증설은 피할 수 없는 숙제죠. 기존에 Nextcloud 데이터를 저장하던 로컬 디스크나 NAS의 용량을 늘리는 것은 다음과 같은 단점들이 있습니다.

    • 비용 증가: 고용량 디스크나 NAS 장비를 추가 구매해야 하므로 초기 비용이 많이 들어요.
    • 확장성 제한: 물리적인 공간이나 장비의 한계로 인해 무한정 확장이 어렵습니다.
    • 관리 복잡성: 디스크 추가, RAID 구성 변경 등 관리 작업이 복잡해질 수 있죠.
    • 데이터 관리 비효율: 대용량 데이터를 효율적으로 관리하고 접근하는 데 한계가 있어요.

    이런 문제들을 해결하기 위해 오브젝트 스토리지가 대안으로 떠오르고 있습니다. 오브젝트 스토리지는 데이터를 객체(Object)라는 단위로 저장하며, 각 객체는 고유한 ID와 메타데이터를 가져요. 이러한 구조 덕분에 다음과 같은 장점을 가지게 되는 거죠:

    • 뛰어난 확장성: 사실상 무한대에 가까운 용량 확장이 가능합니다.
    • 비용 효율성: 사용한 만큼만 비용을 지불하는 종량제 방식이 많아서 효율적이에요.
    • 데이터 내구성 및 가용성: 여러 복제본을 저장하여 데이터 손실 위험을 줄이고 안정적인 서비스 제공이 가능해요.
    • 다양한 접근 방식: S3 API 등을 통해 다양한 애플리케이션과 쉽게 연동할 수 있습니다.

    특히 S3 호환 스토리지는 AWS S3와 동일한 API를 사용하기 때문에, AWS S3를 네이티브로 사용하지 않더라도 S3 API를 지원하는 다양한 스토리지 솔루션(예: MinIO, Ceph RGW 등)을 Nextcloud와 연동할 수 있다는 큰 장점이 있어요. 즉, 자체적으로 구축한 오브젝트 스토리지 시스템을 Nextcloud의 백엔드 스토리지로 활용하여 대용량 데이터를 저렴하고 효율적으로 관리할 수 있게 되는 거죠. 제가 홈랩에서 MinIO를 직접 구축하고 Nextcloud와 연동했던 경험을 바탕으로, 이 부분이 왜 매력적인지 더 자세히 설명해 드릴게요.

    2. S3 호환 스토리지란 무엇일까요? (쉽게 말해~)

    자, 여기서 ‘S3 호환 스토리지’라는 말이 조금 어렵게 느껴지실 수도 있어요. 쉽게 풀어 설명해 드릴게요. S3는 Amazon Web Services(AWS)에서 제공하는 오브젝트 스토리지 서비스의 이름이에요. 워낙 많이 사용되고 표준처럼 자리 잡았기 때문에, 많은 스토리지 솔루션들이 AWS S3의 작동 방식과 API를 그대로 따라 만들고 있습니다. 이걸 바로 ‘S3 호환’이라고 부르는 거죠.

    그러니까, S3 호환 스토리지는:

    • AWS S3처럼 데이터를 객체(Object) 단위로 저장하고 관리하는 스토리지입니다.
    • AWS S3와 동일한 API(Application Programming Interface)를 사용해서 데이터를 읽고 쓸 수 있어요.
    • AWS S3가 아닌, 자체적으로 구축하거나 다른 벤더에서 제공하는 스토리지입니다. (예: MinIO, Ceph Rados Gateway, Cloudian 등)

    이게 왜 중요하냐면요, Nextcloud는 기본적으로 로컬 파일 시스템이나 SMB/NFS 같은 네트워크 파일 시스템을 스토리지로 사용하도록 설계되었거든요. 하지만 Nextcloud의 ‘External Storage’ 기능을 활용하면, S3 API를 지원하는 다양한 외부 스토리지 시스템을 마치 Nextcloud 자체 스토리지처럼 사용할 수 있게 되는 거예요. 특히 MinIO 같은 S3 호환 스토리지를 사용하면, 오픈 소스로 구축 가능하면서도 뛰어난 성능과 확장성을 가진 오브젝트 스토리지를 Nextcloud와 연동할 수 있다는 강력한 이점이 생기죠. 제가 직접 MinIO를 설치하고 Nextcloud와 연동하면서 느낀 점은, 마치 AWS S3를 우리 회사 데이터센터에 그대로 옮겨온 듯한 느낌이었어요. 처음엔 이게 가능할까 싶었는데, 실제로 되더라고요!

    3. MinIO 설치 및 기본 설정 (홈랩에서 직접 해보니)

    자, 이제 본격적으로 S3 호환 스토리지의 대표 주자 중 하나인 MinIO를 설치하고 기본 설정을 해보겠습니다. 저는 제 홈랩 환경에서 Docker를 활용하여 MinIO를 설치했는데요, 이게 가장 간편하고 빠르게 테스트해 볼 수 있는 방법이더라고요. 여러분도 비슷한 환경이라면 이 방법을 추천합니다.

    1단계: Docker 및 Docker Compose 설치

    아직 Docker가 설치되어 있지 않다면, 운영체제에 맞게 설치해주세요. 저는 Ubuntu 기준의 명령어를 보여드릴게요.

    sudo apt update
    sudo apt install docker.io docker-compose -y
    
    sudo systemctl start docker
    sudo systemctl enable docker
    

    2단계: MinIO Docker Compose 파일 작성

    프로젝트 디렉토리를 만들고, 그 안에 docker-compose.yml 파일을 생성합니다. 아래는 제가 사용했던 예시 설정이에요. 실제 운영 환경에서는 보안을 위해 볼륨 경로, 비밀번호 등을 더욱 신중하게 설정해야 한다는 점은 꼭 기억해두세요.

    version: '3.7'
    
    services:
      minio:
        image: minio/minio:latest
        container_name: minio
        restart: always
        ports:
          - "9000:9000" # API 포트
          - "9001:9001" # Console 포트
        volumes:
          - minio_data:/data # MinIO 데이터 저장 경로
        environment:
          MINIO_ROOT_USER: "admin"
          MINIO_ROOT_PASSWORD: "password123"
        command: server /data --console-address ":9001"
    
    volumes:
      minio_data:
    

    여기서 중요한 것은 MINIO_ROOT_USER와 MINIO_ROOT_PASSWORD입니다. 이 정보는 나중에 Nextcloud에서 MinIO에 접속할 때 사용되니 잘 기억해두셔야 해요. 저는 테스트를 위해 간단하게 설정했지만, 실제 환경에서는 복잡하고 안전한 비밀번호를 사용하시는 것을 강력히 권장합니다.

    3단계: MinIO 컨테이너 실행

    작성한 docker-compose.yml 파일이 있는 디렉토리에서 다음 명령어를 실행합니다.

    docker-compose up -d
    

    이제 Docker 컨테이너가 백그라운드에서 실행될 거예요. docker ps 명령어로 잘 실행되고 있는지 확인해보세요.

    4단계: MinIO Console 접속 및 버킷 생성

    웹 브라우저를 열고 http://{여러분의 서버 IP}:9001로 접속해보세요. 아까 설정한 ID(admin)와 비밀번호(password123)로 로그인할 수 있습니다. 로그인 후, Nextcloud에서 사용할 버킷(Bucket)을 하나 생성해줍니다. 버킷은 데이터를 담는 컨테이너라고 생각하시면 돼요. 저는 nextcloud-storage라는 이름으로 버킷을 생성했습니다.

    MinIO 웹 콘솔에서 'nextcloud-storage' 버킷 생성 화면

    MinIO 웹 콘솔에서 ‘nextcloud-storage’ 버킷 생성

    4. Nextcloud와 MinIO 연동 설정 (진짜 핵심!)

    이제 가장 중요한 단계입니다. Nextcloud에서 외부 스토리지를 설정하여 방금 만든 MinIO 버킷을 연결하는 과정이에요. 이 설정이 제대로 되어야 Nextcloud의 파일들이 MinIO에 저장되게 됩니다.

    1단계: Nextcloud 관리자 페이지 접속

    Nextcloud 관리자 페이지(Admin Dashboard)에 접속합니다.

    2단계: 외부 스토리지 설정 메뉴 이동

    좌측 메뉴에서 관리(Administration) > 스토리지(Storage)로 이동합니다. 여기서 외부 스토리지(External Storage) 섹션을 찾으세요.

    3단계: 새 외부 스토리지 추가

    ‘+ 외부 스토리지를 추가합니다(Add storage)’ 버튼을 클릭하고, 드롭다운 메뉴에서 ‘Amazon S3’를 선택합니다. MinIO가 S3 API를 호환하기 때문에 Amazon S3를 선택하면 돼요.

    4단계: S3 연결 정보 입력

    이제 MinIO에 연결하기 위한 정보를 입력하는 화면이 나옵니다. 여기서 각 항목을 정확히 입력하는 것이 매우 중요해요. 제가 직접 해보면서 헷갈렸던 부분들을 위주로 설명드릴게요.

    • 연결 이름(Connection name): Nextcloud에서 표시될 스토리지의 이름입니다. 알아보기 쉽게 MinIO Storage 등으로 입력하세요.
    • 호스트(Hostname): MinIO 서버의 주소입니다. Docker로 설치했다면 컨테이너 이름이나 IP 주소를 입력합니다. 저는 minio (Docker Compose 네트워크 내 호스트명) 또는 192.168.1.100 (MinIO 서버 실제 IP) 같이 입력했어요.
    • 포트(Port): MinIO API가 사용하는 포트입니다. 기본값은 9000이에요.
    • 지역(Region): MinIO는 지역 개념이 필수는 아니지만, 필수로 입력해야 하는 경우 아무 값이나 입력해도 돼요. (예: us-east-1)
    • 액세스 키 ID(Access Key ID): MinIO에 설정했던 MINIO_ROOT_USER 값을 입력합니다. (저는 admin)
    • 시크릿 액세스 키(Secret Access Key): MinIO에 설정했던 MINIO_ROOT_PASSWORD 값을 입력합니다. (저는 password123)
    • 버킷 이름(Bucket Name): MinIO에서 생성했던 버킷 이름을 정확히 입력합니다. (저는 nextcloud-storage)
    • SSL/TLS 사용(Enable SSL): MinIO를 HTTPS로 설정했다면 체크합니다. 저는 내부망에서 테스트했기에 체크하지 않았어요.

    모든 정보를 정확히 입력했다면, 우측 상단의 ‘연결 설정(Configure connection)’ 버튼을 클릭합니다. 잠시 후, 연결이 성공하면 초록색 체크 표시가 나타날 거예요. 만약 연결 실패 메시지가 뜬다면, 호스트네임, 포트, Access Key, Secret Access Key, 버킷 이름 등을 다시 한번 꼼꼼히 확인해보세요. 방화벽 설정도 확인해야 할 수 있어요.

    5단계: 마운트 옵션 설정

    연결이 성공하면, 이제 이 외부 스토리지를 Nextcloud의 어느 위치에 마운트할지 설정해야 합니다. ‘마운트(Mount)’ 항목에 원하는 경로를 입력하세요. 예를 들어, /minio-storage와 같이 입력하면, Nextcloud의 파일 목록에 minio-storage라는 폴더가 생기고, 그 안에 MinIO 버킷의 모든 파일이 보이게 돼요.

    6단계: ‘폴더 사용(Use folder)’ 클릭

    모든 설정이 완료되면, 입력한 경로 옆의 ‘폴더 사용(Use folder)’ 버튼을 클릭하여 설정을 확정합니다.

    이제 Nextcloud의 파일 목록으로 돌아가면, 방금 설정한 경로(예: /minio-storage)에 MinIO 버킷의 내용이 나타나는 것을 확인할 수 있어요. Nextcloud와 MinIO 연동이 성공한 거죠!

    Nextcloud 외부 스토리지 설정 화면: S3 연결 정보 입력

    5. 실제 사용 및 성능 검증

    자, 이제 Nextcloud와 MinIO가 성공적으로 연동되었어요! 그럼 실제 사용은 어떨까요? 제가 겪었던 몇 가지 경험과 주의사항을 공유해 드릴게요. 처음에는 ‘이야, 이제 용량 걱정 없겠다!’하고 신나서 이것저것 많이 올려봤어요. 사진, 동영상, 백업 파일 등등… 용량이 정말 순식간에 늘어나더라고요. MinIO 스토리지 자체는 워낙 확장성이 좋으니 문제가 없었지만, Nextcloud의 파일 접근 속도나 동기화 성능에서 약간의 아쉬움이 느껴질 때도 있었어요.

    초기에 느낀 점은 Nextcloud의 기본 설정 그대로 사용했더니, 대용량 파일 업로드/다운로드 시 응답 속도가 조금 느리게 느껴진다는 거였어요. 특히 동기화 클라이언트에서 파일을 불러올 때 딜레이가 있더라고요. 이 문제를 해결하기 위해 Nextcloud와 MinIO의 여러 설정을 조정해봤습니다.

    • Nextcloud 설정 최적화: Nextcloud의 config.php 파일을 조정하여 캐싱 설정을 변경하거나, memory_limit 같은 PHP 설정을 늘려주는 것이 도움이 되었어요. 또한, Nextcloud의 External Storage 설정에서 ‘Enable preview’ 옵션을 끄거나, ‘Background jobs’를 Cron으로 설정하는 등 최적화 작업을 진행했습니다.
    • MinIO 성능 튜닝: MinIO 자체의 성능을 높이기 위해, 더 빠른 디스크를 사용하거나, MinIO 서버의 CPU/메모리 자원을 충분히 확보하는 것도 중요했어요. 또한, Nextcloud에서 MinIO로 접근할 때 사용하는 네트워크 대역폭도 충분해야 했습니다.
    • 버킷 및 객체 관리: MinIO의 버킷 설정을 통해 라이프사이클 정책(Lifecycle Policies)을 설정하여 오래된 데이터를 자동으로 삭제하거나 아카이빙하는 것도 용량 관리에 큰 도움이 되었어요.

    이런 최적화 작업을 거치면서, 대용량 파일도 훨씬 빠르고 안정적으로 주고받을 수 있게 되었습니다. 특히 Home Assistant 같은 다른 서비스의 백업 데이터를 MinIO에 직접 저장하고, Nextcloud를 통해 접근하도록 구성했을 때, 용량 관리와 접근성이 동시에 해결되는 것을 보며 ‘이거 진짜 물건이다’ 싶었어요. Nextcloud의 ‘External Storage’에서 ‘Enable sharing’ 옵션을 끄면, 외부 스토리지에 저장된 파일의 공유 기능을 비활성화하여 보안을 강화할 수 있다는 팁도 알게 됐어요.

    검증 결과:

    • 용량 확장성: 무한대에 가까운 용량 확보 ✓
    • 데이터 접근 속도: 최적화 후 만족스러운 수준 달성 ✓
    • 안정성: MinIO의 자체 내구성 기능 활용으로 안정성 확보 ✓
    • 비용 효율성: 자체 구축으로 AWS S3 대비 비용 절감 효과 ✓

    Nextcloud 파일 목록: MinIO에 저장된 파일 확인

    6. 마치며: 더 넓은 클라우드 공간을 향해

    오늘 우리는 Nextcloud와 S3 호환 스토리지 (MinIO) 연동을 통해 대용량 클라우드 스토리지 확장 전략을 살펴봤습니다. 처음에는 다소 복잡하게 느껴질 수 있지만, 한번 제대로 구축해두면 그 어떤 방법보다 유연하고 확장성이 뛰어나며 비용 효율적인 스토리지 환경을 만들 수 있다는 걸 직접 경험했어요. 특히 개인 홈랩을 운영하는 분들이나, 자체적인 프라이빗 클라우드 환경을 구축하려는 기업에게는 정말 매력적인 솔루션이라고 생각해요.

    제가 겪었던 여러 경험들이 여러분의 시행착오를 줄이는 데 조금이나마 도움이 되었으면 좋겠습니다. 이 과정을 통해 단순히 용량을 늘리는 것을 넘어, 데이터를 더욱 효율적으로 관리하고 접근하는 방법에 대한 인사이트를 얻으셨기를 바래요.

    앞으로도 저는 13년차 인프라 엔지니어의 경험을 바탕으로, 여러분의 IT 환경 구축과 운영에 실질적인 도움이 될 수 있는 꿀팁들을 계속해서 공유할 예정입니다. 혹시 Nextcloud나 오브젝트 스토리지에 대해 더 궁금한 점이 있다면 언제든지 댓글로 남겨주세요! 함께 이야기 나누고 해결해나가면 좋겠어요. 다음 글에서는 아마도 이 스토리지 환경을 활용한 백업 전략이나, 보안 강화 방법에 대해 다루게 될 것 같네요. 기대해주세요!

    Nextcloud S3 스토리지 연동: 클라우드 확장 전략 요약

  • [NAS] OMV와 Immich 연동: 구글 포토 대안, 실제 구축 가이드

    [NAS] OMV와 Immich 연동: 구글 포토 대안, 실제 구축 가이드

    [NAS] OMV와 Immich 연동: 구글 포토 대안, 실제 구축 가이드

    안녕하세요, 13년차 서버실 지킴이입니다. 오늘은 많은 분들이 고민하시는 구글 포토(Google Photos) 대안에 대한 이야기를 해볼까 합니다. 특히 저처럼 홈랩(Homelab)을 운영하며 데이터 주권에 관심이 많으신 분들이라면 더욱 공감하실 거예요.

    아마 많은 분들이 구글 포토의 편리함 때문에 사진 백업에 사용하셨을 겁니다. 저도 그랬거든요. 그런데 정책이 바뀌면서 무료 용량이 제한되고, 내 소중한 사진들이 과연 안전하게 잘 관리되고 있는 건지, 상업적으로 활용될 여지는 없는지 같은 걱정들이 스멀스멀 올라오더라고요. 그래서 “내 손으로 직접 내 사진을 관리하자!”는 생각으로 자가 호스팅(Self-hosting) 사진 갤러리 구축을 결심했습니다. 그리고 그 해답은 바로 OpenMediaVault(OMV)와 Immich의 조합이었습니다.

    처음엔 이게 뭔가 싶었는데, 막상 해보니 꽤나 만족스러웠습니다. 물론 삽질 좀 했지만요. ㅎㅎ 오늘은 제가 직접 OMV에 Immich를 연동해서 구글 포토 대안을 구축한 실제 사례와 함께, 삽질하며 얻은 팁들을 솔직하게 공유해 드릴게요. 혹시 이런 경험 있으신가요? 지금부터 저와 함께 나만의 NAS 사진 동기화 솔루션을 만들어 봅시다!

    홈랩 환경에서 OMV와 Immich가 어떻게 연동되어 사진을 관리하는지 보여주는 간략한 아키텍처입니다.

    1. 왜 OMV와 Immich 조합일까요?

    먼저 핵심 개념부터 쉽게 풀어볼까요? 💡

    • OpenMediaVault (OMV): OMV는 NAS(Network Attached Storage) 운영체제입니다. 쉽게 말해, 집에 남는 PC나 라즈베리 파이 같은 장치에 설치하면 그걸 훌륭한 나스 서버로 바꿔주는 소프트웨어예요. 안정적이고 다양한 플러그인을 지원하며, 특히 Docker(도커)를 공식적으로 지원해서 컨테이너 기반의 애플리케이션들을 쉽게 올릴 수 있다는 큰 장점이 있습니다.

    • Immich: Immich는 자가 호스팅(Self-hosted) 사진 및 비디오 백업 솔루션입니다. 구글 포토와 거의 흡사한 기능을 제공하는데, 내 서버 위에서 돌아간다는 게 가장 큰 차이점이죠. 모바일 앱으로 자동 백업, 얼굴 인식, 객체 인식, 검색, 타임라인 뷰 등 편리한 기능들이 많아서 “이거 진짜 물건이네!” 싶더라고요. 활발하게 개발되고 있으며, 이미 실사용에 충분히 안정화되어 있습니다.

    제가 이 둘을 선택한 이유는 명확합니다. OMV의 안정적인 NAS 환경 위에 Docker로 Immich를 올리면, 내 데이터는 내 서버에 안전하게 보관하면서도 구글 포토 못지않은 편리함을 누릴 수 있기 때문이죠. 데이터 주권(Data Sovereignty)을 확보하는 동시에, 비용 부담 없이 대용량 사진 갤러리를 운영할 수 있다는 게 가장 큰 매력이었습니다.

    2. OMV에 Docker와 Immich 설치하기: 실전 구현

    자, 그럼 이제 본격적으로 구축 과정을 살펴볼까요? OMV에 Docker를 설치하는 방법은 다양하지만, 저는 Portainer(포테이너)를 활용하는 것을 추천합니다. 웹 UI로 Docker 컨테이너를 관리하기가 훨씬 편하거든요.

    2.1. OMV에 Docker 및 Portainer 설치

    1. OMV 웹 UI에 접속해서 ‘시스템’ > ‘플러그인’ 메뉴로 이동합니다.

    2. openmediavault-omvextrasorg 플러그인을 설치합니다. 이 플러그인이 Docker 설치를 위한 저장소를 추가해 줍니다.

    3. 플러그인 설치 후, ‘OMV-Extras’ > ‘Docker’ 탭으로 이동해서 ‘Docker 설치’ 버튼을 클릭합니다. 잠시 기다리면 Docker가 설치될 겁니다.

    4. 이어서 ‘Portainer 설치’ 버튼을 클릭하면 Portainer 컨테이너도 함께 설치됩니다. 설치가 완료되면 OMV IP 주소:9000으로 접속해서 Portainer 웹 UI를 확인할 수 있습니다. 🎉

    2.2. Immich용 Docker Compose 파일 작성

    Portainer에 접속했다면, 이제 Immich를 배포할 차례입니다. Immich는 여러 개의 컨테이너로 구성되어 있어서 Docker Compose를 사용하는 게 일반적이에요. Portainer에서 ‘Stacks’ 메뉴로 가서 ‘Add stack’을 클릭하고, 아래와 같이 docker-compose.yml 파일을 작성해 주세요.

    ⚠️ 중요: 볼륨 경로와 환경 변수는 본인의 OMV 환경에 맞게 반드시 수정해야 합니다.

    Portainer에서 Immich Docker Compose 스택 설정 화면

    Portainer에서 Immich 스택을 생성할 때 사용하는 Docker Compose 파일 예시입니다.

    version: '3.8'
    
    services:
      immich-server:
        container_name: immich_server
        image: ghcr.io/immich-app/immich-server:release
        command: ['start.sh', 'immich']
        volumes:
          - /srv/dev-disk-by-uuid-YOUR_DISK_UUID/data/immich/upload:/usr/src/app/upload # OMV 공유 폴더 경로로 변경
          - /etc/localtime:/etc/localtime:ro
        env_file:
          - .env
        ports:
          - 2283:3001 # Immich 웹 UI 포트
        depends_on:
          - immich-redis
          - immich-database
        restart: always
    
      immich-microservices:
        container_name: immich_microservices
        image: ghcr.io/immich-app/immich-microservices:release
        command: ['start.sh', 'microservices']
        volumes:
          - /srv/dev-disk-by-uuid-YOUR_DISK_UUID/data/immich/upload:/usr/src/app/upload # OMV 공유 폴더 경로로 변경
          - /etc/localtime:/etc/localtime:ro
        env_file:
          - .env
        depends_on:
          - immich-redis
          - immich-database
        restart: always
    
      immich-web:
        container_name: immich_web
        image: ghcr.io/immich-app/immich-web:release
        command: ['start.sh', 'web']
        env_file:
          - .env
        ports:
          - 2284:3000 # Immich 웹 UI 포트 (Reverse Proxy 사용 시 변경 가능)
        restart: always
    
      immich-redis:
        container_name: immich_redis
        image: redis:7.2-alpine@sha256:98f5a8ee0f30e0f99bc3f4f7ba05e3c58c72331f965f858a3bc5fa8e8e4f13d8 # 최신 권장 버전
        restart: always
    
      immich-database:
        container_name: immich_database
        image: postgres:15-alpine@sha256:0ea5f42eab7ac1c03c87b7b75fcace28ebaa1f6abcff02ef9ef2999b3f06c36e # 최신 권장 버전
        environment:
          POSTGRES_USER: immich # 변경 가능
          POSTGRES_PASSWORD: your_strong_password # **매우 중요: 강력한 비밀번호로 변경하세요!**
          POSTGRES_DB: immich # 변경 가능
        volumes:
          - /srv/dev-disk-by-uuid-YOUR_DISK_UUID/data/immich/database:/var/lib/postgresql/data # OMV 공유 폴더 경로로 변경
        restart: always
    
      immich-proxy:
        container_name: immich_proxy
        image: ghcr.io/immich-app/immich-proxy:release
        ports:
          - 2285:8080 # Immich 외부 접근 포트 (Reverse Proxy 사용 시 변경 가능)
        environment:
          IMMICH_SERVER_URL: http://immich-server:3001
          IMMICH_WEB_URL: http://immich-web:3000
        depends_on:
          - immich-server
          - immich-web
        restart: always
    

    💡 팁: OMV에서 /srv/dev-disk-by-uuid-YOUR_DISK_UUID 경로는 실제 디스크의 UUID 기반 경로입니다. ‘스토리지’ > ‘파일 시스템’에서 확인하거나, ‘스토리지’ > ‘공유 폴더’를 만들고 해당 폴더의 실제 경로를 확인하여 사용하세요. 저는 /srv/dev-disk-by-uuid-YOUR_DISK_UUID/data/immich 아래에 upload와 database 폴더를 미리 만들어두고 권한을 abc:users (UID 998, GID 100)로 설정했습니다. Docker 컨테이너의 기본 유저는 node (UID 1000)인 경우가 많으니, 권한 문제(Permission Denied)로 고생하지 않으려면 미리 공유 폴더의 소유자(Owner)와 그룹(Group)을 root:users로 설정하거나, Docker Compose 파일 내 Immich 서비스에 user: "1000:100" 같은 형태로 지정해 주는 것도 좋은 방법입니다.

    2.3. 환경 변수 파일 (.env) 작성

    Docker Compose 파일과 같은 경로에 .env 파일을 생성하고 아래 내용을 채워 넣으세요. API_KEY는 직접 생성해야 합니다.

    DB_HOSTNAME=immich-database
    DB_USERNAME=immich
    DB_PASSWORD=your_strong_password # 위에서 설정한 비밀번호와 동일하게!
    DB_DATABASE_NAME=immich
    REDIS_HOSTNAME=immich-redis
    
    NODE_ENV=production
    
    # Immich API Key (https://immich.app/docs/install/environment-variables/ 참고)
    # openssl rand -base64 64 로 생성 가능
    IMMICH_API_KEY=your_generated_api_key_here
    

    IMMICH_API_KEY는 openssl rand -base64 64 명령어로 생성할 수 있습니다. 이걸 꼭 해주셔야 모바일 앱과 연동할 때 문제가 없어요. 저는 이걸 몰라서 한참 삽질했거든요. 😭

    3. 주의사항 및 트러블슈팅: 삽질은 나만 한다! ⚠️

    제가 겪었던 몇 가지 문제와 해결 팁을 공유합니다.

    • 권한 문제(Permission Denied): 앞서 언급했듯이, OMV의 공유 폴더 권한 설정이 정말 중요합니다. Docker 컨테이너가 볼륨에 쓰기/읽기 권한이 없으면 제대로 작동하지 않거든요. chmod -R 775 /srv/dev-disk-by-uuid-YOUR_DISK_UUID/data/immich 같은 명령어로 권한을 넓게 주거나, chown -R abc:users /srv/dev-disk-by-uuid-YOUR_DISK_UUID/data/immich처럼 소유자를 Docker 컨테이너의 실행 유저와 맞춰주면 됩니다.

    • 메모리 부족: Immich는 특히 사진 메타데이터 처리나 얼굴 인식 같은 작업을 할 때 꽤 많은 메모리를 사용합니다. 제 구형 NAS는 8GB RAM인데, 초기 동기화 시에는 버거워하더라고요. 최소 8GB 이상, 여유가 된다면 16GB RAM을 권장합니다.

    • 초기 동기화 시간: 기존에 쌓아둔 사진이 많다면, 처음 Immich에 업로드하고 인덱싱하는 데 상당한 시간이 걸립니다. 여유를 가지고 기다리세요. 저는 며칠 걸렸습니다. 😅

    • 외부 접속 설정 (Reverse Proxy): Immich를 외부에서 안전하게 접속하려면 Nginx Proxy Manager 같은 리버스 프록시(Reverse Proxy)를 설정하는 게 좋습니다. SSL(HTTPS) 적용은 필수죠! OMV에 Docker로 Nginx Proxy Manager를 설치하고 Immich 컨테이너의 포트(예: 2285)를 바라보게 설정하면 됩니다. 이 부분은 다음 기회에 더 자세히 다뤄볼게요.

    4. 검증 및 결과: 드디어 내 손 안의 구글 포토! 🎉

    모든 설정이 완료되고 Docker Compose 스택을 실행했다면, 잠시 후 Immich가 정상적으로 구동될 겁니다. 웹 브라우저에서 http://OMV_IP_주소:2285 (또는 Reverse Proxy 설정 시 도메인 주소)로 접속해 보세요. 멋진 Immich 로그인 화면이 나타날 겁니다.

    최초 접속 시 관리자 계정을 생성하고 나면, 바로 Immich의 대시보드가 눈에 들어올 거예요. 모바일 앱(안드로이드/iOS 모두 지원)을 설치하고 서버 주소와 API 키를 입력하면, 스마트폰의 사진들을 자동으로 Immich 서버로 백업할 수 있습니다. 진짜 편리하더라고요!

    Immich 웹 UI 대시보드: 자가 호스팅 사진 갤러리

    Immich 웹 UI에 접속하여 사진들이 성공적으로 업로드되고 관리되는 모습입니다.

    저는 이미 수만 장의 사진들을 Immich로 옮겨왔습니다. 얼굴 인식 기능도 꽤 정확하고, 검색 기능도 구글 포토 못지않게 잘 작동하더라고요. 내 서버에 내 사진이 있다는 심리적 안정감은 덤이고요. 😌

    5. 마무리: 데이터 주권, 이제 시작입니다!

    오늘은 OMV와 Immich를 연동하여 구글 포토 대안을 구축하는 과정을 상세히 소개해 드렸습니다. 물론 처음에는 삽질도 좀 하고, 설정에 시간을 꽤 투자했지만, 그만큼 얻는 것이 많다고 생각해요. 내 소중한 데이터를 내 손으로 관리할 수 있다는 것, 이보다 더 큰 만족감은 없더라고요.

    Immich는 활발하게 개발되고 있는 프로젝트라서, 앞으로 더 많은 기능과 개선이 이루어질 거라 기대하고 있습니다. 혹시 구글 포토 대안을 찾고 계셨다면, OMV와 Immich 조합을 꼭 한번 시도해 보세요! 분명 후회하지 않으실 겁니다.

    다음 글에서는 Immich의 외부 접속 보안을 강화하기 위한 Nginx Proxy Manager 설정 방법이나, 백업 전략에 대해 더 자세히 다뤄볼 예정입니다. 궁금한 점이 있다면 언제든지 댓글로 남겨주세요!

    구글 포토와 Immich 기능 비교 인포그래픽

    구글 포토와 Immich의 주요 특징을 비교한 표입니다.