6P by GN⁺ | ★ favorite | 댓글 5개
  • 개인 블로그를 기존 보유 도메인 위에 정적 페이지로 구성하고, 콘텐츠 추가와 기본 SEO를 함께 만족하는 최소 구현을 목표로 함
  • 구현은 작은 template.html, markdown2, O1에게 요청해 만든 render.py, 그리고 Markdown 글 작성으로 단순하게 이어짐
  • 템플릿은 system-ui, 최대 폭 70ch, color-scheme: light dark, viewport, UTF-8처럼 기본 HTML/CSS만 사용함
  • render.py./posts/{post}/eng.md를 HTML로 변환하고 이미지 경로를 조정한 뒤 ./blog/{post}.htmlindex.html을 생성함
  • Jekyll, Ghost, WordPress 없이도 정적 렌더링과 호스팅만으로 운영 가능한 블로그를 만들 수 있음을 보여줌

최소 블로그 요구사항과 실제 구성

  • 출발점은 네 가지 요구사항이었음
    • 이미 소유한 도메인을 사용할 것
    • 현대 웹 표준을 따르고 괜찮은 SEO를 가질 것
    • 새 콘텐츠 추가가 매우 쉬울 것
    • 모든 페이지가 정적으로 빌드될 것
  • 실제 구현 흐름은 단순함
    • 작은 template.html 작성
    • pip install markdown2 실행
    • O1에게 render.py 스크립트 요청
    • 글 작성 후 렌더링하고 호스팅함
  • Jekyll, Ghost, WordPress 같은 기존 블로그 엔진은 사용하지 않음

템플릿과 렌더링 스크립트

  • template.html은 기본 HTML 문서 구조와 최소한의 CSS만 담음
    • color-scheme: light dark로 라이트/다크 색상 체계를 지정함
    • 본문 스타일은 system-ui, sans-serif, 최대 폭 70ch, 줄 높이 1.5, 글자 크기 1.25em으로 설정함
    • id="head-link"가 붙은 홈 링크와 {{ content }} 자리표시자를 사용함
  • render.pymarkdown2로 Markdown 글을 HTML로 변환함
    • 입력 디렉터리는 ./posts, 출력 디렉터리는 ./blog
    • 각 글은 ./posts/{post_directory}/eng.md에서 읽음
    • 첫 번째 # 헤더를 글 제목으로 사용함
    • fenced-code-blocks, header-ids 옵션으로 Markdown을 변환함
    • 이미지 경로의 <img src="/posts/{post_code}/ 기준으로 바꿈
    • 템플릿의 {{ content }}를 변환된 HTML로 대체하고 제목 문자열도 글 제목으로 바꿈
  • 인덱스 페이지도 같은 스크립트에서 생성함
    • greetings.md를 먼저 HTML로 변환함
    • 각 글 제목을 읽어 /blog/{post_code}.html 링크 목록을 추가함
    • 최종 결과를 index.html로 저장함
  • 글은 2025-03-31에 수동으로 작성됨

댓글과 토론

저도 현재 제 블로그를 딱 위에처럼 운영하고 있습니다. 제 개인 요구사항을 만족하는 SSG를 만들어서 사용하고 있죠. 섬네일 이미지, 카테고리, 태그 기능을 활용하기 위해 개별 커스텀 기능을 넣어서 말이죠. 첨부하는 이미지는 자동으로 webp로 변환해서 참조하도록 하고 있고 덕분에 렌더링 속도가 매우 만족스럽습니다.

오 그런 커스텀 기능은 직접 코드를 작성하며 추가해 나가시나요? 저도 늘 diy 하려하다가도 기존에 사용하던 ssg 블로그 프레임워크들이 제공하는 확장, 플러그인 기능들 때문에 망설여 지더라구요.

욕심을 덜어내고 욕심만 덜어내면 나머진 크게 어렵지 않습니다. ssg도 AI에게 요청하면 코드 다 작성해주고, 기능도 추가해달라고 하면 사실 다 추가해줍니다 ㅎㅎ

폰트만 이쁜 걸 고르면 볼 만 하더라구요.

Hacker News 의견들
  • 이 블로그 글의 차트가 떠오름: https://molodtsov.me/2023/02/how-to-start-your-blog-in-2023/
    정적 사이트 생성기(SSG) 늪에 빠지니, 원래 쓰고 싶던 글이나 하려던 일 대신 SSG 자체에 대해 쓰고 만지작거리는 시간이 대부분이었음
    결국 SSG를 버리고 WordPress를 설치한 뒤 신경을 끊었는데, 해방감이 컸다
    목표가 만지작거리고 그 과정을 쓰는 것이라면 괜찮고, 만지작거림이 글쓰기를 방해하지 않는 사람도 괜찮지만 나는 아니었음
    글을 쓰려는 순간에 필요한 마지막 것은 미룰 핑계임

    • 2025년 WordPress는 위험한 특성 두 가지를 같이 갖고 있음
      WordPress와 모든 플러그인은 최신 상태를 유지하지 않으면 침해당할 수 있고, BDFL은 사소한 개인적 이유로 보안 업데이트 전달이나 수신 접근을 막을 수 있는 사람임
      정적 사이트는 패치할 보안 취약점이 없으니 SSG 프로젝트가 관리자의 문제로 완전히 무너져도 큰 상관이 없지만, WordPress에서는 매우 중요해짐
    • 나도 비슷함. 오래전에 DokuWiki로 시작했다가 GitHub Pages를 써보기로 했고, 전부 옮긴 뒤 검색이 필요해져서 맞춤 Google 검색을 붙였음
      방문자가 댓글을 남길 방법이 필요해서 Disqus를 추가했고, 결국 여러 서비스와 많은 JavaScript가 뒤섞인 잡탕이 됨
      몇 년 전 다시 내 데이터를 직접 소유하고 외부 서비스에 의존하지 않으려고 Disqus 댓글을 내보낸 뒤 Serendipity를 만지다가 WordPress로 정착함
      댓글과 Markdown 페이지를 가져올 수 있었고, Fediverse로 전부 발행해 주는 플러그인도 있었음
      SQLite로 작동하게 만들고 자동 업데이트를 켜 두니 사실상 유지보수가 필요 없게 됨
    • 블로그 스팸인가? :) URL은 https://rakhim.org/honestly-undefined/19/
    • 동의하지만 95%의 경우 WordPress는 과함이라고 봄
      필요하지 않을 가능성이 큰 기능 때문에 너무 많은 유지보수가 필요함. 최신 상태를 유지하지 않으면 봇넷의 일부가 될 수 있음
      대부분의 블로그에는 정적 사이트 생성기로 충분하고, 유지보수가 필요해도 내가 원하는 시점에 하면 됨
    • nikola에 꽤 만족하고 있음: https://getnikola.com/
      정말 원했던 것은 게시를 위한 명령 하나와 글에 이미지를 쉽게 끌어다 놓는 방법이었는데, 전자는 잘 되고 후자는 Jupyter Notebook 게시 기능으로 가능함
      절대 원하지 않았던 것은 “HTML을 클라이언트에 보내기”에 데이터베이스 같은 부담이 생기는 방식이었음
  • 좋지만 블로그라고 부르려면 작은 기능 두 가지가 더 필요하다고 느낌
    첫째, 글을 날짜순으로 정렬하고 최신 글이 먼저 나오게 하며, 날짜를 어딘가에 표시해야 함. 최소 구성을 유지하려면 글 파일의 메타데이터, 예를 들면 생성 시간을 쓰면 됨
    둘째, 당연히 RSS 피드가 필요함. 기존 스크립트와 최소 RSS 템플릿만으로 링크와 제목만 담은 간단한 피드는 쉽게 만들 수 있을 듯함

    • RSS는 좋지만, 블로그로 인정받기 위한 필수 조건이어서는 안 된다고 봄
      “팔로우”되는 것이 항상 좋은 건 아니고, 독자에게 맞추려는 압박을 만들 수 있음. 소셜 미디어를 나쁘게 만드는 바로 그 요인임
    • 타당함
      1번은 TOML 같은 형식으로 메타데이터를 담은 파일을 자동 생성하는 쪽으로 기울고 있음
      2번 RSS는 확실히 추가할 예정이지만, 1번에 의존함 :-)
  • 독립 웹사이트를 늘 좋아해 왔고, 내 웹사이트도 약 25년 전 비슷하게 시작했음
    당시 내가 알던 적절한 기술이 Classic ASP뿐이라, 최소 구성으로 단순하게 ASP로만 만들었음
    지금은 Common Lisp로 정적으로 생성되는 사이트로 돌아가며, 이 구성이 장기 설정이 될 것 같음: https://github.com/susam/susam.net/blob/main/site.lisp
    단순한 페이지 묶음으로 시작하는 것은 최소 실행 가능 웹사이트를 만드는 좋은 방법이었지만, 시간이 지나며 RSS 피드, 날짜순 블로그 목록, 태그별 색인, 도구·게임·데모 같은 비블로그 콘텐츠 지원, 서드파티 없는 댓글 같은 기능이 필요해짐
    요구사항이 늘 때마다 소스도 자라서, 몇백 줄이던 코드가 이제는 약 1300줄의 Common Lisp가 됨
    그래도 전체 코드를 한 번에 머릿속에 담을 수 있고, 버그가 나면 10분 안에 추론하고 고칠 수 있는 수준으로 유지하고 싶음
    요즘은 좋아하는 블로거들의 글 목록을 제공하는 블로그롤을 추가하고 싶은 유혹이 있음. 피드 리더를 대체할 수도 있겠지만, 이메일까지 읽는 물건으로 커지지는 않게 조심하려 함

    • 거의 같은 경로를 밟았음
      소스 코드는 여기 있음: https://github.com/brilee/modern-descartes-v2/blob/master/ma...
      RSS 피드, 날짜순 블로그 목록, 태깅 시스템, 파일 감시 재컴파일이 붙은 로컬 개발 서버가 포함됨
    • 내 경로도 비슷했고, 사실 몇 번 반복해 봤음
      현재 버전은 1000줄 미만 Python 스크립트로 유지됨: https://github.com/llimllib/obsidian_notes/blob/c93b9b5c46fe...
    • 정확히 이거임. “이 장치를 만들고 싶다”고 정하고 직접 코딩할 수 있는 능력은 어떤 WYSIWYG보다 낫다
      글 묶음, 색인, 슬라이드쇼 같은 파생 페이지를 만들었고, 사람과 비디오 게임용 태그 변형도 만들었음
      썸네일 갤러리나 인용 박스 같은 일반 위젯의 모양과 느낌도 완전히 제어할 수 있음
    • Lamb에 Flock 기능을 만들었는데, 피드를 내 블로그로 신디케이션하는 기능임. 다중 사용자 방식의 대안으로 주로 만들었음: https://github.com/svandragt/lamb
      높은 수준의 참고 자료로 쓸 만할 수 있음
    • RSS와 날짜는 확실히 필요할 것 같음
      앞으로 셰이더와 웹 게임도 임베드하고 싶어질 수 있는데, 복잡도가 너무 커지지 않기를 바람
  • 브라우저가 text/markdowntext/gemini를 네이티브로 지원하면 좋겠음
    브라우저가 PDF 렌더링을 할 수 있다면, Markdown/Gemini 콘텐츠용 간단한 포매터와 사용자가 정할 수 있는 스타일시트 정도를 넣는 게 그렇게 어렵지는 않을 것 같음
    지금도 text/plain 블로그를 쓸 수는 있지만, 실제 하이퍼텍스트가 아니라 SEO에서 손해를 봄. link 헤더로 뭔가 마법을 부릴 수는 있을지도 모름
    다른 형식을 지원하면 깔끔하게 발행하는 장벽이 낮아지고 제어권이 사용자에게 돌아감

    • 브라우저 네이티브 Markdown 렌더링은 아쉽지만 가능성이 낮아 보임
      먼저 어떤 Markdown 변종과 확장을 쓸지 브라우저들이 합의해야 함. Markdown은 거의 텍스트 형식계의 CSV 같아서 모두가 각자 방식으로 쓰기 때문임
      너무 최소화하면 쓸모없다는 불만이 나오고, 확장을 고르면 비대하다는 불만이 나올 것임
      장단기 장단점에 대해 신중히 논의하려 해도 “완벽이 선의 적이 되게 하지 말라”는 말로 막힐 수 있음
      특정 기능 집합에 합의하더라도, 실제로 그만한 가치가 있는지도 의문임
      PDF를 브라우저에서 직접 읽는 일은 충분히 흔하지만, Markdown을 직접 읽는 혜택은 전 세계 소프트웨어 개발자 중 일부와 이상한 사람 다섯 명 정도에게만 갈 가능성이 큼
      그래서 살아 있는 동안 브라우저 네이티브 Markdown 렌더링을 못 봐도 놀랍지 않을 듯함
    • 브라우저의 PDF 렌더링은 JavaScript로 했거나, 적어도 한때는 그랬음
      브라우저 네이티브 지원보다 새로운 버전이 필요할 때 쓸 수 있는 XSLT용 라이브러리도 있고, jpegxl 등 여러 형식용 라이브러리도 있음
    • Gemini에도 자체 형식이 있나?
  • html_content = html_content.replace('Minimum viable blog', title)라면 글에 Minimum viable blog 문자열이 나올 때마다 현재 글 제목으로 바뀌는 건가? 버그 맞지 않나?

    • 맞음, 잘 잡았음
      글에 있는 코드는 O1이 만든 첫 초안이고, 이 문자열은 {{ title }}로 교체됐음
  • 약 15년 동안 미니멀 블로그를 실험해 왔고, 배운 요령이 몇 가지 있음
    const title = lines.match(/# (.+)/)[1] 정도로도 충분해서 frontmatter를 피할 수 있음
    내 블로그들은 글이 너무 많아져 페이지네이션, 태그, 카테고리, 정렬이 필요했던 적이 없음
    JSX는 https://immaculata.dev/guides/enabling-jsx.html 같은 수상한 해킹을 쓰면 순수 서버 측 문자열 빌더로 꽤 좋음
    이제 GitHub Pages도 https://immaculata.dev/guides/using-gh-pages.html 같은 것으로 Jekyll 대신 임의 빌드 단계를 쓰기 쉬워졌음
    highlight.js는 HTML에 세 줄만 추가해도 되는 아주 쉬운 코드 구문 강조의 왕에 가깝고, shiki는 멋지지만 느림

  • Hugo/Zola + Cloudflare Pages 같은 표준 정적 블로그 프레임워크를 쓰면 쉽다
    내 블로그도 100KB 미만의 최소 구성이며 원글 작성자가 나열한 기준을 모두 충족함
    Hugo Blog Awesome 테마를 쓰고, 512kb 가이드라인을 따르며 페이지 크기를 확인했고, 이미지와 불필요한 JS를 제거했음. 애초에 많지는 않았음
    참고: https://512kb.club, https://radar.cloudflare.com/scan

  • 한동안 “MVB”를 운영했는데 내 것은 더 단순했음
    그냥 HTML 페이지 하나를 두고, 글은 .txt 파일로 쓰며 홈페이지를 수동으로 업데이트했음
    꽤 장황하긴 했지만 그래도 현대 웹을 상대하는 것보다는 쉬웠다고 봄
    이후 더 정교한 쪽으로 옮겨 지금은 개인 사이트와 블로그에 Astro를 쓰고 있는데 정말 훌륭함
    Astro는 랜딩 페이지에서 “콘텐츠 중심 사이트”에 최고의 플랫폼이라고 주장하는데, 6개월 써 보니 동의하게 됨
    블로그를 만드는 데 필요한 거의 모든 것에 대해 명확하고 따라가기 쉬운 관례를 제공하고, 쓸데없는 부분을 덜어냄

    • Astro는 정말 대단함. 왜 더 인기가 없는지 모르겠음
    • 다른 사람의 테마를 쓰는지, 아니면 직접 만들었는지 궁금함
  • 몇몇 사이트에서 Bun JS와 JavaScript 문자열 안의 HTML을 쓰는 방식을 실험해 봤음
    Bun에는 변경 시 정적 HTML을 다시 생성하는 —hot 플래그가 있음
    IntelliJ IDE는 문자열 위의 // language=html 주석을 감지해서 내부 HTML을 포매팅하고 구문 강조도 해 줌
    템플릿 언어 대신 순수 JavaScript 함수를 쓰면, 템플릿 언어에서 어떻게 하는지 찾아보지 않고 필요한 로직을 직접 작성할 수 있음

  • 너무 비대해서 로딩이 오래 걸리는 웹사이트에 질려서, 내 블로그에도 아주 비슷한 접근을 쓰고 있음: https://blog.borrego.dev
    소스: https://github.com/agubelu/blog

    • 아주 마음에 들고 보기 좋음. 모바일에서는 어떻게 보이나?