hswork.win

미니PC 한 대로 웹 서비스 4개 운영하기

2026-07-14 · 인프라

집에 있는 인텔 N100 미니PC 한 대가 제 서버 전부입니다. 여기에 지금 네 개의 웹 서비스가 돌아갑니다. 직장인 퇴사가이드, 웹 게임, 투병기 블로그, 그리고 일정 관리 서비스입니다. 클라우드를 쓰면 편하지만, 개인 프로젝트에 매달 고정비를 내는 건 부담이라 홈서버를 택했습니다.

서비스마다 도메인을 나눈 이유

처음에는 서비스마다 도메인을 따로 샀습니다. 그런데 서비스가 늘수록 관리가 번거로워졌습니다. 도메인 갱신일도 제각각이고, 인증서도 따로 발급해야 했습니다. 그래서 루트 도메인 하나를 두고 서브도메인으로 나누는 방식으로 정리했습니다. 지금은 서비스마다 (서비스명).hswork.win 형태를 씁니다. 새 서비스를 열 때 도메인을 새로 살 필요가 없고, 와일드카드 DNS 레코드를 걸어두면 서브도메인을 추가할 때 DNS를 건드리지 않아도 됩니다.

포트 하나를 여러 서비스가 나눠 쓰는 법

홈서버의 가장 큰 제약은 공인 IP가 하나뿐이고, 공유기에서 열어줄 수 있는 443 포트도 하나라는 점입니다. 서비스가 넷인데 입구는 하나입니다. 해법은 리버스 프록시입니다. 앞단에 nginx를 두고, 들어온 요청의 호스트명(server_name)을 보고 각 컨테이너로 넘겨줍니다. 브라우저가 어떤 주소로 들어왔는지에 따라 서로 다른 컨테이너가 응답하는 구조입니다.

이걸 모르고 처음 서브도메인을 붙였을 때, 엉뚱하게도 루트 도메인으로 접속해도 다른 서비스 화면이 떴습니다. 원인은 단순했습니다. nginx는 요청의 호스트명과 일치하는 설정이 하나도 없으면 맨 처음 정의된 설정을 기본값으로 사용합니다. 그래서 등록해두지 않은 주소가 전부 첫 번째 서비스로 흘러들어간 것이었습니다. 도메인마다 설정 블록을 명시해 주니 해결됐습니다.

포트를 아예 쓰지 않는 쪽이 편할 때도 있다

서비스가 셋을 넘어가면서 방식을 하나 더 섞었습니다. 리버스 프록시 구성에서는 443을 쥔 컨테이너가 모든 서비스의 입구 노릇을 하는데, 설정 파일 한 줄을 잘못 건드리면 넷이 동시에 내려갑니다. 실제로 인증서 경로를 잘못 적었다가 nginx가 기동하지 못해 전 서비스가 몇 분간 멈춘 적도 있습니다. 나중에 붙인 서비스들은 컨테이너가 밖으로 먼저 연결을 걸어 통로를 만드는 방식을 씁니다. 공유기 포트포워딩도, 443을 나눠 쓰는 설정도 손댈 일이 없습니다.

지금은 두 갈래가 공존합니다. 오래된 서비스 둘은 nginx가 호스트명으로 갈라주고, 나중에 붙인 서비스들은 각자 통로를 열고 나갑니다. 새 서비스를 하나 더 붙일 때 기존 설정 파일을 아예 열어보지 않아도 된다는 점이 생각보다 컸습니다.

컨테이너는 서비스별로 완전히 분리

네 서비스는 성격이 많이 다릅니다. 어떤 것은 검색 노출이 중요한 정적 사이트이고, 어떤 것은 실시간 통신이 계속 열려 있어야 하는 게임 서버입니다. 그래서 컨테이너·네트워크·배포 파이프라인을 서비스마다 완전히 분리했습니다. 한 서비스를 재배포해도 다른 서비스는 영향을 받지 않아야 하니까요. 데이터가 있는 서비스는 볼륨을 따로 두고, 컨테이너를 지웠다 다시 만들어도 데이터가 남도록 했습니다.

데이터베이스는 아예 서버 바깥으로 뺐습니다. 집에 있는 NAS에 두고 미니PC의 서비스들이 네트워크로 붙습니다. 미니PC를 통째로 갈아엎어도 데이터는 그대로라 마음이 편합니다. 문제는 서비스가 늘면서 어느 테이블이 어느 서비스 것인지 헷갈리기 시작한 겁니다. 테이블 이름 앞에 서비스를 알아볼 수 있는 접두사를 붙이는 규칙을 뒤늦게 만들었습니다.

겪고 나서야 알게 된 것들

운영하면서 배운 건 대부분 사고를 통해서였습니다. 도커를 잘못 재설치했다가 컨테이너들이 참조하던 내부 네트워크가 통째로 사라져 전부 기동에 실패한 적이 있습니다. 죽은 컨테이너가 물고 있던 포트를 프록시 프로세스가 계속 점유해, 새 컨테이너가 "포트가 이미 사용 중"이라며 뜨지 않은 적도 있습니다. 둘 다 원인을 알고 나면 몇 줄로 해결되지만, 모르면 몇 시간을 헤맵니다.

가장 오래 헤맨 건 같은 주소인데 접속하는 위치에 따라 다른 내용이 나오던 일이었습니다. 서버 자신에서 불러보면 새 버전인데 밖에서 보면 며칠 전 버전이었고, 컨테이너는 분명히 새것이었으며 로그도 깨끗했습니다. 범인은 지워진 옛 네트워크가 남긴 방화벽 규칙이었습니다. 밖에서 들어온 트래픽만 그 유령 규칙에 먼저 걸려 이제는 없는 주소로 흘러갔던 겁니다. 규칙을 손으로 지웠더니 이번에는 사이트 전체가 응답을 멈췄고, 도커 데몬을 재시작해 규칙을 처음부터 다시 만들게 하고서야 정리됐습니다.

지금은 모든 컨테이너에 자동 재시작 정책을 걸어두고, 장애가 났을 때 확인할 순서를 문서로 정리해 두었습니다. 컨테이너 상태, 포트 점유자, 컨테이너 안의 파일, 그리고 서버 안에서 부른 응답과 밖에서 부른 응답의 비교. 이 순서로 훑으면 대부분 몇 분 안에 어디가 문제인지 좁혀집니다. 재부팅 한 번에 서비스가 전부 내려가는 일은 그 뒤로 없었습니다.

홈서버 운영은 결국 화려한 기술보다, 무엇이 어디서 어떻게 도는지 스스로 설명할 수 있느냐의 문제인 것 같습니다. 미니PC 한 대는 생각보다 훨씬 많은 일을 해냅니다. 요즘은 기능을 하나 붙일 때마다 문서를 먼저 고칩니다.

← 개발 기록 목록