콘텐츠로 이동

설계 원칙

이 홈랩을 운영하는 규칙들입니다. 새로운 결정을 내릴 때는 먼저 이 목록에 비춰봅니다.

저장소가 곧 서버다

Git 저장소가 단일 진실 공급원입니다. 호스트에서 설정을 직접 고치지 않습니다. 저장소에서 수정하고 검증한 뒤 배포하고 커밋합니다. 호스트와 저장소가 어긋나면 저장소가 옳고 호스트를 저장소에 맞게 재구축합니다.

열린 포트 0개

애플리케이션 포트를 공개 인터넷에 직접 노출하지 않습니다. 외부 트래픽은 오직 Cloudflare Tunnel → Caddy 경로로만 들어오므로, 방화벽은 닫힌 채로 유지되고 공격 표면은 호스트가 아니라 터널이 됩니다. 전체 그림은 보안 모델 참고.

tailnet이 내부 경계다

호스트 간 통신은 Tailscale 위에서 이루어지고 tailnet 멤버십이 "내부"의 기준입니다. Beszel 같은 운영자 전용 화면은 공개 엔드포인트의 비밀번호가 아니라 tailnet 주소 대역으로 차단합니다.

비밀은 스토어에 닿지 않는다

평문 비밀은 .nix 파일에도 Nix 스토어에도 절대 넣지 않습니다. 민감한 값은 모두 sops 암호화 YAML에 있고 각 호스트가 자기 SSH 키로 활성화 시점에 복호화합니다. 저장소가 유출되어도 평문 비밀은 노출되지 않습니다.

전부 고정한다

  • 컨테이너 이미지 태그는 고정, latest 금지.
  • flake.lock이 시스템 전체를 고정하며 nix flake update로만 의도적으로 갱신하고 손으로 편집하지 않습니다.
  • system.stateVersion은 설치 시점 기본값의 기록이며 올리지 않습니다.

yggdrasil은 가볍게

엣지 노드는 RAM이 4 GB이고 역할은 라우팅과 관측 둘뿐입니다. 애플리케이션은 애플리케이션 호스트(midgard 또는 alfheim)에 두고 yggdrasil에는 두지 않습니다. 새 서비스가 인그레스도 모니터링도 아니라면 yggdrasil에 둘 이유가 없습니다.

NixOS 모듈 우선

인프라와 NixOS 모듈로 깔끔하게 패키징되는 앱은 NixOS 모듈을 우선합니다. OCI 컨테이너는 업스트림이 컨테이너로 확실히 더 잘 패키징되고 대상 호스트에 Podman을 의도적으로 활성화한 경우에만 씁니다.

한 번에 하나씩

작고 집중된 변경: 저장소 수정 → PR 생성 → CI가 모든 호스트 빌드 → 초록색이면 병합 → CD 배포. 로컬 just test / just switch는 명시적인 비상 또는 부트스트랩 요청이 있을 때만 사용합니다. 무관한 변경 두 개를 같은 배포에 싣지 않습니다.