시작은 단순했다
클라우드 비용이 아깝고, 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로 구글 포토 대체하기

Docker Compose 설치 과정에서 구버전 docker, NTFS 권한 문제 등 4가지 트러블슈팅을 겪었다. DB는 반드시 ext4에 둬야 한다.
5편 — Vaultwarden으로 비밀번호 자체 호스팅
구글 비밀번호를 CSV로 내보내서 Vaultwarden으로 이전했다. Bitwarden 브라우저 확장과 연동하면 기존과 사용감이 동일하다.
6편 — Portainer CE로 Docker GUI 관리

컨테이너가 8개를 넘어가면서 CLI 관리가 한계에 달했다. Portainer CE로 웹 UI에서 컨테이너를 관리한다. 보안상 VPN 안에서만 접근한다.
7편 — Grafana + Prometheus로 홈서버 모니터링

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시간 운영에 최적화했다.

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

Portainer 대신 Spring Boot + React로 컨테이너 모니터링 대시보드를 직접 만들었다. SSE로 실시간 로그 스트리밍을 구현한 게 핵심이다.
돌아보며
파일 서버 하나 만들려고 시작했는데 어쩌다 보니 이렇게 됐다.
홈서버의 가장 큰 장점은 공부할 게 계속 생긴다는 거다. 서비스 하나 올리면 모니터링이 필요하고, 모니터링 하다 보면 튜닝하고 싶어지고, 외부에 열면 보안이 신경 쓰이고. 그 과정에서 Linux, Docker, Nginx, Spring Boot, React를 실제로 써보게 된다.
클라우드가 편하긴 하지만, 직접 서버를 굴리는 재미는 또 다르다.