SEUL Log

포트폴리오

Obsidian + git으로 블로그 만들기

February 19, 2024
obsidian
git
Nextjs

안녕하세요. 해당 포스팅에서는 velog를 떠나 obsidian으로 블로그를 만든 이유를 적어보고 어떻게 구현했는지에 대해서도 소개해보려고 합니다. 혹시라도 obsidian으로 블로그를 만드실 생각이 있는 분이시라면 해당 방법도 참고해보시면 좋을 것 같습니다 :)

Obsidian을 선택한 이유

velog를 떠나서...

저는 개발 공부를 시작하면서부터 기술블로그를 작성하기 시작해 2년 정도 velog에서 기술 블로그를 작성했습니다. 물론 지금도 velog는 블로그를 시작하는 사람들에게 가장 좋은 선택지 중 하나라고 생각합니다. 하지만 저는 다음의 몇 가지 이유로 블로그를 옮겨야겠다는 생각을 했습니다.

  • 블로그 커스텀이 불가능하다.
  • 태그를 카테고리로 사용해 태그가 많아지면 카테고리가 무한정으로 늘어난다.
  • 통계 분석 기능이 많지 않다.

같은 이유로 github page와 티스토리 또한 선택지에서 제외했습니다. 두 서비스 모두 velog 대비 커스텀이 자유롭지만 결국 직접 만드는 것보다는 제한적이라는 생각이 들었고 통계와 SEO 같은 부분들도 직접 작업해보고 싶어 직접 블로그를 만들기로 결정했습니다. 

그래서 내가 만들고 싶은 블로그는? (요구사항 정리)

이후에 고민했던 부분은 어떤 식으로 블로그를 만드는 방법이었습니다. 우선 제가 원하는 요구사항을 정리했습니다.

  • 자유로운 커스텀
  • SEO와 통계를 작업에 유리할 것
  • 배포가 쉬울 것
  • 서버 작업은 하지 않을 것
  • 기존에 사용하고 있는 노트앱을 활용할 수 있으면 좋을 것 같음

위의 요구사항 중 SEO, 통계, 배포의 편리성으로 인해 프론트엔드 프레임워크는 Next.js를 선택했습니다. 그리고 서버 작업을 하지 않을 것 을 고려해 선택할 수 있는 선택지는 노션이 있었습니다. 노션은 notion API를 제공해 노션을 database 처럼 사용할 수 있는 방법이 있었고 찾아보니 nextjs-notion-starter-kit, morethanlog 등 기존의 좋은 서비스가 있어 시작하기 수월했습니다. 하지만 저는 최근 꽤 많은 시간을 들여 노션에서 옵시디언으로 이사를 했기 때문에 마지막 요구사항이었던 기존의 노트앱 활용 측면에서 아쉬운 점이 있었습니다.

결국 최종적으로 옵시디언을 notion API 방식처럼 사용해서 개발하기로 결정했습니다. (저는 옵시디언으로 이사를 와서 옵시디언을 선택했지만 노션으로 만드는 게 훨씬 더 간편했을 것 같긴 합니다.)

Obsidian - git - Next.js

제가 계획하고 구현한 방식은 다음과 같습니다.

옵시디언의 로컬 저장소를 동기화하기 위해 git과 github를 사용하여 버전을 관리하고 github에서 제공하는 github REST API를 사용해 프론트에서 github에 있는 *.md파일을 가져와 렌더링하는 방식입니다. 옵시디언에서 작성한 글을 다른 과정 없이 바로 포스팅할 수 있다는 장점이 있지만 블로그 구현 방법 치고는 쪼금 복잡하다는 단점이 있었습니다.

그럼 이제 실제로 어떤 방식으로 구현할 수 있는지 자세히 알아보겠습니다.

Obsidian - git 연결하기

옵시디언은 로컬 저장소를 사용하기 때문에 동기화를 위해서는 클라우드를 연결해야 합니다. 다른 클라우드를 사용해도 상관없지만 저는 github REST API를 사용해 블로그 데이터를 받아오도록 구현하였으므로 git과 github를 사용해 버전관리를 진행했습니다.

Git 플러그인 설치

다행히도 obsidian에는 git을 연결할 수 있는 플러그인이 존재해 해당 플러그인을 사용하면 깃허브 레포를 문서 저장소로 사용할 수 있습니다.

해당 플러그인을 사용하면 설정한 시간 주기로 자동으로 commit과 push를 할 수 있고 이때 commit 메세지도 설정할 수 있습니다. 저는 다른 작업을 할 때는 10분 단위로 설정해두고 블로그 글을 작성할 때는 꺼놓는 방식을 사용했습니다.

Obsidian Vault와 git 연동하기

다음으로는 로컬에 있는 옵시디언 저장소로 이동해서 git을 구성하고 저장소와 연결해야 합니다. 이 때 터미널에 명령어를 입력하는 방식과 github 데스크탑 앱을 사용하는 방식이 있는데 이 글에서는 연동방법을 설명하면 너무 길어질 것 같아 잘 작성된 다른 블로그의 글로 대신하겠습니다.

터미널 방식으로 연결한 글 github 데스크탑 앱을 사용해 연결한 글

Github REST API로 git에 있는 정보 받아오기

이제 옵시디언과 git을 연결했으니 실제로 사용할 블로그를 만들어줘야 합니다. 저는 SEO + 편한 배포 + Next14 공부 등의 이유로 Next.js를 선택해 개발했으나 Github REST API의 경우 node 환경에서 개발된 여타 프레임워크들도 사용할 수 있습니다.

Github REST API란?

먼저 Github REST API가 무엇인지 알아볼 필요가 있습니다. 다음은 chatGPT가 알려준 github REST API의 정의입니다.

위와 같이 Github REST API는 깃허브의 레포지토리와 관련된 정보를 코드에서 접근할 수 있도록 도와주는 작업을 해줍니다. 이번에는 레포지토리의 파일에 접근하기 위해 사용했지만 Github Docs에 따르면 CI/CD, 데이터 검색, workflow 자동화 등에도 사용될 수 있을 것 같습니다.

Octokit으로 Github REST API 호출하기

공식문서에서는 Octokit을 사용해 Github REST API를 호출하는 것을 권장하고 있습니다. Octokit은 Github REST API의 엔드 포인트와 통신하기 쉽게 추상화되어 있고 인증이 더 편리하다는 장점이 있습니다.(Octokit 공식문서)

그럼 이제 Octokit을 사용해서 Github 레포지토리의 file을 불러오는 방식에 대해 알아보겠습니다.

먼저 인증에 사용할 github access token을 만들어야 합니다. 깃허브 > settings > Developer Settings > Personal access token 에 들어가서 새로운 토큰을 생성해줍니다. 해당 토큰은 Github API를 사용하기 위해 필요하며 저는 classic 방식을 사용해 토큰을 생성해줬습니다.

이제 프로젝트로 돌아와 Octokit을 설치합니다.

npm install octokit

그 다음으로 인증 정보를 설정합니다.

const octokit = new Octokit({ auth: gitAccessToken, })

인증정보를 설정한 후 원하는 요청을 할 수 있습니다. 저는 블로그의 글 목록을 불러오기 위해 특정 path의 모든 content에 대한 정보를 불러오는 요청을 작성했습니다.

export const getRawPosts = async (path: string = 'blog') => { const { data } = await octokit.rest.repos.getContent({ mediaType: { format: 'raw', }, owner, repo, path, next: { revalidate: 3600,// nextjs의 revalidate 관련 속성 }, }) return data }

전체 정보가 아닌 특정 파일의 정보 blobData를 받아오고 싶다면 아래와 같이 요청할 수 있습니다.

export const getPostBlobData = async (sha: string) => { const { data } = await octokit.rest.git.getBlob({ owner, repo, file_sha: sha, next: { revalidate: 3600,// nextjs의 revalidate 관련 속성 }, }) return data }

결론

최종적으로 vercel로 배포하여 현재의 블로그를 만들 수 있었습니다. 처음에 생각했던 것보다 약간 복잡해지긴 했지만 추후에 원하는 기능을 더 추가하면서 블로그에 애정을 더해가는 재미도 있을 것 같습니다.

그리고 저는 obsidian vault와 프론트를 따로 두는 방식으로 작업했지만 옵시디언 자체를 publish하는 방법(유료)도 있고 obsidian digital garden을 사용해 배포하는 방법도 있는 것 같습니다. 원하는 방법을 사용하시면 될 것 같습니다!