본문으로 건너뛰기
강홍재/ James
← Writing

hongjae.co를 만들면서 한 결정 다섯 가지

2026-06-10

QA 엔지니어 출신 빌더가 자기 사이트를 만들면서 한 결정들 - 정직한 톤, 점진적 i18n, apex DNS 함정, push로 끝나는 CI, 그리고 "끝이 아니라 시작"이라는 정체성까지.

이 사이트는 처음부터 "끝낼 수 있는 한 페이지"가 아니라 "계속 손볼 자리"로 시작했다. 14년 동안 QA 엔지니어로 일하면서 가장 많이 본 실패는 "한 번 만들고 멈춘 것들"이었기 때문이다. 그 시각을 자기 사이트에도 그대로 들고 왔다.

만드는 과정에서 한 결정 다섯 가지를 정리한다. 정답은 아니고, 이 사이트의 톤에 맞춘 선택들.

1. 정직한 톤이 콘텐츠보다 먼저였다

각 프로젝트 카드에서 측정되지 않은 지표는 "측정 전"이라고 적었다. 멈춘 프로젝트는 "멈춘 결정"으로 표시했다. 사용자 수, 성장률, 매출은 검증된 것만 적기로 결정했다.

이게 왜 결정이냐면, 마케팅 글의 표준 어휘는 정반대이기 때문이다. "성장 중", "활발한 사용자 기반", "여러 도메인에서 검증" 같은 문구는 측정 안 된 것을 그대로 옮길 수 있는 도구다. 그걸 안 쓰기로 정한 순간, 글 한 줄 쓸 때마다 "이건 측정됐나?"가 먼저 떠오른다.

QA에서 가져온 습관이다. 결함 리포트에서 "가끔 안 됨"이 가장 무서운 말이다. "100번 중 3번 실패"가 훨씬 다루기 쉽다.

2. i18n은 처음부터, 콘텐츠는 점진적으로

KO/EN 두 언어를 처음부터 지원하기로 결정했다. 다만 모든 콘텐츠를 두 언어로 동시에 작성하는 건 솔로 운영에서 부담이 너무 크다.

해결책은 콘텐츠 모델에 부분 오버라이드를 허용하는 것이었다.

type Project = {
  tagline: string;        // KO 본문
  problem?: string;
  // ... 다른 케이스 스터디 필드들
  en?: Partial<LocalizableFields>;  // EN 오버라이드, 부분만 가능
};

function localizeProject(p, locale) {
  if (locale === "ko" || !p.en) return p;
  return { ...p, ...p.en };
}

EN 페이지에서 EN 필드가 있으면 영문, 없으면 KO로 폴백한다. 그래서 신규 프로젝트를 추가할 때 KO만 먼저 적어도 사이트가 절대 깨지지 않는다. EN 번역은 시간 날 때 점진적으로 채우면 된다.

처음에는 dictionary 파일을 따로 두는 패턴도 고민했는데, "콘텐츠 entry와 번역이 한 자리에 있는 게 작성이 빠르다"는 게 더 중요했다.

3. Apex DNS는 자동화의 함정이었다

hongjae.co 도메인을 Cloudflare Workers에 붙일 때, Custom Domain 자동화가 IPv6 AAAA 레코드는 만들어주는데 IPv4 A 레코드는 안 만들었다. 거기에 수동으로 A를 추가하려고 하면 "A DNS record managed by Workers already exists"로 거부됐다.

자동화가 "관리 중"이라고 주장하는데 실제로 절반만 관리하는 상태. 한국 가정망 사용자 다수가 IPv4만 쓰는 환경이라, 그대로 두면 사이트에 접속 못 한다.

우회는 apex 도메인을 custom_domain 대신 zone_name으로 wire하고, A 레코드를 직접 placeholder IP로 추가하는 것이었다. Worker route가 그 위에서 트래픽을 가로채니 실제 IP는 의미가 없다.

이 결정은 자동화에 대한 일반 교훈으로 남았다. "잘 작동할 때까지는 자동화고, 안 될 때는 디버깅 가능한 표면이 필요하다." 자동화가 실패하는 시점에 우회 경로가 없으면, 그 자동화는 운영 환경의 함정이다.

4. CI는 push 하나로 끝나야 했다

배포는 git push origin main 한 줄로 끝나도록 결정했다. Cloudflare Workers Builds가 GitHub repo와 연결돼 있어서, push가 트리거 → 자동 빌드 → 자동 배포 → 1-3분 안에 사이트 갱신.

로컬에서 직접 npm run deploy도 가능하지만 그건 비상용이다. "변경했으면 push, 끝." 이 한 줄로 모든 게 닫혀야 사이트를 자주 만질 수 있다.

이전 회사들에서 본 가장 안 좋은 패턴은 배포 절차가 복잡해서 "그냥 다음 스프린트에" 미뤄지는 변경들이었다. 한 줄 고치고 안 올라가면 그 변경은 사실상 없는 것과 같다. 자주 손보는 자리를 만들고 싶으면, 손보고 나서 push 한 번으로 닫혀야 한다.

5. 사이트는 끝이 아니라 시작이다

오해받기 좋은 게 portfolio 사이트의 정체성이다. "이미 만든 것들을 정리한 자리"로 보이지만, 그렇게 보이는 순간 다음에 만들 것이 안 보인다.

이 사이트는 working blog에 가깝게 만들었다.

  • /work에 진행 중인 mvp가 있고
  • /lab에 falsifiable한 next experiment가 있고
  • /writing에 (이 글처럼) 정리되는 흔적이 있다

무엇이 진행 중인지, 그게 무엇을 만들었는지보다 더 정직한 정보다. 사이트를 본 사람이 "이 사람이 지금 무엇을 하고 있나"를 알 수 있어야 협업 제안도 시작된다.

지금 가장 집중하는 건 DocuStory다. 한국 부동산 관련 문서의 위험을 LLM이 아닌 룰 기반으로 정리하는 분석 엔진. 다음 한 발은 실제 문서 100건 외부 검증이다.

같이 만들 사람과 조직을 찾는 중이다. 메일은 hello@hongjae.co로.