시작은 단순했다

클라우드 비용이 아깝고, NAS도 필요하고, 사이드 프로젝트 서버도 있으면 좋겠고. 마침 집에 안 쓰는 ThinkPad가 있었다.

그렇게 시작된 홈서버 구축기가 어느새 12편이 됐다.


최종 구성

전체 아키텍처 구성도

  • 기기: ThinkPad E15 Gen3 (Ryzen 5 5600U, RAM 16GB)
  • OS: Ubuntu Server 24.04 LTS
  • 네트워크: Tailscale VPN + OCI Nginx 리버스 프록시
  • 도메인: yourdomain.com (Cloudflare)
  • 스토리지: 256GB SSD (OS/Docker) + 1TB SSD (/mnt/data, NTFS)

운영 중인 서비스 전체 목록

포트 서비스 접근 방식
2283 Immich (사진 관리) 도메인 (OCI 프록시)
9090 Filebrowser (파일 관리) 도메인 (OCI 프록시)
11000 Vaultwarden (비밀번호) 도메인 (OCI 프록시)
13000 Grafana (모니터링) Tailscale VPN
19000 Portainer (Docker GUI) Tailscale VPN
19090 Prometheus Tailscale VPN
19100 Node Exporter 내부 수집용
23000 컨테이너 대시보드 (React) Tailscale VPN
28080 컨테이너 대시보드 (Spring) Tailscale VPN

12편 한눈에 보기

1편 — 왜 홈서버인가? + 전체 아키텍처

→ 보러가기

클라우드 대신 홈서버를 선택한 이유와 Tailscale + OCI + Cloudflare로 구성한 전체 아키텍처를 소개한다.


2편 — Ubuntu Server 설치 + Tailscale VPN

→ 보러가기

Ventoy로 Ubuntu Server 24.04를 설치하고, Tailscale VPN으로 홈서버와 OCI 인스턴스를 하나의 사설 네트워크로 묶었다.


3편 — 외장 SSD 마운트 + Filebrowser 원격 파일 관리

→ 보러가기

NTFS 외장 SSD를 마운트하고 ntfsfix로 읽기/쓰기 문제를 해결했다. Docker로 Filebrowser를 띄워서 브라우저에서 파일을 관리할 수 있게 됐다.


4편 — Immich로 구글 포토 대체하기

→ 보러가기

Immich 접속 화면

Docker Compose 설치 과정에서 구버전 docker, NTFS 권한 문제 등 4가지 트러블슈팅을 겪었다. DB는 반드시 ext4에 둬야 한다.


5편 — Vaultwarden으로 비밀번호 자체 호스팅

→ 보러가기

구글 비밀번호를 CSV로 내보내서 Vaultwarden으로 이전했다. Bitwarden 브라우저 확장과 연동하면 기존과 사용감이 동일하다.


6편 — Portainer CE로 Docker GUI 관리

→ 보러가기

Portainer 대시보드

컨테이너가 8개를 넘어가면서 CLI 관리가 한계에 달했다. Portainer CE로 웹 UI에서 컨테이너를 관리한다. 보안상 VPN 안에서만 접근한다.


7편 — Grafana + Prometheus로 홈서버 모니터링

→ 보러가기

Grafana 모니터링 대시보드

Node Exporter를 홈서버 + OCI 두 곳에 설치하고, Prometheus가 Tailscale VPN을 통해 두 서버의 메트릭을 수집한다. ThinkPad 배터리 메트릭도 추가했다.


8편 — Fail2ban으로 SSH 브루트포스 차단

→ 보러가기

auth.log를 열어보니 수천 줄의 SSH 로그인 시도가 쌓여 있었다. Fail2ban으로 자동 차단하고, recidive jail로 반복 공격자는 7일 장기 차단한다.


9편 — certbot –expand로 SSL 서브도메인 추가

→ 보러가기

서비스가 늘어날 때마다 SSL 인증서에 서브도메인을 추가해야 한다. --expand 옵션과 셸 스크립트로 관리하면 -d 한 줄만 추가하면 된다.

브라우저 인증서 정보


10편 — PostgreSQL 자동 백업 (pg_dump + cron)

→ 보러가기

Immich DB가 날아가면 앨범, 태그, 얼굴 인식 데이터가 전부 사라진다. docker exec으로 pg_dumpall을 실행하고 cron으로 매일 새벽 3시에 자동 백업한다.


11편 — TLP + thinkfan + Swap 튜닝으로 운영 최적화

→ 보러가기

CPU 온도 85°C → 55°C, Swap 사용률 26% → 7%. TLP 터보 부스트 비활성화와 swappiness 튜닝으로 24시간 운영에 최적화했다.

Grafana - Swap 튜닝 전후


12편 — 직접 만든 컨테이너 대시보드 (Spring Boot + React + SSE)

→ 보러가기

커스텀 대시보드 UI

Portainer 대신 Spring Boot + React로 컨테이너 모니터링 대시보드를 직접 만들었다. SSE로 실시간 로그 스트리밍을 구현한 게 핵심이다.


돌아보며

파일 서버 하나 만들려고 시작했는데 어쩌다 보니 이렇게 됐다.

홈서버의 가장 큰 장점은 공부할 게 계속 생긴다는 거다. 서비스 하나 올리면 모니터링이 필요하고, 모니터링 하다 보면 튜닝하고 싶어지고, 외부에 열면 보안이 신경 쓰이고. 그 과정에서 Linux, Docker, Nginx, Spring Boot, React를 실제로 써보게 된다.

클라우드가 편하긴 하지만, 직접 서버를 굴리는 재미는 또 다르다.