← 아티클 목록

개발일지WhoAmI — 공부 기록을 발행 가능한 형태로 좁힌 파이프라인 →

관리자 화면이 필요했는데 사이트를 서버 렌더링으로 바꾸지 않았다

브라우저에서 글을 쓰고 이미지를 끌어다 놓는 편집 화면이 필요했다. 그것을 사이트 안에 두면 쓰기 API가 공개 사이트에 함께 올라간다. 편집 편의와 공개 표면을 맞바꾸지 않으려고 관리자를 저장소의 scripts/ 안에 두고 공개 배포 산출물에서 제외한 기록.

목차 3

2026-09-05 정정 — 설명의 «저장소 밖»을 바로잡았다. 관리자 코드는 저장소의 scripts/ 안에 있고, 공개 빌드 산출물 밖에 있다.

2026-08-09 정정 — 관리자 기능을 추가하려면 사이트 전체를 서버 렌더링해야 한다는 설명을 바로잡았다. Astro는 특정 라우트만 on-demand로 실행할 수 있으며, 여기서 피한 것은 런타임 자체가 아니라 공개 배포에 관리자와 저장소 쓰기 권한을 추가하는 선택이다.

옵시디언 노트를 글로 옮기는 일을 파일 편집기로 하다 보면 매번 같은 데서 막힌다. frontmatter 의 카테고리를 오타 없이 적어야 하고, 이미지를 넣으려면 폴더를 만들어 파일을 옮기고 본문 경로를 손으로 쓴다. 한 편에 서너 번씩 나오는 일이라 브라우저에서 쓰고 끌어다 놓는 화면이 필요했다.

문제는 그 화면을 어디에 두느냐였다. Astro 로 만든 이 사이트는 어댑터 없이 기본 정적 출력으로 빌드된다. 편집 화면 자체는 정적 페이지로 만들 수 있지만, 저장소 파일을 쓰려면 요청 때 실행되는 서버 엔드포인트가 필요하다. Astro 공식 문서대로라면 어댑터를 붙이고 관리자 페이지와 API에만 export const prerender = false를 둘 수 있고, 나머지 페이지는 계속 정적으로 미리 만든다. 사이트 전체를 SSR로 바꿔야 한다는 처음 설명은 틀렸다. 현재 /share/* 요청을 처리하는 Worker도 이미 있으므로 런타임을 처음 도입하는 문제도 아니다. 실제 차이는 공개 배포에 관리자 화면, 인증 처리와 저장소 쓰기 API라는 새 권한 표면을 추가한다는 데 있다.

관리자를 빌드 결과물 밖으로 뺐다

관리자는 scripts/ 안의 독립 Node 서버로 두었다. npm run build 결과물인 dist/와 배포 Worker 번들에는 관리자 코드와 쓰기 API가 들어가지 않는다. 일반 글은 정적 자산으로 제공되고, 별도 Worker가 담당하는 /share/* 경로와도 관리자는 무관하다. 편집 화면은 이 PC에서만 뜬다.

npm run write 하나로 Astro 개발 서버와 관리자를 함께 띄우고, 왼쪽에서 글을 고르면 오른쪽에 미리보기가 붙는다. 기본 바인딩은 127.0.0.1 이라 같은 네트워크의 다른 기기에서도 닿지 않는다.

같은 화면을 CLI 로도 쓸 수 있게 규칙은 한 곳에 모았다. 볼트에서 글을 가져오는 변환·민감정보 차단은 scripts/lib/import-core.mjs 한 파일에 있고, 관리자와 node scripts/import-note.mjs 가 같은 함수를 부른다. 화면으로 하든 명령으로 하든 결과가 같아야 하기 때문이다.

얻을 수 있었지만 버린 두 가지

어댑터를 붙여 관리자 라우트만 on-demand로 두는 길을 버렸다. 공개 글은 정적으로 유지할 수 있지만, 관리자와 쓰기 API는 공개 주소에서 실행되는 기능이 된다. 그때부터 기존 공유 링크 Worker의 제한된 역할과 별개로 인증·인가, 요청 검증, 저장소 쓰기 권한과 런타임 운영을 함께 책임져야 한다. 개인 블로그에서 이 교환은 얻는 것보다 잃는 것이 크다고 봤다. 관리 도구를 쓰는 편의 때문에 공개 배포의 권한 표면을 늘리지 않기로 했다.

Decap 이나 Sveltia 같은 CMS 를 붙여 GitHub OAuth 로 로그인하는 방식도 버렸다. 정적 사이트를 유지하면서 브라우저 편집을 얻는 정석에 가까운 답이지만, GitHub OAuth 앱과 토큰을 중개하는 서버를 따로 운영해야 한다. 배포 경로를 git 하나로 두려고 만든 물건에 운영할 것이 하나 더 붙는다.

버린 두 길에는 공통점이 있다. 둘 다 편집 화면을 인터넷 어딘가에 두는 방식이고, 필요한 것은 쓰는 동안 편한 화면이었지 어디서나 접속되는 화면이 아니었다.

폰에서 쓰는 경로는 아직 정리하지 못했다

예외를 하나 뒀다. npm run write -- --host 로 켜면 같은 와이파이의 폰에서도 열린다. 토큰 없이는 접속되지 않고 토큰은 서버를 켤 때마다 새로 만든다.

이 경로는 아직 안전하지 않다. HTTP 라서 접속 주소가 그대로 오가고, --host 는 특정 주소 하나가 아니라 이 PC 의 모든 네트워크 인터페이스에 붙는다. 「이 와이파이에만 열었다」가 성립하지 않는다는 뜻이다. 저장소 감사에서 High 로 분류했고 아직 코드로 고치지 않았다. 지금은 문서에 신뢰하는 망에서만 쓰라고 적어 두고 밖에서는 초안만 메모해 두는 것으로 운영하고 있는데, 문서로 막는 것은 고친 것이 아니다.

고치려면 접속 방식 자체가 바뀐다. 지금 확실히 말할 수 있는 범위는 관리자가 저장소의 로컬 작업 트리만 바꾸고, 커밋·푸시·배포는 하지 않는다는 데까지다. 공개 사이트는 별도의 배포 절차를 밟기 전에는 바뀌지 않고, 관리자 코드와 쓰기 API도 dist/나 배포 Worker 번들에 들어가지 않는다.

함께 보면 좋은 글

이 기록과 태그가 겹치는 아티클입니다.