어쩌다 블로그
프로그래머는 평생을 공부하는 직업이라고들 한다.
아무래도 평생을 공부하다 보면, 학부 때 배우는 컴퓨터 공학의 기본 지식에 더해 실무를 하며 배우는 다양한 도메인 지식, 새로 나온 기술, 나만의 노하우 등 다양한 지식들이 차곡차곡 쌓여간다.
자연스레 기억력만으로는 감당이 어려워지고, 몇 달 전 배웠던 내용조차 흐릿해질 때가 생긴다.
그래서 개인 지식 관리의 필요성을 절실히 느끼게 되었다.
처음에는 간단히 워드 문서에 메모하고, 구글 드라이브에 백업하는 수준이었지만, 이후 노션을 거쳐 지금은 옵시디언에 정착하게 되었다.
지식이 하나둘 쌓이기 시작하자, 그것을 공유하고 싶은 마음도 함께 커졌다.
나는 연구자라기보다는 실무자에 가깝기에 내 지식이 독창적이지는 않다.
하지만 이미 널리 알려진 지식이더라도, 내 방식대로 재구성한 것이라면, 충분히 공유할 가치가 있다고 생각한다.
또한 많지는 않지만 게임 서버 개발자로 일하면서 현업에서 얻은 경험과 노하우들도 조금씩 쌓여가고 있다. 이 역시 블로그에 담을 만한 좋은 소재가 된다.
"남에게 설명할 수 있어야 제대로 아는 것"이라는 말이 있다.
예전에 비 전공자에게 컴퓨터 공학의 기초를 설명해준 적이 있는데, 그 과정에서 내가 막연하게만 이해하고 있었던 개념들이 많다는 사실을 깨달았다.
직접 설명해보며 내 지식의 빈틈을 확인하고, 그걸 채워나가는 경험이었다.
블로그 글쓰기도 마찬가지다. 글을 쓰는 과정에서 내 지식을 다시 정리하고, 정제할 수 있다.
실제 방문자가 있든 없든, 구글 검색을 통해 누군가 내 글을 읽을 수 있다는 생각만으로도 글을 타인의 시점에서 쓰게 된다.
그리고 이 과정은 분명 내 지식을 더 단단하게 만들어줄 것이라 기대한다.
맘에 드는 게 없어
사실 나에게 기술 블로그 운영은 예전부터 하고 싶었던 일종의 숙원 사업같은 것이었다.
나는 스스로 완벽주의자라고 생각하지는 않지만, 특정 분야에 대해서는 유독 고집스러운 면이 있는 것 같다. 블로그 플랫폼도 그중 하나였다.
네이버 블로그, 티스토리, velog, 구글 블로거, 심지어 직접 워드프레스를 호스팅해보기도 했지만, 그 어느 것도 완전히 마음에 들지는 않았다.
블로그의 UI나 동작을 내 마음대로 컨트롤하고 싶었지만, 기존 플랫폼에서는 제약이 따랐고, 가능하더라도 많은 시간을 들여 커스터마이징해야 했다.
또 개인 지식 관리를 노션에서 옵시디언으로 옮긴 이유이기도 한데, 내 데이터가 언젠가 서비스 종료될 플랫폼에 종속되어 있는 게 마음이 편치 않았다.
결국은 직접
결국은 직접 만들어야 했다.
막상 블로그를 직접 만드려고 하니, 구현해야하는 시스템이 정말 많았다.
글 에디터, 글을 저장할 DB, 태그 기능, 로그인 연동, 검색 기능, 정적 파일 제공 등등.
엄두가 나지 않아 차일피일 미루던 와중 정적 블로그 유행이 불었다.
마크다운으로 작성된 문서를 html로 변환해 서비스하는 방식으로, 정적 파일만 호스팅하면 되기 때문에 많은 사람들이 사용했다.
나도 따라 시도해봤지만 역시 마음대로 커스터마이징 하기 쉽지 않았고 서버 개발자라 그런지 몰라도 백엔드가 없다는 느낌이 맘에 들지 않았다.
내 블로그를 정적 블로그로 만들지는 않았지만 약간의 힌트를 얻었다.
옵시디언에서 작성된 마크다운 파일을 직접 블로그 포스팅으로 서비스하게 된다면 많은 부분을 구현하지 않아도 된다.
옵시디언 볼트의 파일을 읽어와 html로 변환해서 태그와 본문 내용을 잘 인덱싱만 해두면 사용자에게 바로 제공이 가능한 상태가 된다.
예전과 달리 이제는 AI도 많이 발전하여 코드를 잘 만들어준다.
이번 블로그 만들기 프로젝트는 Claude Sonnet 4를 사용해서 바이브 코딩으로 진행할 수 있었다.
원하는 모양과 기능을 이야기하면 알아서 프론트엔드의 css, html, js와 백엔드인 node.js 기능을 구현해준다.
당연히 생성된 코드를 바로 사용할 수는 없다. 모든 코드를 검토해서 의도를 잘못 이해한 부분들을 수정해야한다.
그럼에도 직접 작성하는 것에 비해 어마어마한 시간을 아낄 수 있었다.
특히 프론트엔드는 전부 클로드가 작성했고 내가 하는 일이라고는 css로 margin 깔짝거리면서 좀 더 보기 좋게 만드는 작업이 전부였다.
작동 방식
실제 과정은 좀 더 복잡하지만 여기서는 간략하게 전체적인 작동 개요를 설명해보려고 한다.
실제 서비스에서는 변경점 인식시 스로틀링과 같은 기능이 추가된다.
블로그 글 작성
옵시디언에 블로그 글을 작성한다.
이 때 프로퍼티로 태그, 작성일, 공개여부와 같은 메타 정보를 입력하고 썸네일 이미지를 업로드한다.
변환 처리
서버에도 옵시디언이 설치되어있고 옵시디언 싱크를 구독하고 있기 때문에 변경점은 자동으로 싱크가 된다.
서버의 node.js 서비스가 볼트의 파일 변경을 감지하면 변환 과정을 시작한다.
변환 과정
- 원본이 한국어인 문서를 영어로 번역
- 만약 마크다운 파일 해시값이 변경되지 않았다면 스킵
- OpenAI의 API(gpt-4o-mini)를 사용해 번역
- 옵시디언 방식의 태그를 마크다운 형식으로 변경
- 이미지 크기 설정과 같은 태그는 html로 직접 변경
- 상대 링크, 절대 링크를 경우에 따라 적절히 처리
- 마크다운을 html로 변환
- markdown-it
- 글에 설정된 태그, 작성일, 썸네일 등 메타 정보를 메모리에 등록
- node-cache
- 읽는 시간 예상: reading-time
- 글 내용을 읽어 검색 인덱싱
- fuzzysort
- 필요한 정적 파일을 서비스 폴더로 복사
변환 과정이 끝나면 메모리에 글과 메타 정보가 인덱싱 되어있는 상태가 되게 된다.
백엔드 처리
웹 요청은 express를 통해 서비스 된다.
- 목록 페이지: 인덱싱 된 글을 조회/전송
- 글 페이지: 요청된 글을 전송
- 검색 API: fuzzysort에 인덱싱 되어있는 글을 검색하여 결과 전송
추가적으로 SEO나 최적화를 위해 몇가지 부수적인 기능을 구현했다.
- 글에 맞는 hreflang, meta 같은 태그 생성
- 메모리에 있는 정보로 sitemap, robots과 같은 페이지 생성
- 이미지 리사이징 및 캐싱
프론트엔드 처리
댓글은 깃헙 Discussions을 이용한 giscus를 사용했다.
사용자 이용 현황을 위해 구글 애널리틱스를 추가했고, 이를 위해 쿠키 허용 처리창도 추가했다
잘 써봐야지
사실, 10년 전쯤에도 한 번 블로그를 시작한 적이 있다.
인디 게임 리뷰 블로그를 운영해보겠다고 마음먹고, 열심히 블로그를 꾸몄다. 하지만 몇 개 포스팅을 올린 후 흐지부지 그만두고 말았다.
왠지 그 때 기억 때문인지, 야심차게 코딩을 마치고 첫 글을 적었지만 텅 비어있는 카테고리를 보니 조금 막막한 기분이 든다.
하지만 이번에는 다를 거라고 스스로를 다독이며 꾸준히 포스팅 해보려 한다.