미니PC 한 대로 홈서버: Proxmox VM·LXC 나눈 기준

5600G·램 64GB·SSD 1TB 미니PC에 Proxmox를 올리고 Docker VM 하나, LXC 세 개로 나눴다. 무엇을 어디에 뒀는지, 공유기 포트를 닫고 Tailscale로만 들어가게 바꾼 이유.
미니PC 한 대로 홈서버 서비스 열 개 남짓을 돌린다. Ryzen 5 5600G, 램 64GB, SSD 1TB 미니PC에 Proxmox VE를 올리고, 앱은 Docker VM 하나에, 네트워크 관문·CI 러너·개발 서버는 LXC 세 개에 나눴다. 나눈 기준은 하나다. 같이 꺼져도 되는 것끼리만 한곳에 둔다.
사양: 5600G, 램 64GB, SSD 1TB
| 항목 | 사양 | 홈서버에서 뜻하는 것 |
|---|---|---|
| CPU | Ryzen 5 5600G, 6코어 12스레드, TDP 65W | 게스트 여러 개를 동시에 돌릴 여유. 내장 그래픽이라 그래픽카드 없이 화면이 나온다 |
| 램 | 64GB | VM에 크게 떼어 주고 LXC는 작게 줄 수 있는 양 |
| 저장장치 | SSD 1TB | OS, 컨테이너, DB. 사진 원본은 NAS로 보낼 계획 |
| GPU | 없음 | 로컬 LLM은 GPU를 단 별도 서버에서 돌린다 |
미니PC는 24시간 켜 두는 장비라 크기와 소음, 전력이 먼저다. 5600G는 TDP 65W에 내장 그래픽이 있어 이 조건에 맞는다. 대신 GPU 연산이 필요한 일은 처음부터 이 상자 밖으로 뺐다.
나눈 결과: VM 1개, LXC 3개
| 번호 | 종류 | 맡은 일 |
|---|---|---|
| 100 | VM | Docker 서버. Gitea, Postgres, Immich, Open WebUI, code-server, SearXNG, Dashy 같은 앱 컨테이너 |
| 110 | LXC | 네트워크 관문. Tailscale, AdGuard Home, Nginx Proxy Manager |
| 120 | LXC | 블로그 빌드 전용 Gitea Actions Runner (Debian 13 + Docker) |
| 121 | LXC | 개발 서버. PC의 VS Code가 SSH로 붙어 Dev Container를 띄운다 |
상자 밖에는 Synology NAS와 GPU 서버가 한 대씩 있다. NAS는 정리한 뒤 백업 저장소로 쓸 계획이다.
번호는 Proxmox의 게스트 ID다. 100번을 앱, 110번을 네트워크, 120번대를 빌드·개발로 정해 두니 목록만 봐도 무엇이 무엇인지 보인다. 집 전체에서 이 미니PC가 어디에 있는지는 홈 네트워크 지도에 그려 두었다.
관문은 앱과 떨어뜨린다
DNS(AdGuard Home), 리버스 프록시(Nginx Proxy Manager), VPN(Tailscale)은 모든 서비스의 입구다. 셋 중 하나만 멈춰도 Gitea든 사진이든 전부 접속이 끊긴다.
그래서 이 셋을 Docker VM에 넣지 않고 LXC 하나에 따로 뒀다. 앱 컨테이너를 재시작하거나 Docker를 업데이트하느라 VM을 껐다 켜도 입구는 살아 있다. 반대로 관문 LXC를 만질 때는 앱이 그대로 돈다.
LXC는 VM보다 가볍고 부팅이 몇 초면 끝난다. 이 세 서비스처럼 작고 오래 켜 두는 일에 맞는다.
같은 Docker라도 하는 일이 다르면 따로
블로그 빌드 러너도 Docker를 쓰지만 앱 VM에 넣지 않고 LXC를 새로 만들었다. 빌드는 이미지를 받고 CPU를 몰아 쓰는 일이다. 앱과 같은 Docker에 두면 빌드하는 동안 다른 서비스가 느려질 수 있고, 러너를 지우고 다시 만들 때 앱까지 신경 써야 한다.
Proxmox 문서는 Docker 같은 애플리케이션 컨테이너를 최대한 격리하려면 VM 안에서 돌리라고 권한다. LXC 안에서 Docker를 돌리려면 컨테이너 옵션에 nesting과 keyctl을 켜야 한다. 러너는 지워도 다시 만들면 그만인 블로그 전용 장비라 가벼운 LXC를 골랐다. 러너가 하는 일은 Gitea Actions로 Jekyll 배포하기에 있다.
# /etc/pve/lxc/120.conf 중
features: keyctl=1,nesting=1
밖에서 들어오는 문은 닫는다
처음에는 공유기 443 포트를 관문 LXC로 열어 두고 서브도메인마다 서비스를 붙였다. 2026-09-25에 포트포워딩을 지웠다. 지금은 Tailscale에 붙은 기기에서만 홈서버 서비스에 들어갈 수 있고, 공개 DNS에는 집 IP가 없다.
포트를 닫아도 내부 주소에 HTTPS가 그대로 붙는 것은 DNS 인증으로 받는 와일드카드 인증서 덕이다. 이름 풀이, 인증서, 집 밖 접속이 어떻게 이어지는지는 홈 네트워크 지도에 그림과 함께 정리했다.
손이 갔던 것 세 가지
LXC에서 한글이 깨졌다. 새로 만든 Debian LXC는 LANG=C로 시작해서 한글 파일명과 로그가 물음표로 나온다. 로케일을 UTF-8로 바꾸면 된다.
apt install -y locales
sed -i 's/^# *\(ko_KR.UTF-8\)/\1/' /etc/locale.gen && locale-gen
update-locale LANG=ko_KR.UTF-8 # 다시 로그인하면 적용
Docker 소켓 권한. 일반 사용자로 docker ps를 치면 permission denied가 난다. 사용자를 docker 그룹에 넣고 다시 로그인한다. 같은 무렵 sudoers 설정이 꼬인 일도 있었다. sudoers 수정은 꼭 visudo로 한다. 문법이 틀리면 저장 전에 막아 준다.
Portainer를 껐다. 지금은 서비스마다 docker-compose.yml을 두고 Compose로 관리한다. 설정이 파일로 남으니 AI에게 그대로 보여 주고 고치기 쉽고, 구성 자체도 어렵지 않다. 불편한 점은 로그 보기 하나다. 로그 전용 웹 화면(Dozzle)을 붙일 예정이다.
다음에 할 것
미니PC 한 대에 서비스를 몰 때 사양보다 먼저 정할 것은 나누는 기준이다. 관문, 앱, 빌드를 따로 두면 하나를 고치는 동안 나머지는 그대로 돈다.
남은 일은 백업이다. NAS를 정리한 뒤 Gitea 전체 백업(gitea dump)과 사진 원본 사본을 NAS로 보낸다. 다음 홈랩 글에서는 이번에 한 줄로 넘긴 관문 LXC, Tailscale·AdGuard·Nginx Proxy Manager를 어떻게 엮었는지 적는다.