# 집 미디어 서버 만들기: Docker로 Transmission, Jellyfin, 그리고 Telegram 봇
한 저녁 만에 Telegram으로 편리하게 제어할 수 있는 완전한 홈 미디어 서버를 구축할 수 있습니다. Transmission의 구식 인터페이스를 현대적인 Flood UI로 바꾸고, Jellyfin의 자동 인덱싱으로 수동 파일 복사를 건너뛰며, 다운로드 완료 알림을 메신저로 바로 받아 지속적인 모니터링을 대체하세요. 모든 것이 NAS(네트워크 연결 스토리지) 위에서 실행되며, 단 하나의 Docker 명령어로 시작됩니다.
Docker 기반 솔루션 구조
시스템의 핵심은 CIFS 볼륨을 통해 공통 파일 시스템을 공유하는 세 개의 컨테이너입니다. Transmission은 토렌트 다운로드를 담당하고, Jellyfin은 미디어 파일을 인덱싱하며 시청 인터페이스를 제공하며, Telegram 봇은 제어와 알림을 위한 사용자 인터페이스 역할을 합니다. 핵심 기능은 Docker 볼륨에 CIFS 드라이버를 사용해 컨테이너 내부에서 네트워크 공유를 직접 마운트하는 것으로, 호스트의 로컬 파일 시스템에 얽매이지 않습니다.
초보자들이 흔히 저지르는 실수는 Windows에서 네트워크 드라이브에 바인드 마운트를 사용하려는 것입니다. WSL2의 특성상 이런 경로는 컨테이너 내부에서 보이지 않습니다. 해결책은 볼륨 유형을 cifs로 명시적으로 지정하고 연결 매개변수를 설정하는 것입니다:
volumes:
downloads:
driver: local
driver_opts:
type: cifs
device: ${SMB_HOST}
o: "username=${SMB_USER},password=${SMB_PASSWORD},vers=3.0,uid=1000,gid=1000,file_mode=0777,dir_mode=0777"
Transmission과 Jellyfin 두 서비스 모두 이 볼륨을 사용하지만 컨테이너 내부 마운트 지점이 다르기 때문에 경로가 일관되고 충돌이 없습니다.
Telegram 봇과 자동화 설정
봇은 python-telegram-bot 라이브러리를 사용한 Python으로 제작되었으며, Transmission의 RPC API를 통해 상호작용합니다. Transmission 컨테이너와 공유 네트워크 스택 모드(network_mode: "service:transmission")로 실행되어 추가 포트 포워딩 없이 지연을 최소화합니다.
주요 봇 기능:
- .torrent 파일이나 마그넷 링크 전송으로 토렌트 추가
- 유니코드 프로그레스 바로 자동 완료 알림
- 인라인 메시지 버튼으로 활성 다운로드 관리
- 재시작 시 중복 방지를 위한 알림 필터링
프로그레스 바는 간단한 함수로 구현됩니다:
def progress_bar(pct, width=12):
filled = round(pct * width)
return "█" * filled + "░" * (width - filled)
봇 재시작 시 스팸을 피하기 위해 완료된 토렌트 ID를 추적합니다. 시작 시 completed_ids 집합을 초기화해 새로 완료된 다운로드에만 알림을 보냅니다.
Transmission 세부 조정과 이미지 제한 우회
공식 linuxserver/transmission 이미지는 특이점이 있습니다: 실행할 때마다 settings.json 일부를 덮어쓰며 환경 변수를 무시합니다. 이는 watch-dir, download-dir, incomplete-dir 같은 설정에 영향을 줍니다. 해결책은 초기화 후 데몬 시작 전에 사용자 정의 스크립트를 실행하는 custom-cont-init.d 메커니즘입니다.
예제 스크립트 01-fix-settings.sh:
#!/bin/sh
mkdir -p /downloads/Downloads
mkdir -p /downloads/.incomplete
mkdir -p /downloads/watch
SETTINGS=/config/settings.json
if [ -f "$SETTINGS" ]; then
sed -i 's|"watch-dir": ".*"|"watch-dir": "/downloads/watch"|' $SETTINGS
sed -i 's|"watch-dir-enabled": false|"watch-dir-enabled": true|' $SETTINGS
sed -i 's|"download-dir": ".*"|"download-dir": "/downloads/Downloads"|' $SETTINGS
sed -i 's|"incomplete-dir": ".*"|"incomplete-dir": "/downloads/.incomplete"|' $SETTINGS
sed -i 's|"incomplete-dir-enabled": false|"incomplete-dir-enabled": true|' $SETTINGS
fi
또 다른 문제는 Flood UI 설치입니다. 최신 이미지 버전에서 타사 인터페이스를 제거했습니다. GitHub에서 아카이브를 수동으로 다운로드해 config/flood-ui/에 압축 해제해야 합니다. 리포지토리에는 자동화를 위한 setup-flood.sh 스크립트가 포함되어 있습니다.
Jellyfin 첫 실행과 TV 연동
컨테이너를 시작한 후 http://localhost:8096에서 Jellyfin 웹 인터페이스를 열어보세요. 초기 설정은 사용자 생성과 미디어 라이브러리 추가입니다. 공유 폴더를 Jellyfin 컨테이너에서 /media/Downloads로 지정하세요.
Jellyfin은 자동으로:
- 폴더 내용 스캔
- 콘텐츠 유형 식별(영화, TV 프로그램)
- TMDB에서 메타데이터와 포스터 가져오기
- 장르, 연도, 배우별 직관적 탐색 구축
TV 시청을 위해 공식 Jellyfin 앱을 설치하세요(Android TV, Apple TV, Fire TV, Roku 지원). 첫 실행 시 호스트의 로컬 IP와 8096 포트를 입력합니다. 이전에 생성한 사용자 계정으로 로그인하세요.
자주 묻는 질문과 기능 확장
NAS가 없나요? CIFS 볼륨을 bind 옵션의 로컬 폴더로 교체하세요:
volumes:
downloads:
driver: local
driver_opts:
type: none
device: /absolute/path/to/folder
o: bind
VPN을 사용하고 싶나요? gluetun 컨테이너를 사용하고 Transmission을 그 네트워크 네임스페이스로 이동하세요:
transmission:
network_mode: "service:gluetun"
depends_on:
- gluetun
업데이트는 어떻게 하나요? 다음 명령어를 실행하세요:
docker compose pull && docker compose up -d
원격 액세스? Tailscale이나 Cloudflare Tunnel을 사용하세요—라우터 포트 포워딩보다 안전합니다.
핵심 사항
- Windows의 Docker Desktop에서 네트워크 드라이브에는 바인드 마운트 대신 CIFS 볼륨이 필수
custom-cont-init.d메커니즘으로 공식 Transmission 이미지 제한 우회- 봇과 Transmission 간 공유 네트워크 스택으로 설정 간소화 및 안정성 향상
- Jellyfin이 미디어에 메타데이터 자동 추가—수동 조정 불필요
- 모든 데이터가 외부 NAS에 저장되어 OS 재설치에도 안전
— Editorial Team
아직 댓글이 없습니다.