Ugreen NAS, Ubiquiti 등에 관심은 있으나 현재는 직접 만지는 과정 자체를 더 즐기는 단계
운영 원칙
Infrastructure-as-Code: 가능한 모든 설정을 스크립트 또는 관리 플랫폼(Ansible 등)으로 자동화하고 코드로 저장
재현성(Reproducibility): 장애 발생이나 머신 교체 시 인프라를 빠르게 재배포·재구성 가능해야 하며, 실험 서비스 제거 시에도 잔여물이 남지 않아야 함
사용 편의성: 취미 프로젝트인 만큼 표준적이고 익숙한 접근 방식 선호
운영체제
Debian 배포판을 베어메탈에 직접 설치하여 사용
NixOS(재현 가능한 빌드)나 Talos(k8s 클러스터) 등도 고려했으나, 단일 머신에서의 k8s 워크로드 관리 부담과 시간 부족으로 보류
ProxMox 같은 하이퍼바이저도 불필요하다고 판단하여 미사용
네트워크 아키텍처
외부 노출 방식으로 Cloudflare Tunnel 채택
서버에서 Cloudflare 네트워크로 아웃바운드 전용 연결을 생성하므로 방화벽에서 인바운드 포트를 열 필요 없음
터널 설정 후 양방향 트래픽이 터널을 통해 흐름
도메인을 Cloudflare DNS에 연결하면 서브도메인별로 머신의 특정 포트·프로토콜(HTTP/HTTPS/TCP 등)에 매핑 가능
완전 무료로 제공되며, ngrok보다 나은 대안으로 평가
고정 IP(White IP) 방식은 비용과 보안 위험이 있고, Tailscale Funnel 등의 대안도 있으나 가장 간편한 솔루션으로 Cloudflare Tunnel 선택
Traefik
오픈소스 리버스 프록시로, Docker를 네이티브로 인식하여 서버 자동화에 유리
컨테이너에 적절한 라벨을 붙이면 자동으로 라우팅을 감지하여 별도 설정 파일 수정 불필요
Authentik
IdP(Identity Provider) 및 SSO 플랫폼
설정을 블루프린트(YAML 파일) 형태로 저장할 수 있어 IaC 원칙 준수 가능
ForwardAuth 미들웨어를 통해 민감한 서비스에 접근 시 로그인 페이지로 리다이렉트
운영 도구
Ansible
에이전트리스(SSH만 필요) 인프라 자동화 도구로, YAML 기반 설정과 풍부한 예제가 장점
각 서비스를 역할(role) 단위로 정의: tasks, defaults, handlers, templates, files로 구성
tasks: 실행할 작업 정의
defaults: 이미지 태그, 포트, 컨테이너 이름 등 기본값
handlers: 설정 변경 시 컨테이너 재시작
templates: Jinja2 기반 .env 파일, config.yaml 렌더링
files: 정적 설정, 스크립트
서비스 배포의 일반적 단계:
공유 리소스(네트워크, 볼륨) 생성 → PostgreSQL에 스키마·사용자 생성 → 설정 템플릿 렌더링 → Docker 이미지 풀 → 컨테이너 실행(환경변수, 로깅 설정 포함) → Authentik 블루프린트에 인증 설정 프로비저닝 → 필요시 Cloudflare Tunnel 설정
단점으로는 방대한 문서, 반복적인 DSL 구조와 보일러플레이트가 존재하나 익숙해서 계속 사용 중
GitOps 통합 없이 수동으로 플레이북 실행, 현재로서는 충분
SOPS (Secrets OPerationS)
YAML/JSON 값만 암호화하고 키 구조는 그대로 유지하여 Git diff가 유용하게 동작
age 암호화 백엔드 사용 — "PGP 없이 암호화를 단순하게 만든" 도구
호스트별로 일반 설정 파일(homelab.yaml)과 암호화 파일(homelab.sops.yaml)을 분리 관리
워크플로우:
age-keygen으로 키 생성 → sops 명령으로 암호화 파일 편집(에디터에서 복호화 후 저장 시 자동 재암호화) → Ansible 실행 시 자동 복호화
Ansible이 SOPS를 네이티브 지원하므로 별도 모듈이나 플래그 불필요
Ansible Vault 대비 장점: 파일 전체가 아닌 값 단위 암호화로 diff 활용 가능
한계: age 개인키를 팀원과 안전하게 공유해야 하며, 키 분실 시 시크릿 복구 불가
1인 운영 홈랩에서는 적절한 수준의 복잡도
실행 중인 서비스
미디어 관리: *arr 스택
Prowlarr: 인덱서 관리자로, 검색 결과를 다른 *arr 서비스에 전달
Radarr: 영화 컬렉션 관리자 — 원하는 영화를 지정하면 검색·다운로드·정리를 자동 수행
Lidarr: 음악용 동일 기능, Navidrome과 연동
Bazarr: 자막 자동 다운로드
Tidarr: Tidal 음원을 로컬에 보관할 수 있는 서비스
Transmission: BitTorrent 클라이언트(포트 9091)로, 모든 *arr 서비스의 다운로드 요청 처리
모든 서비스가 Authentik 인증 뒤에 위치
공유 다운로드 디렉토리(/mnt/data/docker/transmission/downloads)와 PUID/PGID 1000을 사용해 하드링크로 디스크 공간 절약
워크플로우 예시: 영화를 Radarr에 추가 → Prowlarr로 검색 → Transmission이 다운로드 → Radarr가 미디어 라이브러리로 이동 → Jellyfin에서 시청 가능
미디어 소비
Jellyfin: 오픈소스 미디어 서버로, Plex와 달리 클라우드 로그인 불필요. 자체 인증 사용, Android TV 앱 포함 다양한 기기 지원
Navidrome: Subsonic API를 지원하는 음악 스트리밍 서버, 모바일 앱(DSub2000 등)과 연동. Lidarr가 라이브러리 폴더에 음악을 공급
Calibre Web: 전자책 라이브러리 관리자 및 리더
랩톱의 Calibre 데스크톱 앱에서 관리하는 메타데이터 DB를 Syncthing으로 서버에 동기화
OPDS API를 통해 여러 리더에서 책 접근 가능
AI 및 채팅
LibreChat: 셀프호스팅 AI 채팅 인터페이스로, 여러 LLM 프로바이더(OpenAI, Anthropic, 로컬 Ollama)에 연결 가능
RAG(Retrieval Augmented Generation) 지원
MongoDB(채팅 이력), PostgreSQL + pgvector(임베딩), MeiliSearch(전문 검색) 필요로 상대적으로 무거운 구성
Claude Code의 접근성이 더 좋아 사용 빈도가 낮으며, 제거를 고려 중
사진 및 파일
Immich: 셀프호스팅 Google Photos 대체 서비스
폰에서 자동 사진 백업, 얼굴 인식, 앨범 정리, EXIF 메타데이터 추출
자체 PostgreSQL(pgvector 포함)과 머신러닝 컨테이너(이미지 분류)를 사용하며, 현재 수천 장의 사진 저장 중
Syncthing: 랩톱·폰·서버 간 폴더 동기화. 클라우드 중개 없이 P2P 직접 동기화
Obsidian Vault, 문서 등을 여러 기기와 Android에서 동기화
MinIO: S3 호환 오브젝트 스토리지로, S3 API가 필요한 테스트나 애플리케이션에 활용
독서 및 정보
Miniflux: 미니멀 RSS 피드 리더로, 약 50개 블로그·뉴스 소스 구독
키보드 단축키 지원, 알고리듬 기반 정렬 없이 시간순 피드 제공
인프라 및 인증
Traefik: 호스트네임 기반으로 Docker 컨테이너에 트래픽을 라우팅하는 리버스 프록시. 컨테이너 시작 시 적절한 라벨만 있으면 자동 감지
Authentik: SSO 및 ID 프로바이더. ForwardAuth 미들웨어로 서비스 보호, 블루프린트를 Git에 저장하여 전체 인증 설정 관리
PostgreSQL: 공유 데이터베이스 서버로, Authentik·Miniflux·Immich·LibreChat 등이 각각 별도 DB 대신 하나의 인스턴스를 공유하여 리소스 절약 및 백업 용이
Redis: 공유 캐시 및 세션 저장소, 주로 Authentik 등의 세션 관리와 작업 큐에 사용
커스텀 소프트웨어
Highlight Exporter: KOReader, Readwise, Apple Books에서 책 하이라이트를 추출하여 Obsidian 호환 마크다운으로 변환하는 Go 서비스
Telegram Assistant: 다양한 자동화 작업과 그룹 채팅 내 AI 접근을 제공하는 Telegram 봇. 새로운 기술 시험용으로 가장 자주 재작성하는 프로젝트
Chess-blunder trainer: chess.com이나 lichess.com 게임을 불러와 Stockfish로 분석 후 실수한 수를 선별하여 훈련하는 웹앱으로, 곧 오픈소스 공개 예정
모니터링
Beszel
간편한 설정과 운영, 좋은 기본값을 갖춘 경량 모니터링 솔루션
Grafana 스택은 두 대의 머신에서 기본 OS 통계를 보기에는 과도하고 복잡하다고 판단
Glances 등 유사 프로젝트들도 지나치게 튜닝이 필요하다고 느낌
Beszel은 필요 기능의 120%를 커버하면서 설치가 간편
Statsping
특정 리소스에 대한 세밀한 모니터링을 위한 미니멀 서비스 핑 도구
정의된 엔드포인트에 핑을 보내 지연 시간과 가용성을 보고하고, 서비스 장애 시 다양한 방법으로 알림
홈랩 장애 시에도 살아남도록 클라우드 머신에서 호스팅, 별도 유지보수 오버헤드 없음
현재 부족한 부분
백업
백업의 중요성을 인지하면서도 현재 전혀 구현하지 않은 상태
영화·음악·사진 데이터 손실보다는 각 서비스의 데이터베이스 백업이 필요하나, 적절한 솔루션(restic 등)과 하드웨어 구성을 아직 결정하지 못함
RAID 설정
미디어 데이터와 시스템이 단일 M2 NVMe 드라이브에 공존하는 상태
NAS 서버나 별도 백업 머신을 위한 물리적 공간이 부족
클라우드 독립성
리소스 가용성을 Cloudflare Tunnel 인프라에 크게 의존
Cloudflare 장애 시 인프라 접근도 함께 중단되며, 향후 대안에 투자할 계획
완전한 IaC 및 자동화
CI 파이프라인이나 자동 프로비저닝 없이 Ansible 플레이북을 수동 실행
현재로서는 GitOps로의 전환이 큰 이점을 가져올 것으로 느끼지 않음
비용 효율성 및 결론
Hetzner 가상머신에 월 약 7유로 지출, 홈서버의 전기 사용량은 매우 적을 것으로 추정
새 서비스 추가나 설정 수정에 약 20~30분 소요, Claude Code에 상당 부분 위임하고 배포 전 간단한 리뷰만 수행
전체 프로젝트에 투입된 시간은 수년에 걸쳐 약 100~150시간으로 추정
최소한의 벤더 종속 없이 데이터를 소유하며, 갑작스러운 서비스 약관 변경이나 알고리듬 피드, 인수합병에 따른 데이터 소실 위험이 없음
완벽한 시스템이 아니라 인프라 이해와 즐거움이 목표이며, 배포하는 서비스, 작성하는 Ansible 역할, 암호화하는 시크릿 하나하나가 학습의 가치