13년차의 서버실

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

[태그:] Synology Docker

  • [NAS] Immich NAS 성능 벤치마크와 최적화

    [NAS] Immich NAS 성능 벤치마크와 최적화

    [NAS] Immich NAS 성능 벤치마크와 최적화

    사진이 몇 만 장을 넘어가면, 그때부터는 단순히 저장만 하는 NAS(Network Attached Storage, 네트워크 저장소)로는 답이 잘 안 나오더라고요. 특히 Immich NAS 성능 이슈는 썸네일 생성, 머신러닝(Machine Learning, 기계학습) 분석, 모바일 업로드가 한꺼번에 몰릴 때 바로 체감됩니다. 저도 홈랩에서 Docker on NAS 환경으로 Immich를 굴려보면서 “왜 평소엔 멀쩡한데 오늘만 이렇게 느리지?” 같은 상황을 꽤 겪었습니다. 이번 글은 숫자를 지어내는 벤치마크가 아니라, 실제로 재현 가능한 측정 기준과 최적화 포인트를 정리한 글입니다.

    특히 Synology Docker 환경이나 TrueNAS 계열에서 Immich를 올려 쓰는 분들이라면, CPU만 볼 게 아니라 저장소 I/O(Input/Output, 입출력), 썸네일 작업 큐, PostgreSQL(포스트그레스큐엘, 데이터베이스) 설정까지 같이 봐야 합니다. 여기서 중요한 포인트! Immich 벤치마크는 단순 속도 테스트가 아니라 병목 구간을 찾는 과정이라는 점입니다.

    Immich NAS 성능 구성을 보여주는 전체 아키텍처 다이어그램

    Immich, PostgreSQL, Redis, 업로드 클라이언트, NAS 스토리지 경로가 한눈에 보이는 전체 구성도입니다.

    1. 왜 Immich NAS 성능이 생각보다 중요할까요?

    쉽게 말해 Immich는 그냥 사진을 쌓아두는 앱이 아닙니다. 업로드가 들어오면 메타데이터(metadata, 부가정보)를 정리하고, 썸네일(thumbnail, 미리보기 이미지)을 만들고, 검색을 위한 인덱스(index, 색인)를 쌓고, 경우에 따라 머신러닝 모델이 얼굴이나 장면 분석도 수행합니다. 그러니까 저장소 하나만 빠르다고 끝이 아니고, CPU, 메모리, 디스크, 컨테이너 배치가 같이 맞아야 하더라고요.

    제가 직접 해보니 초반엔 “NAS에 Docker만 올리면 되겠지”라고 생각했었는데, 실제로 써보니까 다음 세 가지가 체감 성능을 많이 갈랐습니다.

    • 대량 초기 인덱싱: 처음 라이브러리를 스캔할 때 CPU와 저장소 부하가 크게 올라갑니다.
    • 동시 업로드: 휴대폰 여러 대가 동시에 백업하면 I/O 대기 시간이 늘어납니다.
    • 썸네일/트랜스코딩: 작은 파일이 아주 많이 만들어져서 HDD 기반 볼륨은 생각보다 불리할 수 있습니다.

    혹시 이런 경험 있으신가요? 업로드는 끝났는데 앱에서 사진이 늦게 보이거나, 검색 결과가 한참 뒤에 반영되는 경우요. 이런 게 바로 사진 관리 솔루션으로서 Immich NAS 성능 문제로 이어집니다.

    2. Immich 벤치마크를 볼 때 기준을 먼저 정해야 합니다

    Benchmark(벤치마크, 성능 측정)라고 하면 숫자부터 보고 싶어지는데요, 사실 환경마다 차이가 너무 커서 절대 수치만 보면 오해하기 쉽습니다. CPU 세대, SSD 캐시 여부, 데이터셋 크기, 파일당 평균 용량, 컨테이너 리소스 제한이 다 다르거든요. 그래서 저는 아래처럼 작업 단위 기준으로 보는 걸 추천합니다.

    측정 항목 왜 중요한가 병목 힌트
    초기 라이브러리 스캔 시간 대량 사진 등록 시 전체 체감 속도에 직결 CPU 또는 디스크 I/O
    업로드 후 사진 표시 지연 모바일 백업 만족도와 직접 연결 썸네일 큐 적체, DB 응답 지연
    검색 반영 속도 메타데이터 처리 성능 확인 가능 DB, 인덱싱 작업 병목
    백그라운드 작업 중 CPU 점유 다른 NAS 서비스와 공존 가능성 판단 ML 작업, 트랜스코딩 부하
    스토리지 사용 패턴 썸네일/DB 경로 최적화 판단 작은 파일 쓰기 지연

    즉, Immich NAS 성능을 제대로 보려면 “몇 초 나왔냐”보다 “어떤 작업에서 느려졌냐”가 더 중요합니다. 저도 처음엔 이게 뭔가 싶었는데, 병목을 구간별로 나눠서 보니 훨씬 명확해지더라고요.

    3. Docker on NAS 환경에서 먼저 확인할 구성

    실전 들어가기 전에, 구성부터 정리하겠습니다. Synology Docker나 일반 리눅스 NAS, 그리고 TrueNAS 계열처럼 컨테이너 앱으로 Immich를 운영하는 경우에도 핵심은 비슷합니다.

    1. 사진 원본 라이브러리 경로와 데이터베이스 저장 경로를 구분합니다.
    2. 가능하면 PostgreSQL 데이터 디렉터리는 SSD 계층에 둡니다.
    3. 업로드 원본과 썸네일 캐시는 같은 풀(pool, 저장소 집합)에 둘지 분리할지 미리 결정합니다.
    4. 백그라운드 작업 시간대를 정합니다. 가족 사진 업로드가 많은 시간과 겹치면 체감이 확 떨어집니다.

    제가 홈랩에서 삽질 좀 했습니다 ㅎㅎ 원본 사진은 대용량 HDD 어레이(array, 디스크 묶음)에 두고, DB랑 캐시까지 같은 볼륨에 몰아뒀더니 작은 파일 I/O가 몰릴 때 응답성이 확 나빠졌습니다. 이후 DB와 캐시 계층을 더 빠른 스토리지로 분리하니 체감이 꽤 좋아졌습니다.

    예시 docker-compose.yml

    services:
      immich-server:
        image: ghcr.io/immich-app/immich-server:release
        container_name: immich_server
        depends_on:
          - redis
          - database
        environment:
          DB_HOSTNAME: database
          DB_USERNAME: immich
          DB_PASSWORD: change_me
          DB_DATABASE_NAME: immich
          REDIS_HOSTNAME: redis
        ports:
          - "2283:2283"
        volumes:
          - /mnt/nas/photo-library:/usr/src/app/upload
          - /etc/localtime:/etc/localtime:ro
        restart: unless-stopped
    
      immich-machine-learning:
        image: ghcr.io/immich-app/immich-machine-learning:release
        container_name: immich_ml
        volumes:
          - /mnt/fast/immich-model-cache:/cache
        restart: unless-stopped
    
      redis:
        image: redis:7
        container_name: immich_redis
        restart: unless-stopped
    
      database:
        image: tensorchord/pgvecto-rs:pg14-v0.2.0
        container_name: immich_db
        environment:
          POSTGRES_USER: immich
          POSTGRES_PASSWORD: change_me
          POSTGRES_DB: immich
        volumes:
          - /mnt/fast/postgres-immich:/var/lib/postgresql/data
        restart: unless-stopped

    버전은 예시일 뿐이고, 실제 배포 전에는 사용 중인 Immich 공식 문서와 현재 이미지 태그를 반드시 다시 확인하셔야 합니다. 중요한 건 구조입니다. 업로드 경로, 모델 캐시, 데이터베이스 경로를 어떻게 나누느냐가 성능에 직접 영향을 줍니다.

    Immich NAS 성능 최적화를 위한 스토리지 마운트 분리 구성 이미지

    업로드 볼륨, 데이터베이스 볼륨, 모델 캐시 볼륨을 서로 다른 스토리지 계층에 배치하는 구성 예시입니다.

    4. Immich 벤치마크를 위한 측정 절차

    이제 본격적으로 측정해보겠습니다. 여기서 제가 추천하는 방식은 동일 데이터셋으로 세 번 반복입니다. 첫 번째는 캐시가 비어 있는 상태, 두 번째는 일부 캐시가 쌓인 상태, 세 번째는 설정 변경 후 비교용입니다.

    1. 컨테이너 상태와 리소스 점유를 먼저 확인합니다.
    2. 테스트용 사진 세트를 준비합니다. 가능하면 파일 크기와 개수가 섞여 있어야 합니다.
    3. 업로드 직후부터 라이브러리 반영 완료 시점까지 시간을 기록합니다.
    4. CPU, 메모리, 디스크 I/O, 컨테이너 로그를 함께 봅니다.
    5. 설정을 하나만 바꾼 뒤 다시 측정합니다. 한 번에 여러 개 바꾸면 원인 파악이 안 됩니다.

    기본 확인 명령어

    docker ps
    
    docker stats
    
    docker logs -f immich_server
    
    docker logs -f immich_db
    
    df -h
    
    iostat -x 1

    여기서 iostat는 디스크 대기 시간을 보기 좋습니다. 만약 NAS 운영체제에서 직접 설치가 어렵다면, 제공되는 모니터링 도구로 대체해도 됩니다. Synology에서는 리소스 모니터(resource monitor), TrueNAS 계열에서는 대시보드와 풀 I/O 그래프를 같이 보면 감이 옵니다.

    업로드 테스트 예시

    time rsync -avh ./sample-photos/ /mnt/nas/photo-library/import-test/
    
    find /mnt/nas/photo-library/import-test -type f | wc -l

    실제로 써보니까 업로드 자체보다, 그 뒤에 이어지는 백그라운드 잡(background job, 백그라운드 작업)이 더 오래 걸리는 경우가 많았습니다. 그래서 저는 업로드 종료 시점과 앱에서 사진이 정상 탐색되는 시점을 따로 적어뒀습니다.

    5. 제가 자주 본 병목 구간과 최적화 포인트

    Immich NAS 성능을 끌어올릴 때는 무작정 CPU를 올리는 것보다 병목별 대응이 더 효과적입니다.

    • DB가 느린 경우: PostgreSQL 데이터 경로를 더 빠른 스토리지로 이동해보세요. Synology Docker나 TrueNAS Docker 환경이라면 기본 스토리지 계층을 확인하고 SSD 풀로 분리하는 걸 추천합니다.
    • 썸네일 생성이 밀리는 경우: 원본 사진 경로는 HDD여도, 캐시와 DB는 SSD 계층이 유리합니다.
    • 컨테이너 간 I/O 경쟁: Immich 외에 미디어 서버, 백업 작업, 다운로드 작업이 동시에 돌면 NAS 전체 응답성이 떨어집니다.
    • 메모리 부족: 스왑(swap, 디스크 기반 가상 메모리)이 발생하면 체감 성능이 급격히 무너집니다.

    저도 처음엔 CPU 사용률만 보고 있었는데, 근데 여기서 함정이 있더라고요. CPU는 40~50% 정도인데도 체감은 엄청 느릴 수 있습니다. 이런 경우는 대체로 디스크 대기나 작은 파일 쓰기 병목이었습니다.

    튜닝 전후를 비교할 때 체크할 것

    항목 튜닝 전 튜닝 후 기대 변화
    업로드 후 썸네일 반영 지연이 길고 들쭉날쭉 반영 속도가 더 일정해짐
    DB 응답 검색/스크롤 시 버벅임 목록 탐색이 부드러워짐
    동시 작업 시 NAS 반응성 다른 서비스도 같이 느려짐 영향 범위가 줄어듦
    백그라운드 작업 완료 시간 예측이 어려움 대체로 패턴이 안정적

    6. ⚠️ 트러블슈팅: 실제로 많이 겪는 문제

    이 섹션은 진짜 경험담 위주입니다. 저도 처음엔 헷갈렸는데, 아래 문제들은 꽤 자주 만났습니다.

    1) 볼륨 권한 문제로 업로드는 되는데 후처리가 꼬이는 경우

    컨테이너 내부 사용자 권한과 NAS 실제 디렉터리 권한이 안 맞으면 생기는 문제입니다. 파일은 생기는데 일부 작업이 실패하거나, 썸네일 생성 로그에 에러가 남을 수 있습니다.

    ls -al /mnt/nas/photo-library
    id
    
    docker exec -it immich_server sh

    해결 포인트: 컨테이너에서 접근하는 UID/GID와 NAS 공유 폴더 권한을 맞추는 겁니다.

    2) 데이터베이스를 느린 HDD 볼륨에 둔 경우

    사진 원본은 순차 읽기 비중이 커서 HDD도 어느 정도 버티는데, DB는 작은 쓰기와 랜덤 접근이 잦거든요. 그래서 같은 HDD 풀에 몰아두면 검색 반영과 라이브러리 응답성이 같이 떨어질 수 있습니다.

    해결 포인트: PostgreSQL 경로를 더 빠른 SSD 계층으로 옮기고, 원본 라이브러리와 분리해보세요. 특히 Synology Docker나 TrueNAS Docker 환경에서는 별도 SSD 볼륨을 준비해두는 것이 중요합니다.

    3) 머신러닝 작업이 몰리면서 NAS 전체가 답답해지는 경우

    얼굴 인식이나 장면 분석이 동시에 많이 돌면 CPU 자원을 꽤 씁니다. 이럴 때는 백업 작업, 미디어 인덱싱 작업과 시간이 겹치지 않게 분산하는 게 좋습니다.

    해결 포인트: 초기 분석은 야간으로 미루고, 낮에는 업로드 위주로 운영해보세요.

    Immich NAS 성능 벤치마크 결과를 확인하는 모니터링 대시보드 이미지

    업로드 이후 백그라운드 작업 큐가 쌓이고, CPU와 디스크 사용량이 함께 움직이는 모습을 보여주는 대시보드 예시입니다.

    7. 검증: 어떤 결과가 나오면 최적화가 잘 된 걸까요?

    여기서 중요한 건 절대 점수보다 일관성입니다. 제가 직접 해보니 최적화가 잘 된 환경은 다음 특징이 있었습니다.

    • 업로드 후 사진 표시까지 걸리는 시간이 들쭉날쭉하지 않습니다.
    • 대량 업로드 중에도 웹 인터페이스 탐색이 완전히 무너지지 않습니다.
    • 검색과 스크롤이 이전보다 자연스럽게 유지됩니다.
    • 백그라운드 작업이 끝나는 패턴이 예측 가능해집니다.

    즉, Immich 벤치마크의 핵심은 “최고 속도”보다 “실사용 중 안정성”입니다. 숫자 하나만 보고 판단하면 실제 사용감과 어긋날 때가 많습니다.

    가능하다면 아래처럼 간단한 기록표를 만들어 두세요.

    # 예시 기록 항목
    # 테스트 날짜
    # 사진 수 / 총 용량
    # 원본 저장소 위치
    # DB 저장소 위치
    # 업로드 완료 시각
    # 라이브러리 반영 완료 시각
    # 썸네일 생성 완료 체감 시각
    # CPU / 메모리 / I/O 특이사항

    이렇게 해두면 Synology Docker 환경과 다른 NAS 환경을 비교할 때도 훨씬 객관적으로 볼 수 있습니다. 다음 글에서는 모니터링 스택까지 붙여서 좀 더 자동화된 방식으로 다뤄볼 예정입니다.

    8. 정리 + 자주 묻는 질문

    정리해보면, 사진 관리 솔루션으로서 Immich는 정말 매력적입니다. 다만 NAS 위에서 잘 돌리려면 애플리케이션만 보는 게 아니라 스토리지 구조와 컨테이너 배치까지 같이 봐야 하더라고요. 저도 처음엔 단순히 이미지 올리고 끝인 줄 알았는데, 실제로는 Docker on NAS 환경 설계가 성능의 절반 이상을 좌우했습니다. 드디어 됐다! 싶은 순간은, 업로드와 탐색이 동시에 자연스럽게 돌아갈 때 오더군요.

    • Q. CPU가 높지 않은데도 느린 이유는 뭔가요?
      A. 디스크 I/O나 DB 응답 지연일 가능성이 큽니다. 작은 파일 쓰기가 많은 구간을 의심해보세요.
    • Q. 사진 원본도 SSD에 둬야 하나요?
      A. 꼭 그렇진 않습니다. 다만 DB와 캐시 계층은 더 빠른 스토리지가 체감에 유리합니다.
    • Q. TrueNAS Docker로 검색해도 되나요?
      A. 검색 키워드로는 많이 쓰지만, 실제 운영 방식은 NAS 플랫폼 버전에 따라 앱 또는 컨테이너 구성 방식이 다를 수 있으니 현재 환경 기준으로 확인하시는 게 좋습니다.
    • Q. Immich NAS 성능 최적화에서 가장 먼저 할 일은?
      A. 원본, DB, 캐시 경로를 분리해서 병목 위치를 확인하는 겁니다.
    Immich NAS 성능 최적화 전후를 요약한 인포그래픽

    병목 구간, 저장소 배치, 체크리스트를 한 장으로 요약한 인포그래픽입니다.

    이전 글에서 NAS 볼륨 설계와 백업 전략을 다뤘다면, 이번 글은 그 위에 Immich를 얹었을 때의 실제 운영 포인트에 더 가깝습니다. 다음 글에서는 로그와 모니터링을 붙여서, 어떤 지표를 보면 병목이 바로 보이는지 이어서 정리해보겠습니다. Immich NAS 성능 문제로 답답하셨다면, 오늘은 숫자보다 구조부터 다시 보시는 걸 추천드립니다.

  • [Nas] Docker Compose로 NAS에 앱 배포 및 관리하기: Synology, TrueNAS SCALE 가이드

    [Nas] Docker Compose로 NAS에 앱 배포 및 관리하기: Synology, TrueNAS SCALE 가이드

    13년차 서버실: Docker Compose로 NAS 앱 배포 및 관리 – Synology, TrueNAS SCALE 실전 가이드

    안녕하세요! 13년차 인프라 엔지니어입니다. 오늘은 많은 분들이 궁금해하실 주제를 다뤄볼게요. 바로 Docker Compose를 활용해서 NAS(Network Attached Storage)에 다양한 애플리케이션을 배포하고 관리하는 방법인데요. Synology와 TrueNAS SCALE 환경에서 직접 경험했던 내용을 바탕으로 실전 팁을 공유해드리겠습니다. 혹시 NAS를 파일 저장소로만 쓰고 계신가요? Docker Compose와 함께라면 여러분의 NAS가 훨씬 더 똑똑한 홈랩 서버로 변신합니다! 😉

    NAS 환경에서 Docker Compose를 활용한 애플리케이션 배포 및 관리 아키텍처 개요

    왜 NAS에 Docker Compose를 써야 할까요?

    NAS를 운영하다 보면 언젠가는 ‘파일 저장소 말고 다른 기능도 쓰고 싶은데…’ 하는 생각이 들게 돼요. 개인 블로그를 운영하고 싶거나, 영화·음악 스트리밍 서버를 구축하고 싶을 때 말이죠. 예전 같으면 복잡한 설치 과정과 설정 때문에 망설였겠지만, Docker와 Docker Compose를 알게 된 후로는 정말 달라졌어요.

    Docker는 애플리케이션을 컨테이너라는 격리된 환경에 담아 실행하는 기술입니다. 덕분에 운영체제나 다른 프로그램과의 충돌 걱정 없이 원하는 앱을 쉽게 설치하고 실행할 수 있죠. 다만 여러 개의 컨테이너를 묶어서 관리하려면 일일이 명령어를 입력해야 해서 번거로울 때가 많아요. 이때 등장하는 것이 바로 Docker Compose입니다!

    쉽게 말해, Docker Compose는 YAML이라는 설정 파일을 사용해서 여러 컨테이너로 구성된 애플리케이션을 한 번에 정의하고 실행할 수 있게 해주는 도구예요. 마치 오케스트라의 지휘자처럼 여러 악기(컨테이너)들이 조화롭게 연주(실행)되도록 지휘하는 역할을 하는 거죠.

    Docker Compose를 NAS에서 사용하면 좋은 점은 다음과 같아요:

    • ✅ 간편한 배포: 복잡한 설정 과정을 YAML 파일 하나로 정의하고, 단 한 번의 명령어로 여러 컨테이너를 한 번에 띄울 수 있어요.
    • ✅ 쉬운 관리: 컨테이너의 시작, 중지, 재시작, 삭제 등을 Compose 명령어로 간단하게 관리할 수 있습니다.
    • ✅ 재현성: 동일한 YAML 설정 파일만 있으면 언제 어디서든 똑같은 환경을 구축할 수 있어요. 개발, 테스트, 운영 환경 간의 차이로 인한 문제를 줄여주거든요.
    • ✅ 포트 충돌 방지: 각 컨테이너가 사용할 포트(Port)를 명확하게 지정하여 충돌을 피할 수 있습니다.
    • ✅ 확장성: 필요에 따라 컨테이너 수를 늘리거나 줄이기가 정말 쉬워요.

    Synology와 TrueNAS SCALE, Docker Compose 활용법

    Synology DSM과 TrueNAS SCALE은 각기 다른 방식으로 Docker 환경을 제공하지만, Docker Compose를 활용하는 기본 원리는 동일합니다. 핵심은 docker-compose.yml 파일을 작성하고 실행하는 거죠.

    1. Synology NAS에서 Docker Compose 사용하기

    Synology NAS에서는 ‘Docker’ 패키지를 설치하면 Docker Compose 기능을 사용할 수 있어요. DSM의 ‘패키지 센터’에서 Docker를 검색하여 설치해주세요. 저는 보통 SSH로 NAS에 접속해서 작업하는 것을 선호하지만, DSM의 ‘텍스트 편집기’나 ‘File Station’을 이용해 YAML 파일을 작성하고 관리할 수도 있습니다.

    실행 단계:

    1. SSH 접속: Putty(Windows) 또는 터미널(macOS/Linux)을 이용해 NAS에 SSH로 접속합니다.
    2. 작업 디렉토리 생성: 원하는 위치에 애플리케이션을 위한 디렉토리를 만들어요. 예: mkdir /volume1/docker/my-app && cd /volume1/docker/my-app
    3. docker-compose.yml 파일 작성: 텍스트 편집기(vi, nano 등)를 이용해 docker-compose.yml 파일을 생성하고 내용을 작성합니다.
    4. Docker Compose 실행: docker-compose up -d 명령어를 실행하면 설정된 컨테이너들이 백그라운드(-d)에서 실행돼요.

    예시: Nginx 웹 서버와 Portainer (컨테이너 관리 도구) 배포

    Portainer는 Docker 환경을 웹 UI로 쉽게 관리할 수 있게 해주는 정말 유용한 도구예요. NAS에 Portainer를 설치해두면 컨테이너 관리가 훨씬 편해진답니다.

    
    version: '3.8'
    
    services:
      portainer:
        image: portainer/portainer-ce:latest
        container_name: portainer
        restart: unless-stopped
        security_opt:
          - no-new-privileges:true
        ports:
          - "8000:8000"
          - "9443:9443"
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          - portainer_data:/data
        networks:
          - portainer_net
    
      nginx:
        image: nginx:latest
        container_name: my-nginx
        restart: unless-stopped
        ports:
          - "80:80"
          - "443:443"
        volumes:
          - ./nginx.conf:/etc/nginx/nginx.conf:ro
          - ./html:/usr/share/nginx/html:ro
        depends_on:
          - portainer
        networks:
          - portainer_net
    
    volumes:
      portainer_data:
    
    networks:
      portainer_net:
        driver: bridge
    

    이 파일을 /volume1/docker/portainer-nginx/docker-compose.yml에 저장하고, 해당 디렉토리에서 docker-compose up -d를 실행하면 Portainer와 Nginx 웹 서버가 동시에 실행돼요. Portainer는 http://NAS_IP:9443 (SSL), Nginx는 http://NAS_IP로 접속할 수 있습니다.

    Synology DSM에서 Docker 패키지를 설치하는 과정

    2. TrueNAS SCALE에서 Docker Compose 사용하기 (TrueNAS SCALE Apps)

    TrueNAS SCALE은 Kubernetes 기반으로 앱을 관리하는 ‘Apps’ 기능을 제공해요. Docker Compose 파일을 직접 사용하는 방식과는 조금 다르지만, Apps 기능을 통해 원하는 애플리케이션을 쉽게 설치하고 관리할 수 있다는 점은 같습니다. TrueNAS SCALE의 Apps는 Helm chart라는 것을 사용하는데, 많은 경우 Docker Compose 파일과 유사한 구조를 가져요.

    실행 단계:

    1. Apps 메뉴 접근: TrueNAS SCALE 웹 UI에서 ‘Apps’ 메뉴로 이동합니다.
    2. Catalogs 설정: 원하는 애플리케이션을 설치하기 위해 Catalog(앱 스토어 같은 개념)를 추가해야 해요. 커뮤니티에서 제공하는 다양한 Catalog들이 있습니다.
    3. 애플리케이션 설치: Catalog에서 원하는 앱을 선택하고 설치를 진행하면 돼요. 커스텀 앱을 직접 등록하여 Docker Compose 파일처럼 관리할 수도 있습니다.

    주의사항: TrueNAS SCALE의 Apps는 Kubernetes 기반이므로, Docker Compose의 docker-compose.yml 파일을 직접 실행하는 방식과는 다릅니다. 하지만 많은 커뮤니티 앱들이 Docker Compose 구조를 따르고 있어서, YAML 파일의 내용을 이해하고 있다면 앱 설정 시 도움이 돼요. 직접 Docker Compose 파일을 적용하려면 TrueNAS CORE의 ‘iocage’ 플러그인이나 TrueNAS SCALE에서 별도의 VM을 구성해야 할 수도 있습니다. 다만 대부분의 일반 사용자는 Apps 기능으로 충분히 원하는 앱을 설치하고 관리할 수 있어요.

    TrueNAS SCALE의 Apps 메뉴에서 다양한 애플리케이션을 탐색하고 설치하는 과정

    실전 팁 & 트러블슈팅 ⚠️

    13년간 Docker를 다루면서 겪었던 문제와 팁을 공유해 드릴게요. 처음엔 이것 때문에 밤새 고생했던 기억이 있어요. ㅎㅎ

    • 포트 충돌 (Port Conflict): 가장 흔한 문제예요. docker-compose.yml 파일에서 ports 섹션에 이미 사용 중인 호스트 포트를 지정하면 컨테이너가 실행되지 않습니다. Synology NAS의 경우, DSM 자체적으로 사용하는 포트와 충돌하지 않도록 주의해야 해요. 예를 들어 80번 포트는 DSM의 웹 스테이션 등이 사용할 수 있으니, 다른 포트(예: 8080)로 변경하는 것이 훨씬 안전합니다.
    • 볼륨 마운트 경로: 컨테이너 내의 데이터가 호스트 NAS의 특정 경로에 저장되도록 volumes 설정을 잘 해야 합니다. Synology에서는 /volume1/docker/app-name 같은 경로를 주로 사용하고, TrueNAS SCALE에서는 /mnt/poolname/dataset/app-name 같은 경로를 써요. 경로가 잘못되면 데이터가 사라지거나 컨테이너가 제대로 동작하지 않을 수 있으니 주의하세요. 경로 지정 시에는 항상 절대 경로(Absolute Path)를 사용하는 게 정답이에요.
    • 권한 문제 (Permission Issues): 컨테이너가 호스트 파일 시스템에 접근할 때 권한 문제가 발생할 수 있습니다. Docker Compose 파일의 user 옵션을 설정하거나, 호스트 볼륨의 권한을 컨테이너 사용자의 권한에 맞게 조정해야 할 수 있어요.
    • Docker Compose 버전 호환성: version 필드에 명시된 Compose 파일 형식 버전과 실제 사용 중인 Docker Compose 엔진 버전 간의 호환성을 확인하세요. 최신 버전에서는 지원되지 않는 기능이 이전 버전에 있을 수 있습니다.
    • 네트워크 설정: 여러 컨테이너가 서로 통신해야 하는 경우, networks 설정을 올바르게 해야 합니다. 기본적으로는 bridge 네트워크가 사용되지만, 복잡한 구성에서는 custom network을 사용해야 할 때도 있어요.

    💡 팁: 문제가 발생했을 때, docker-compose logs 명령어로 해당 서비스의 로그를 확인하세요. 정말 많은 힌트를 얻을 수 있거든요! 저도 이 명령어로 대부분의 문제를 해결했어요.

    결과 확인 및 관리

    Docker Compose 명령어를 통해 컨테이너를 실행한 후에는 상태를 확인하는 것이 중요합니다.

    • docker-compose ps: 현재 실행 중인 컨테이너 목록과 상태를 보여줘요.
    • docker-compose logs -f : 특정 컨테이너의 실시간 로그를 확인할 수 있습니다. (Ctrl+C로 종료)
    • docker-compose down: 실행 중인 컨테이너들을 중지하고 관련된 네트워크, 볼륨 등을 삭제해요. (데이터 보존 여부는 볼륨 설정에 따라 다름)
    • docker-compose pull: Docker 이미지의 최신 버전을 다운로드합니다.
    • docker-compose up -d --build: 설정 파일을 새로 빌드하고 컨테이너를 실행해요.

    Portainer 대시보드를 통해 Synology 또는 TrueNAS SCALE에서 실행 중인 Docker 컨테이너들을 한눈에 관리하는 모습

    마무리하며

    지금까지 Docker Compose를 활용하여 Synology와 TrueNAS SCALE NAS 환경에서 애플리케이션을 배포하고 관리하는 방법에 대해 알아봤습니다. 처음에는 조금 복잡해 보일 수 있지만, 한 번 익혀두면 NAS의 활용도를 정말 무궁무진하게 높일 수 있는 강력한 도구예요.

    저도 처음엔 간단한 웹 서버 하나 띄우는 것도 버거웠는데, 지금은 여러 컨테이너를 엮어 복잡한 서비스를 구축할 수 있게 됐네요. 여러분도 오늘 알려드린 내용을 바탕으로 차근차근 시도해보신다면, 분명 여러분만의 멋진 홈랩 환경을 구축하실 수 있을 겁니다.

    다음 글에서는 Docker Compose를 활용한 Home Assistant 설치 및 연동에 대한 실전 가이드를 다룰 예정이니 많은 기대 부탁드립니다! 혹시 오늘 내용 중에 궁금한 점이 있다면 언제든지 댓글로 남겨주세요. 함께 해결해나가겠습니다. 😉

  • [NAS] Docker 컨테이너 5가지 비교 및 설치 가이드: Portainer부터 Vaultwarden까지

    NAS에 Docker 설치했는데, 뭘 올려야 할지 모르겠다고요?

    저도 처음에 딱 그랬거든요. Synology NAS에 Docker(도커, 컨테이너 기반 가상화 플랫폼)를 설치하고 나서 한참 멍하니 화면만 바라봤었어요. “이제 뭘 하지?” 하는 느낌 있잖아요. 근데 막상 하나씩 써보기 시작하니까, 진짜 NAS가 단순한 저장소에서 홈 서버로 완전히 탈바꿈하더라고요.

    이 글에서는 제가 13년 넘게 인프라를 운영하면서, 홈랩에서 실제로 돌려보고 “이건 진짜 쓸 만하다”고 느낀 NAS Docker 활용을 위한 인기 컨테이너 5가지를 비교하고 설치 방법까지 정리해 드릴게요. 특히 Docker 컨테이너를 처음 다루는 분들께 도움이 될 거예요.

    ▲ NAS 위에 Docker 컨테이너들이 올라가는 전체 구조 — 하나의 NAS가 여러 서비스를 동시에 제공합니다

    NAS Docker, 왜 써야 하나요?

    쉽게 말해, Docker는 “앱을 격리된 박스 안에 담아서 실행하는 기술”이에요. NAS에서 Docker를 활용하면 이런 게 가능해집니다:

    • 기존 NAS OS(DSM 등)에 영향 없이 별도 앱을 설치
    • 설치/삭제가 깔끔하고 충돌이 거의 없음
    • 오픈소스 서비스를 공식 패키지 없이도 자유롭게 설치
    • 업데이트, 백업, 이전이 훨씬 편함

    Synology NAS에서는 DSM의 패키지 센터에서 “Container Manager”라는 이름으로 Docker를 설치할 수 있어요. QNAP은 “Container Station”이라는 이름으로 제공하고 있고요. 둘 다 GUI(그래픽 인터페이스)를 제공하지만, 저는 개인적으로 SSH 터미널로 직접 명령어를 치는 게 훨씬 편하더라고요. 설정 파일도 관리하기 좋고요.

    NAS Docker 인기 컨테이너 5가지 비교

    일단 전체 비교를 한눈에 보고 시작하는 게 좋을 것 같아서 표로 정리했어요.

    컨테이너 카테고리 주요 용도 리소스 사용 난이도
    Portainer 관리 도구 Docker 컨테이너 GUI 관리 매우 낮음 ⭐ 쉬움
    Nginx Proxy Manager 리버스 프록시 도메인/SSL 인증서 관리 낮음 ⭐⭐ 보통
    Jellyfin 미디어 서버 영상/음악 스트리밍 중간~높음 ⭐⭐ 보통
    Nextcloud 클라우드 스토리지 자체 클라우드 저장소 구축 중간 ⭐⭐⭐ 어려움
    Vaultwarden 비밀번호 관리 Bitwarden 호환 셀프호스트 매우 낮음 ⭐⭐ 보통

    이제 하나씩 살펴볼게요. 각 컨테이너별 설치 명령어도 함께 드릴게요.

    1. Portainer — Docker 관리의 시작점

    Portainer는 Docker 컨테이너를 웹 브라우저에서 GUI로 관리할 수 있게 해주는 도구예요. NAS Docker를 시작하는 분들한테 제일 먼저 추천하는 거거든요. 설치도 제일 쉽고, 이게 있으면 나머지 컨테이너 관리가 훨씬 편해지니까요.

    실제로 써보니까, 어떤 컨테이너가 얼마나 CPU/메모리를 쓰는지 한눈에 보이고, 로그도 바로 확인할 수 있어서 문제 해결할 때 정말 유용하더라고요. 특히 컨테이너가 자동으로 재시작되지 않을 때 원인을 빨리 찾을 수 있어요.

    Portainer 설치 명령어

    # Portainer 데이터 저장용 볼륨 생성
    docker volume create portainer_data
    
    # Portainer 컨테이너 실행
    docker run -d \
      -p 8000:8000 \
      -p 9443:9443 \
      --name portainer \
      --restart=always \
      -v /var/run/docker.sock:/var/run/docker.sock \
      -v portainer_data:/data \
      portainer/portainer-ce:latest

    설치 후 https://NAS-IP:9443으로 접속하면 초기 설정 화면이 뜹니다. 관리자 계정을 만들고 나면 끝이에요. 진짜 간단해요.

    💡 팁: Synology의 Container Manager를 쓰고 있더라도 Portainer를 함께 올려놓으면 훨씬 세밀한 관리가 가능합니다. 두 도구를 병행해도 충돌이 없거든요.

    2. Nginx Proxy Manager — 도메인과 SSL을 한 방에

    이건 제가 홈랩에서 정말 애용하는 Docker 컨테이너예요. Nginx Proxy Manager는 리버스 프록시(외부 요청을 내부 서비스로 전달해주는 역할)를 GUI로 쉽게 설정하고, Let’s Encrypt SSL 인증서까지 자동으로 발급·갱신해줘요.

    처음엔 “리버스 프록시가 뭔데?” 싶었는데, 쉽게 말하면 이런 거예요. jellyfin.내도메인.com, nextcloud.내도메인.com 이렇게 서브도메인마다 다른 서비스로 연결해주는 교통 정리 역할이에요. HTTPS(암호화 통신)도 자동으로 붙여주고요.

    Nginx Proxy Manager docker-compose 설정

    version: '3.8'
    services:
      app:
        image: 'jc21/nginx-proxy-manager:latest'
        container_name: nginx-proxy-manager
        restart: unless-stopped
        ports:
          - '80:80'
          - '81:81'   # 관리 웹 UI 포트
          - '443:443'
        volumes:
          - ./data:/data
          - ./letsencrypt:/etc/letsencrypt

    위 내용을 docker-compose.yml 파일로 저장하고 아래 명령어를 실행하면 됩니다:

    docker compose up -d

    설치 후 http://NAS-IP:81로 접속하면 관리 UI가 뜨고요. 초기 계정은 [email protected] / changeme인데, 로그인하자마자 바로 바꿔야 해요. ⚠️ 이거 그냥 두면 정말 위험합니다. 누구나 접속해서 설정을 바꿀 수 있거든요.

    ▲ Nginx Proxy Manager에서 프록시 호스트를 추가하고 SSL 인증서를 자동 발급하는 화면

    3. Jellyfin — 나만의 미디어 서버 만들기

    Jellyfin은 오픈소스 미디어 서버예요. Plex와 비슷한데, 완전 무료에 계정 없이도 쓸 수 있다는 게 큰 장점이에요. NAS에 쌓아둔 영화, 드라마, 음악을 스마트TV, 폰, 태블릿에서 스트리밍할 수 있거든요.

    제가 직접 써보니까, 자막 자동 검색 기능이랑 메타데이터(영화 포스터, 줄거리 등) 자동 수집이 꽤 잘 되더라고요. 다만 하드웨어 트랜스코딩(영상 포맷 변환)은 NAS CPU/GPU 성능에 따라 다르니까 이 부분은 좀 알아보고 써야 해요.

    Jellyfin docker-compose 설정

    version: '3.8'
    services:
      jellyfin:
        image: jellyfin/jellyfin:latest
        container_name: jellyfin
        restart: unless-stopped
        ports:
          - '8096:8096'
        volumes:
          - ./config:/config
          - ./cache:/cache
          - /volume1/media:/media:ro  # NAS 미디어 폴더 경로로 수정하세요
        environment:
          - TZ=Asia/Seoul

    ⚠️ 주의사항: /volume1/media 경로는 본인 NAS의 실제 미디어 폴더 경로로 반드시 바꿔야 합니다. Synology 기준으로는 보통 /volume1/ 아래에 있어요.

    4. Nextcloud — 나만의 클라우드 저장소 구축

    Nextcloud는 자체 클라우드 스토리지를 구축할 수 있는 오픈소스 플랫폼이에요. 구글 드라이브, 드롭박스 같은 서비스를 내 NAS 위에 직접 올리는 거라고 보면 돼요. 파일 공유, 캘린더, 연락처, 노트 등 다양한 기능을 제공해요.

    솔직히 말하면, 다섯 가지 중에 설치가 제일 까다롭습니다. 저도 처음에 삽질을 좀 했어요. 데이터베이스(MariaDB 또는 PostgreSQL)를 함께 올려야 하거든요.

    Nextcloud + MariaDB docker-compose 설정

    version: '3.8'
    services:
      db:
        image: mariadb:10.11
        container_name: nextcloud-db
        restart: unless-stopped
        environment:
          - MYSQL_ROOT_PASSWORD=강력한루트비밀번호
          - MYSQL_DATABASE=nextcloud
          - MYSQL_USER=nextcloud
          - MYSQL_PASSWORD=강력한비밀번호
        volumes:
          - ./db:/var/lib/mysql
    
      nextcloud:
        image: nextcloud:latest
        container_name: nextcloud
        restart: unless-stopped
        ports:
          - '8080:80'
        depends_on:
          - db
        environment:
          - MYSQL_HOST=db
          - MYSQL_DATABASE=nextcloud
          - MYSQL_USER=nextcloud
          - MYSQL_PASSWORD=강력한비밀번호
          - TZ=Asia/Seoul
        volumes:
          - ./data:/var/www/html

    ⚠️ 꼭 확인하세요: 비밀번호는 절대 예시 그대로 쓰지 마세요. 복잡한 문자열로 바꿔야 해요. 그리고 Nextcloud는 신뢰된 도메인(trusted_domain) 설정을 별도로 해줘야 외부에서 접속이 돼요. 처음 설치하고 나서 “Access through untrusted domain” 오류가 뜨면 config/config.php 파일에서 trusted_domains 항목을 수정해줘야 합니다.

    5. Vaultwarden — 비밀번호 관리, 직접 호스팅하기

    Vaultwarden은 Bitwarden과 호환되는 비밀번호 관리 서버를 셀프호스팅할 수 있게 해주는 프로젝트예요. Bitwarden 공식 서버 대신 내 NAS에서 직접 돌리는 거라고 보면 돼요.

    이거 설치하고 나서 진짜 감탄했어요. 리소스를 엄청 적게 먹으면서도, Bitwarden 공식 앱이나 브라우저 확장 프로그램을 그대로 연결해서 쓸 수 있거든요. 비밀번호가 내 서버에만 저장되니까 보안 측면에서도 마음이 편하고요.

    Vaultwarden docker-compose 설정

    version: '3.8'
    services:
      vaultwarden:
        image: vaultwarden/server:latest
        container_name: vaultwarden
        restart: unless-stopped
        ports:
          - '8888:80'
        volumes:
          - ./vw-data:/data
        environment:
          - TZ=Asia/Seoul
          - SIGNUPS_ALLOWED=true  # 초기 계정 생성 후 false로 변경 권장

    💡 중요 포인트: Vaultwarden은 반드시 HTTPS 환경에서만 제대로 동작해요. 앞서 설치한 Nginx Proxy Manager와 조합해서 SSL을 붙여줘야 합니다. HTTP로는 브라우저 확장 프로그램 연결이 안 되더라고요. 저도 이거 몰라서 한참 헤맸었어요.

    ▲ Portainer에서 5개의 컨테이너가 모두 정상 실행(Running) 상태인 것을 확인하는 화면

    ⚠️ NAS Docker 활용 시 자주 겪는 문제들

    포트 충돌 문제

    NAS 앱 설치를 많이 해두셨다면, 포트 번호가 겹칠 수 있어요. 예를 들어 Synology의 기본 웹 서비스가 80, 443 포트를 이미 쓰고 있을 수 있거든요. 이럴 때는 컨테이너의 호스트 포트 번호를 바꿔주면 됩니다. 8080:80처럼 앞 숫자(호스트 포트)를 안 쓰는 번호로 바꿔주세요.

    볼륨 권한 문제

    NAS에서 Docker 볼륨을 마운트할 때 권한 오류가 나는 경우가 꽤 있어요. 특히 Synology에서 Permission denied 오류가 뜨면, 해당 폴더의 소유자와 권한을 확인해보세요.

    # 폴더 소유자 확인
    ls -la /volume1/docker/
    
    # 권한 수정 (예시)
    chown -R 1000:1000 /volume1/docker/nextcloud/

    메모리 부족

    NAS 램이 4GB 이하라면, 컨테이너를 너무 많이 올리면 전체 시스템이 느려질 수 있어요. 특히 Nextcloud + MariaDB 조합은 생각보다 메모리를 좀 먹거든요. 처음에는 2~3개부터 시작하는 걸 추천드려요.

    설치 전 체크리스트

    1. NAS에 Docker(Container Manager 또는 Container Station) 설치 완료 확인
    2. SSH 접속 활성화 (명령어 방식 사용 시)
    3. Docker 저장 경로 설정 — 가급적 빠른 볼륨(SSD 캐시 있는 풀)에 배치
    4. 포트 충돌 여부 사전 확인
    5. 외부 접속 필요 시 공유기 포트포워딩 설정
    6. 도메인 보유 여부 확인 (Nginx Proxy Manager, Vaultwarden 사용 시 필요)

    ▲ NAS Docker 인기 컨테이너 5가지 용도, 난이도, 리소스 사용량 한눈에 비교

    자주 묻는 질문 (FAQ)

    Q. Synology NAS에서 Docker를 못 쓰는 모델이 있나요?

    네, 있어요. Synology 기준으로 Intel/AMD x86-64 아키텍처 모델에서만 Container Manager(Docker)가 지원됩니다. ARM 기반의 일부 보급형 모델(J 시리즈 등)은 지원이 제한될 수 있으니, 설치 전에 Synology 공식 호환성 페이지에서 확인해보세요.

    Q. docker-compose 명령어가 안 먹혀요.

    최신 Docker에서는 docker-compose(하이픈 있는 구버전) 대신 docker compose(공백, 플러그인 방식)를 사용해요. 둘 다 안 된다면 Docker Compose 플러그인이 설치됐는지 확인해보세요.

    Q. 컨테이너가 재부팅 후 자동 시작이 안 돼요.

    restart: unless-stopped 옵션이 docker-compose에 들어있는지 확인하세요. 명령어 방식으로 실행했다면 --restart=unless-stopped 옵션을 추가해야 합니다.

    NAS Docker 활용, 이렇게 시작하세요

    오늘 소개한 다섯 가지 컨테이너 중에서 처음 시작하는 분들께는 이 순서를 추천드려요:

    1. Portainer 먼저 설치 → Docker 전체 현황 파악
    2. Nginx Proxy Manager 설치 → 도메인/SSL 환경 구축
    3. 그다음 원하는 서비스(Jellyfin, Nextcloud, Vaultwarden) 순서대로 추가

    처음부터 다 설치하려고 하면 꼬이기 쉬워요. 저도 처음에 욕심 부리다가 포트 다 꼬이고 한참 삽질했거든요. 하나씩 안정화시키면서 늘려가는 게 훨씬 낫더라고요.

    Docker Compose를 사용하면 설정 파일 하나로 관리가 되니까, 처음부터 compose 방식에 익숙해지는 걸 강력히 권장합니다. 나중에 마이그레이션이나 백업할 때 훨씬 편해요.

    다음 글에서는 Nginx Proxy Manager와 Let’s Encrypt를 연동해서 외부에서 안전하게 홈서버에 접속하는 방법을 더 자세히 다룰 예정이에요. 이 글에서 설치한 컨테이너들을 외부에서 HTTPS로 접근하게 만드는 실전 가이드가 될 거예요. 🎉

    궁금한 점이나 삽질 경험 있으시면 댓글로 나눠주세요. 같이 해결해봐요!