STILLCODING

STILL CODING / NOTES

개인 개발자의 앱 포털 운영기 — Astro 정적 빌드와 Cloudflare Workers

JH Kim

Still Coding은 제가 만든 웹 앱을 한곳에 모아 소개하는 포털입니다. 게임 모음 Direct Play, 퍼즐 Pinhole Lab, 일본어 문자 학습 가나 공방, 협업 도구 CollaBoard, 버스 노선 탐색 Bus Explorer, 악보 스튜디오 Songnote, 음정 확인 도구 Vocal Check가 각자 하위 도메인에서 따로 운영됩니다. 이 글은 포털 자체를 어떤 구조로 만들고 운영하는지 정리한 기록입니다.

1. 앱은 따로, 포털은 가볍게

앱마다 기술 스택이 다릅니다. Songnote는 React와 Vite, Vocal Check는 프레임워크 없는 순수 자바스크립트, Bus Explorer는 Python FastAPI 서버, CollaBoard와 Direct Play는 Cloudflare Worker와 Durable Objects를 씁니다. 이것들을 하나의 저장소나 하나의 배포로 묶으면 한 앱의 변경이 다른 앱을 멈추게 할 수 있습니다.

그래서 원칙을 정했습니다.

2. 왜 Astro인가

포털에 필요한 것은 거의 전부 “빌드할 때 정해지는 HTML”입니다. 앱 목록, 앱 상세, 개인정보처리방침, 개발 노트 모두 방문자마다 달라질 이유가 없습니다. Astro는 기본적으로 자바스크립트를 보내지 않고 HTML과 CSS만 만들어 내며, 필요한 곳(공유 버튼, QR 코드 대화상자, 언어 선택 메뉴)에만 작은 스크립트를 붙일 수 있습니다.

3. Cloudflare Workers 정적 에셋으로 배포

빌드 결과(dist/)는 Cloudflare Workers의 정적 에셋 기능으로 배포합니다. Worker 스크립트 없이 wrangler.jsonc에 에셋 디렉터리와 커스텀 도메인만 적으면 됩니다.

{
  "name": "still-coding-portfolio",
  "assets": { "directory": "./dist", "not_found_handling": "404-page" },
  "routes": [{ "pattern": "still-coding.cc", "custom_domain": true }]
}

여기서 신경 쓴 설정이 not_found_handling입니다. 단일 페이지 앱(SPA)처럼 모든 경로에 index.html을 돌려주면, 없는 주소도 정상(200)으로 응답하는 soft 404가 됩니다. 크롤러는 이런 사이트에서 어떤 페이지가 진짜인지 판단하기 어렵고, /robots.txt나 /ads.txt를 요청했는데 HTML이 오는 문제도 생깁니다. 포털은 404-page로 두어, 없는 주소에는 404 상태 코드와 함께 안내 페이지를 보여 줍니다.

4. 한국어와 영어, 두 언어 운영

방문자 대부분은 한국어를 쓰지만, 앱 중 일부는 해외 사용자도 씁니다. 그래서 한국어를 기본(/)으로, 영어를 /en/ 아래에 두었습니다.

5. 신뢰를 위한 페이지들

개인이 운영하는 사이트일수록 “누가, 어떻게 운영하는가”를 분명히 보여 주는 것이 중요합니다. 포털에는 다음 페이지를 두었습니다.

특히 개인정보처리방침은 앱별로 실제 코드와 대조해 적었습니다. 예를 들어 Vocal Check는 녹음 파일을 만들지 않고, Songnote는 악보를 브라우저에만 저장하며, CollaBoard는 팀 자료를 서버에 두지 않습니다. 이런 차이를 뭉뚱그리지 않고 앱마다 밝히는 편이 사용자에게 정직합니다.

6. 운영하면서 챙기는 체크리스트

정리

여러 앱을 운영하는 개인 개발자에게 포털은 “모든 것을 담는 플랫폼”보다 가볍고 정직한 안내판이 더 잘 맞았습니다. 앱은 각자 독립적으로 배포하고, 포털은 정적 HTML로 설명과 연결만 맡습니다. 덕분에 새 앱을 추가하는 일은 apps.ts에 항목 하나를 더하고 상세 설명을 쓰는 것으로 끝납니다.